Introduction: Custom Large Font for 16x2 LCDs
A couple of years ago i was learning to use the Ardiuno and started playing around with an Hitachi HD44780 based 16x2 LCD screen. I soon learned that the screen has 8 customizable character slots. I had found a project where someone used those slots to create there own custom characters that could then be used to form large character font using both rows of the screen. I didn't like the look of those characters and couldn't make since of the sketch that person wrote. So i decided i needed to create my own set and use my limited programming skills to create a more user friendly sketch to support my large character font.
In this Instructable i'll show you how i designed my large character font and break down the sketch to make it easier to understand. But first we need to set up the Arduino and LCD.
Here is the finished font
In this Instructable i'll show you how i designed my large character font and break down the sketch to make it easier to understand. But first we need to set up the Arduino and LCD.
Here is the finished font
Step 1: Connecting the LCD to the Arduino
First i want to cover how to connect a Hitachi HD44780 based LCD screen to an Arduino. The first thing you need to do is identify Pin 1 on your display and figure out which pins you need. The first image shows a very simple layout for connecting the LCD to your Arduino. Here is the pin Layout for the LCD.
My LCD only had 15 pins which is fine since 16 should be tied to ground anyway. As you can see in the picture Vee is tied into a potentiometer. This controls the contrast of the screen. The data pins are the individual bits your writing to or reading from the register.
For the purposes of keeping things simple i wired mine up a bit differently. I like to use ribbon cable whenever possible to keep the clutter of wires down. I makes keeping track of the connections allot easier too.
- Pin 1 - Grd
- Pin 2 - VCC
- Pin 3 - Vee (controls screen contrast)
- Pin 4 - RS (controls where in the LCD's memory your writing too)
- Pin 5 - RW (controls weather your Reading or Writing to the LCD)
- Pin 6 - E (enables writing to the register)
- Pin 7 - D0 (not used)
- Pin 8 - D1 (not used)
- Pin 9 - D2 (not used)
- Pin 10 - D3 (not used)
- Pin 11 - D4
- Pin 12 - D5
- Pin 13 - D6
- Pin 14 - D7
- Pin 15 - LED+ (LCD back light)
- Pin 16 - LED- (Grd)
My LCD only had 15 pins which is fine since 16 should be tied to ground anyway. As you can see in the picture Vee is tied into a potentiometer. This controls the contrast of the screen. The data pins are the individual bits your writing to or reading from the register.
For the purposes of keeping things simple i wired mine up a bit differently. I like to use ribbon cable whenever possible to keep the clutter of wires down. I makes keeping track of the connections allot easier too.
- RS pin to D7
- E pin to D6
- D4 pin to D5
- D5 pin to D4
- D6 pin to D3
- D7 pin to D2
- V0 tied to a pot to control brightness
- Grd and R/W tied to ground
- Vcc to +5V
- pin 15 to push button/switch that is tied to ground for control of back light
Step 2: Numerical Font Design
It then came time to think about the font design. What kind of segments would i need to create to make a nice and sharp looking large character font for this screen?
I wanted to start simple and get numbers out of the way first. I figured people would be looking for a good large font to use for an Arduino based digital clock or other project. So logically i started by designing the number 8 since all the segments that comprise the 8 can be mixed to create most of the other numbers. This used up only 6 of the custom blocks. But i still needed one more custom block to be able to display a 0, 1 and 7.
The images show the first generation of numbers i produced. A couple of changes where made in the custom blocks to make the numbers look better. I'll show them in a later step.
I wanted to start simple and get numbers out of the way first. I figured people would be looking for a good large font to use for an Arduino based digital clock or other project. So logically i started by designing the number 8 since all the segments that comprise the 8 can be mixed to create most of the other numbers. This used up only 6 of the custom blocks. But i still needed one more custom block to be able to display a 0, 1 and 7.
The images show the first generation of numbers i produced. A couple of changes where made in the custom blocks to make the numbers look better. I'll show them in a later step.
Step 3: Letter Font Design
After i had created the numbers i moved on to designing letters. I got request from people for letters that are commonly used in Temp, RPM, and Speed displays. So i went ahead and created the full alphabet. To get everything looking right i needed to use the final available custom character block.
The images show the first generation of letters i produced. A couple of changes where made in the custom blocks to make the letters look better. I'll show them in the next step.
The images show the first generation of letters i produced. A couple of changes where made in the custom blocks to make the letters look better. I'll show them in the next step.
Step 4: Refining the Look
My first design for the letters where too rounded for my taste. I then learned how to call up the various predefined characters the LCD is able to display. So i pulled up the Data sheet on the Hitachi HD44780 driver so see the available characters.I noticed the last character is a solid block so i decided to use that in conjunction with the custom characters. I also need the blank character right above the full block. I made a slight adjustment to the custom characters i created and we where ready to build a sketch.
Here is a video of the original characters scrolling across the screen. Some changes have been made since this video was taken.
Here is a video of the original characters scrolling across the screen. Some changes have been made since this video was taken.
Step 5: Arduino Sketch
The attached files below are the Arduino sketch that creates the large font and scrolls it across the screen. I've included the sketch in both ide and text format. It has had a couple of updates since the video. Namely the upper left segment of the number 5 has been changed to the full block to help differentiate it from the S. Also the bottom of the 1, 4 and 9 have been changed to the solid box. What follows is a break down of the sketch in hopes of making it easier to understand so you can adapt it for your own project. A more usable but less understandable sketch was created and is give in the next step.
In the code i first want to lay out the basic info about the sketch and the circuit layout.
To help control the LCD we use the LiquidCrystal.h Library. (#include)
We then set the pins on the Arduino that will be used to control the LCD.
Next the sketch sets up 8 arrays which create and store the 8 customized characters that are used to create the large font. Each array is in Binary. The zeros are blank pixels in the character blocks and the ones represent filled in pixels. The abbreviations i used where to help me keep track of where each block would go in reference to building the large number 0. I have labeled the image to give you a better understanding of the segments and there labels.
Next we have a set of void customxx() that define the placement of each custom block to create the large font. In each one we first set the cursor on the screen where we want to start displaying the blocks needed. Lets look at the first one.
void custom0O()
{ // uses segments to build the number 0
lcd.setCursor(x, 0); Sets cursor on the first row of the display at location x (x used as a variable that can change so the characters can scroll across the screen)
lcd.write(8); places the LT segment
lcd.write(1); places the UB segment
lcd.write(2); places the RT segment
lcd.setCursor(x, 1); Moves cursor to 2nd row
lcd.write(3); places the LL segment
lcd.write(4); places the LB segment
lcd.write(5); Places the LR segment
}
When we get down to the '5' we start using the solid block which is located at address 255. When we reach the 'A' we use a blank block located at address 254. Its important to note that some Hitachi HD44780 compatible screens will have a blank character at 255 and the solid character will be at 254.
void custom5()
{
lcd.setCursor(x,0);
lcd.write(255);
lcd.write(6);
lcd.write(6);
lcd.setCursor(x, 1);
lcd.write(7);
lcd.write(7);
lcd.write(5);
}
After we have defined all the letters we lay out the scrolling of the letters. Since the screens buffer isn't large enough we need to break it down into groups that only use 40 columns. Most of the letters only take up 3 columns plus you use 1 column to keep a space between letters. So we lay it out for the first scrolling group to be A, B, C, D, E, F, G, H, I, and J. We throw a small delay on there so you can see the last couple of letters before it clears the screen to move onto the next group. It takes 4 groups to show all the characters on the screen.
Now we reach the main body of the sketch the void loop(). Here we make a call to the first letter group we defined which lays out the letters into the screen's buffer. We then start a For() statement which starts the letters scrolling across the screen. We give it a slight delay after each column shift so the letters are not blurred. When the For() statement is complete we clear the LCD display and have a short delay before moving onto the next group. The sketch will just keep scrolling through all the letter and number groups until you cut the power.
That pretty much covers the sketch. The pictures do a good job of showing the full font. If there is anything i missed or was unclear on please let me know and i'll update this step accordingly.
In the code i first want to lay out the basic info about the sketch and the circuit layout.
To help control the LCD we use the LiquidCrystal.h Library. (#include
We then set the pins on the Arduino that will be used to control the LCD.
Next the sketch sets up 8 arrays which create and store the 8 customized characters that are used to create the large font. Each array is in Binary. The zeros are blank pixels in the character blocks and the ones represent filled in pixels. The abbreviations i used where to help me keep track of where each block would go in reference to building the large number 0. I have labeled the image to give you a better understanding of the segments and there labels.
- LT= left top
- UB= upper bar
- RT= right top
- LL= lower left
- LB= lower bar
- LR= lower right
- UMB= upper middle bar(upper middle section of the '8')
- LMB= lower middle bar(lower middle section of the '8')
Next we have a set of void customxx() that define the placement of each custom block to create the large font. In each one we first set the cursor on the screen where we want to start displaying the blocks needed. Lets look at the first one.
void custom0O()
{ // uses segments to build the number 0
lcd.setCursor(x, 0); Sets cursor on the first row of the display at location x (x used as a variable that can change so the characters can scroll across the screen)
lcd.write(8); places the LT segment
lcd.write(1); places the UB segment
lcd.write(2); places the RT segment
lcd.setCursor(x, 1); Moves cursor to 2nd row
lcd.write(3); places the LL segment
lcd.write(4); places the LB segment
lcd.write(5); Places the LR segment
}
When we get down to the '5' we start using the solid block which is located at address 255. When we reach the 'A' we use a blank block located at address 254. Its important to note that some Hitachi HD44780 compatible screens will have a blank character at 255 and the solid character will be at 254.
void custom5()
{
lcd.setCursor(x,0);
lcd.write(255);
lcd.write(6);
lcd.write(6);
lcd.setCursor(x, 1);
lcd.write(7);
lcd.write(7);
lcd.write(5);
}
After we have defined all the letters we lay out the scrolling of the letters. Since the screens buffer isn't large enough we need to break it down into groups that only use 40 columns. Most of the letters only take up 3 columns plus you use 1 column to keep a space between letters. So we lay it out for the first scrolling group to be A, B, C, D, E, F, G, H, I, and J. We throw a small delay on there so you can see the last couple of letters before it clears the screen to move onto the next group. It takes 4 groups to show all the characters on the screen.
Now we reach the main body of the sketch the void loop(). Here we make a call to the first letter group we defined which lays out the letters into the screen's buffer. We then start a For() statement which starts the letters scrolling across the screen. We give it a slight delay after each column shift so the letters are not blurred. When the For() statement is complete we clear the LCD display and have a short delay before moving onto the next group. The sketch will just keep scrolling through all the letter and number groups until you cut the power.
That pretty much covers the sketch. The pictures do a good job of showing the full font. If there is anything i missed or was unclear on please let me know and i'll update this step accordingly.
Step 6: More Efficient Sketch
A few days after i had posted my code on the Arduino forums back in early 2010, Mark S adapted it to be table driven. Since it is table driven it uses no RAM. While it complicates the sketch a bit it is a more efficient way of setting up the large font and goes a long way to making the fonts usable. I don't fully understand it myself but i'm including the code here in text form only.
This was made back in 2008 on IDE 0.8. Things have changed a bit since then so the sketch might not compile. I had to make some adjustments to my original sketch before i could post it here since the Liquid CrystalLibrary had changed a bit since i last used the sketch.
Here is a link to the thread in the Arduino Forum Archives where i first demonstrated this custom font. There you can read about the evolution that took place in refining the font and the sketch.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265696343/0
This was made back in 2008 on IDE 0.8. Things have changed a bit since then so the sketch might not compile. I had to make some adjustments to my original sketch before i could post it here since the Liquid CrystalLibrary had changed a bit since i last used the sketch.
Here is a link to the thread in the Arduino Forum Archives where i first demonstrated this custom font. There you can read about the evolution that took place in refining the font and the sketch.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265696343/0