OK, this is the sketch that I used to try out user-defined characters on a four-row, 20 character LCD. If you have a two-row LCD, you'll have to change the calls to "drawbar" in the main loop. You'll need a potentiometer with the track connected to 0V and 5V, and the wiper connected to analog in 0. Turn (or slide) the pot to see the bar extend across the LCD. The crucial command to the LCD is 0x40, which is used to position the "cursor" in the CGRAM, which is where the user-defined characters are stored. A call to "home" is required after defining the characters, to put the cursor back into the main display memory. All this is documented in the HD44780 data sheet.
// lcd_test --- testing the 20x4 LCD for DorkSnow
// John Honniball
#include <LiquidCrystal.h>
LiquidCrystal lcd (8, 9, 10, 4, 5, 6, 7);
/* defChar --- set up a user-defined character in CGRAM */
void defChar (LiquidCrystal &thelcd, int asc, const unsigned char row[8])
{
int i;
if ((asc < 0) || (asc > 7))
return;
thelcd.command (0x40 | (asc << 3));
for (i = 0; i < 8; i++)
thelcd.write (row[i]);
thelcd.home ();
}
/* setup --- Arduino initialisation */
void setup ()
{
static unsigned char cheq[8] = {
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
};
static unsigned char bar0[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char bar1[8] = {
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
};
static unsigned char bar2[8] = {
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
};
static unsigned char bar3[8] = {
0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c
};
static unsigned char bar4[8] = {
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e
};
static unsigned char bar5[8] = {
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
};
lcd.clear ();
defChar (lcd, 0x00, bar0);
defChar (lcd, 0x01, bar1);
defChar (lcd, 0x02, bar2);
defChar (lcd, 0x03, bar3);
defChar (lcd, 0x04, bar4);
defChar (lcd, 0x05, bar5);
defChar (lcd, 0x06, cheq);
lcd.print ("Hello, DorkSnow");
}
/* loop -- Arduino main loop */
void loop ()
{
int ana;
// Read from potentiometer connected to analog pin 0
ana = analogRead (0);
lcd.setCursor (0, 1);
// Display analog value in decimal
lcd.print ("analogRead = ");
lcd.print (ana, DEC);
lcd.print (" ");
// Display two rows of "analog" bar-graph
// For a two-row LCD, change these next two lines to: drawbar (0, ana);
drawbar (2, ana);
drawbar (3, ana);
// Update rate is 50Hz (approx)
delay (20);
}
/* drawbar -- draw a bar on one row of the LCD */
void drawbar (int row, int ana)
{
int bar;
int i;
lcd.setCursor (0, row);
// Bar is 120 pixels long; analog range is 0..1023
bar = ((long int)ana * 120L) / 1023L;
// Each character cell represents six pixels
for (i = 0; i < bar / 6; i++)
lcd.write (0x05);
// Display last few pixels using user-defined characters (if not at extreme right)
if ( i < 20) {
lcd.write (bar % 6);
i++;
}
// Clear remainder of row
for ( ; i < 20; i++)
lcd.write (0x00);
}