Character LCDs are displays that consist of many character “blocks”, and each block can display a letter, number, etc.
In the world today, there is one display controller/driver that dominates this market, the Hitachi HD44780 driver. I have talked about this in another post on reverse engineering a printer LCD.
HD44780-based character LCDs usually come in common sizes such as 16×2 (16 characters per line, two lines), 8×2, 20×2 20×4, using the 8-bit ASCII character set.
Interestingly enough, the HD44780 chip allows up to 8 custom characters to be defined. These can contain any bitmap data, and can be updated as often as you like.
With this in mind, we can construct basic bitmap images for the display, with a resolution of 20×16 pixels if we have four custom characters per line, occupying two lines, 15×16 if we have three per line on two lines (two are still available but not used) or a 40×8 display if we put all eight on one line.
However, there is a gap between each character so images will have gaps, and symmetry can get messed up if you don’t design it correctly.
I connected a standard 16×2 character LCD to my Arduino via a Proto Shield (excuse the messy wiring) and hacked together some code for the custom characters.
I have created a very low-resolution version of the Hack a Day logo for their Trinket competition. The goal is to put their logo in interesting places. Nobody has done this before, so I figured it would be fun to try out.
Here’s the original image for a comparison
My final logo ended up using six of the custom characters for a 15×16 pixel resolution (3×2 resolution in characters) as there are things in the centre which are split in the character gaps so four characters per line can’t work. I finally had to do it this way after too much trial and error using all 8 characters for a 20×16 resolution.
Click on the images for a higher resolution version.
I think the result turned out nicely, considering what the actual display was designed for.
Here’s a link to the Arduino sketch I wrote up with the bitmap: lcd_hackaday.ino
A few weekends ago I got hold of an old broken Canon printer/scanner combo. One thing that caught my eye was the display. It was a 2×20 character LCD (2 lines, 20 characters per line) which is better than some others I have which are 2×16.
Here is an image of my finished example project with this display:
When removing the display I noticed something very interesting in that the display was just a glass panel, and had a ribbon cable attached to it that had only 14 pins. This meant that there was something special with this display in that the display circuitry for driving the display was all built inside the glass, and is called a Chip on Glass display. Normally you find these LCD displays with 60 connections or more, as the multiplexing and driving circuitry is not attached to the glass.
Ok, now here’s why I actually decided to try to actually get this display working in the first place. When I realised there was no circuit board behind the LCD panel as you would normally find with a few driver chips and/or recognisable components, I thought it would be using a proprietary command set for interfacing with an SPI or I2C bus, and would be impossible to sniff and decode the data as the printer was broken and did not power on.
As I counted the pins on the ribbon cable I realised that it had 14 pins. This is a very coincidental number as standard HD44780-based character LCD displays use this exact amount of pins (plus two for the backlight so it’s 16, but here there isn’t one).
I decided to give it a shot.
Looking at the pinout for normal HD44780-based LCDs, the first three pins are responsible for power and the contrast adjustment. I decided to try to wire up these three pins and see what happens. I connected pin 1 to Ground, pin 2 to +5V and pin 3 as the contrast adjustment through a potentiometer from Ground to 5V.
As expected, the first line went solid black which HD44780 LCDs do before you send them data, which proved my theory. I then spent far too much time in actually getting it to work.
Here are my initial connections to the printer circuit board that has the ribbon cable connector for the display:
I tried connecting up the LCD in 4-bit mode using the LiquidCrystal Arduino library, but only random characters and symbols were displayed on the LCD.
I knew this meant there was something wrong with the wiring or something else weird, so I tried connecting it up in 8-bit mode and to no avail. I randomly tried swapping pins around until finally when RS and RW were swapped (pin 4 and 5), it came to life!
Right now I was really happy and relieved that all my time spent was worth it.
I built up a small breakout board so it could easily fit on a breadboard. I cut off a section from the printer PCD with the ribbon cable connecter, glued it to the breakout board and soldered connections from it, then put on a small potentiometer for the contrast adjustment.
Here are some pictures of how it turned out:
I then decided to do a “mini-project” just to make an example of it in action: a temperature display.
I just wrote up a quick program to read the temperature from a LM35 temperature sensor and display the value to the display (in Celsius). This is the image you see in the top of the post.
One more thing that I thought would be interesting is seeing the ASCII character set that the LCD uses. I figured since this display was probably designed for printers or similar consumer devices, it would have some interesting characters built in, and it did!
It has symbols for arrows, some bar graphs, rounded icons and also some Russian (I think?) letters.
Here is a pinout of the display. Note that pins are ordered from left to right:
1 – Ground
2 – Contrast – Connect to 5V for full contrast. Connect via a pot to Ground and 5V.
3 – +5V power supply
4 – RW
5 – RS
6 – Enable
7 – Data 1
8 – Data 2
9 – Data 3
10 – Data 4
11 – Data 5
12 – Data 6
13 – Data 7
14 – Data 8
Overall it was a good learning experience in getting it working, and I really enjoyed it. Continue reading »
Work out exactly what levels you need to enchant your armour/tools at in order to receive a specific enchantment, calculate all possible enchantments for any item with a certain experience level and calculate the most efficient way to get to a certain experience level. This tool does all of this, and is an essential tool for Minecrafters!
• Calculate exactly what levels you need to enchant your armour/tools at in order to receive a specific enchantment!
• Calculate all possible enchantments for any item with a certain experience level, and some information on them!
• Calculate the most efficient way to get to a certain experience level.
This app is very useful to all Minecraft players as you can
predict not only what enchantment you can obtain with a certain experience level or actually work out what level to enchant at to receive a specific enchantment, but also calculate exactly how you can gather up that experience level, for example needing to kill 23 monsters or mine 6 diamonds.
This app is very simple to use, all you need to do is enter your enchantment levels and item/enchantment choices and it does the rest for you!
Also, an option is included to switch to older experience levels. Before Minecraft 1.3, the maximum experience level was 50. This feature allows the app to run on these scales.
When Minecraft updates are released, we will update the app to be compatible with the Minecraft update and provide it free of charge. Note that not all Minecraft updates actually contain changes to the enchanting system, so we will not update in those cases.
It is fully compatible with the iPhone 5 and iPad Mini.
** NOTICE : This app is a an unofficial enchantment app for Minecraft, it is not endorsed or supported by Mojang. **
The Nokia 3310 LCD is well known in the electronics community. It is a monochrome graphics LCD with a resolution of 84×48 and was originally used in the Nokia 3110 and 5110 handsets, and is relatively old (1998), but in my opinion it is brilliant for its price.
I purchased mine on Dealextreme for only $5.60 (link to the product page here), which is a very good price considering what is possible with this display. It came in a nice breakout board so it can be used directly on a breadboard.
If you remove the casing on the breakout board, you will find out that the display looks just like a piece of glass, and has a PCD8544 controller chip embedded inside it.
This controller has an easy to use SPI protocol and handles all the hard work of driving this display (multiplexing, generating bias voltages, ect.).
Driving the display is relatively easy with any microcontroller. However, it runs on and uses 3.3V logic, so you would need level shifters to shift the voltage down.
However, after doing lots of research it seems that the PCD8544 has a maximum voltage of over 5 volts, and that people can drive it perfectly fine on 5V, although it could reduce the life span of the display. I was willing to take the risk.
I decided to connect the VCC (power) connector to my Arduino’s dedicated 3.3V supply, and all the other lines to my Arduino directly. It worked perfectly and still does, with absolutely no issues. However, I do not recommend this so don’t blame me if you end up damaging your display!
Adafruit has made a nice Arduino tutorial and library for using this display. It was perfect for my needs, as their library can draw text, lines, rectangles, circles and other shapes easily to the display, plus all these functions are built into the library. I will not explain how to wire this display up as their tutorial explains it well.
I soldered up a simple shield for driving the display, and a few buttons. However, these are not normal buttons but capacitive buttons! The reason why I made these was because I did not have any normal buttons, plus it is very cool to use! The piece of code I used for the buttons was found over here at the Arduino site, and is connected directly to the buttons. No pullup resistors were used in this case.
The buttons were connected to the following pins:
Select File – Pin 19 (analog A5)
Toggle FPS – Pin 18 (analog A4)
Play – Pin 17 (analog A3)
Here are some images of the shield I made (I apologise for the incredibly messy soldering, I needed this done in a hurry):
First of all I wanted to make a simple text scroller. This was easy, and the following code was used in the loop() routine to scroll some text, with display being the display object:
String text = "Test of scrolling text!";
word textWidth = text.length()*6+85;
for(int i=0; i display.clearDisplay();
This worked very well, with smooth text being scrolled across the screen. However, I wanted more.
I had seen somewhere of getting text to scroll while each character ‘wobbles’.
This effect was easy to achieve.
Instead of printing out a whole string to the display, you print out each character of the string one by one, and change the Y axis of each one for the wobble effect.
To get the ‘wobble’, a sine wave was added to each character’s Y axis, each with a small offset to make the sinusoid slightly different for every letter. I then made a few lines at the bottom to follow the pattern of another sine wave at the bottom of the screen just for something to fill the extra space with.
The effects turned out brilliantly. (Arduino code for the Wobbly Text at the bottom of the page)
This was fun, but I still wanted more. Then I came accross this video. It has an ATMega88 getting video off an SD card and playing it on a monochrome LCD at a good frame rate, and states that the program was written in ASM.
The video looked like it was using some form of 1-bit dithering to be visible on a monochrome display, and was very recognisable. I thought that this was definitely possible, and I was going to give it a try in C++ first and try redoing it in ASM later on, and did not know what frame rate I would get, but I assumed the worst.
I had also purchased an Ethernet shield from Dealextreme. This has the Wiznet chip which is used in the Official Ethernet shields, and works well. It has a SD card slot which would work well for this project. Best of all, it is less than $14 which is almost one third the price of the official version.
First of all I came up with a format for saving my data. The encoded data file would consist of ASCII characters. If the ASCII character was from 0x00 to 0x3F in hex (the first 6 bits, or from B000000 to B111111) then it would be treated as data.
If I wanted the first 6 pixels of the first row on the frame buffer to appear in this binary pattern: 101010 then I would set the character to be 0x2A in hex, or B101010 in binary, and increases the X coordinate by 6. If I repeat this character, it would set the next 6 pixels to 101010, and so on. This is what is used to set the image of the display.
When this is done 14 times, I end up with 84 pixels which is exactly the width of one of the rows of the display. Perfect fit!
Now, if the ASCII character is over 0x3F it is a control character. This is a command that can trigger a certain function in the program.
Here are the control characters:
0x7B – New line – Increments the Y-axis by one, use this when you have written all 14 data characters for the row to go on to the next one and carry on sending your data.
0x7C – Reset the X and Y coordinates – Use this when you have filled up the whole display, and need to start at the beginning point for a new image.
0x7D – Update display – This sends the data in the frame buffer to the display and displays it.
With these commands it is possible to display images or video.
I wrote a Processing script to render a simple 3D Cube and save each frame to a file in the sketch’s project folder using the protocol above (code at the bottom of the page).
I made it save the data to a file called data.dat.
Now I formatted my MicroSD card on Fat32 as the format, and copied the data.dat file onto it.
Writing the Arduino video player program was the most difficult part. I used the SD library included with Arduino to read the files of the SD card and wrote up a file chooser what uses the buttons on the shield, and a routine to read data from the chosen file off the SD card, draw the images and handle the commands.
Everything worked out OK in the end after a day of work, and I had a working product. However, I still needed to finish my goal of displaying video.
Next I did some research on Dithering. I then discovered Windell Oskay’s writeup on how dithering works and some code he wrote to use Dithering in Processing. The example converted real-time video from the webcam to 1-bit dithered images using the Atkinson Dithering algorithm. This was exactly what I needed. (thanks Windell!)
I then modified the program with a output resolution of 84×48, and gave it a video as the input file. (If you want to use a different file, make sure it is 84×48 with ‘high contrast’ for best results with the dithering, although any resolution should still work fine.
For the video, I decided to play the music video of Rick Astley’s “Never Gonna Give You Up”, primarily because of its ‘perfect contrast’ for 1-bit dithering, and also because it’s a fun internet meme
After tackling many more bugs, crashes and other issues I finally had the program working and saving the data file. (yes, download at the bottom of the page)
All I then needed to do was then copy the file to the card and then watch the video!
The results were very impressive. After making the program more efficient I got it to run at a stable 15 frames per second!
I was simply amazed at how good the video looked and how it ran. I had used C++ to do this – No ASM, and it looked almost the same as the one I had seen previously in the other video. However, it should be noted that the other version had a higher resolution display and was running at half the clock speed (8Mhz compared to Arduino’s 16Mhz). There is definitely room for improvement that I will do at some stage. Most of the RAM on the Arduino is used up, but there is around 340 bytes available which should allow extra features. I am still using Adafruit’s library for the display, simply due to its inbuilt framebuffer and ease to draw pixels.
(video is at the top of the page)
In the end, it has been a good experience doing this project and I am impressed by my results. I hope these resources may be useful to others. There are definitely a lot of improvements that need to be made as there are many inefficiencies, but I will fix these at a later stage. Right now I am satisfied that it works perfectly.
Please note that the Processing sketches were written for Processing version 1.5.1. It will not work directly on the Processing 2.0+ betas, however it should be rather easy to port it over.
If you see any files with a .txt extension, just rename it to a .dat extension. There is no difference with the file content. I used it for debugging.
I have been attending the George Education Electronics Engineering & Computer Society, or G3ECS, and have been really enjoying it.
Anyone living in the George/Garden Route area should really attend this. We have a huge variety of people attending from all ages, and we are planning to build a couple of robots.
I enjoy it a lot as I get to work with people with the same interests as me, and many of my friends attend. It is also a great social gathering.