Using LiquidCrystal to Print custom character as location 0

Hi,

In the library file of LiquidCrystal we have for createChar the following:

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (int i=0; i<8; i++) {
    write(charmap[i]);
  }
}

This means that there is up to 8 chars you can set with that function. However for the location 0 when you do the following as expected you get no output, this because 0 also means end of line '\0'!

lcd = new LiquidCrystal(rs, en, d0, d1, d2, d3, d4, d5, d6, d7);

uint8_t user_char[8] = {0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b00000};
lcd->createChar(0, user_char);

char myChar[] = {0, 0};
lcd->print(myChar);

So my question, how do I print a custom char using the 0 location?

Thanks

print char(8). this is the same as char(0)

That means that the library does location &= 0x7; somewhere when printing, however I don't find it anywhere besides in the createChar method. Is it the Arduino print that does that operation? It works BTW.

char myChar= 0;
lcd->print(myChar);

Now it's not a string-ending anymore!

No, it means you can't define more than eight custom characters.

The common hd44780 LCD controller chip maps custom characters 8 thru 15 to 0 thru 7, so you can use char(8) or "\10" for the octal representation embedded in a text string. For whatever reason the hd44780 was designed to handle 16 custom characters, but only has memory for 8.

I had this a little messed up the first time...

"For whatever reason. . ." the instruction set identifies each instruction by determining which is the highest non-zero bit. It disregards that bit and any preceding (higher) zeros and uses the remaining bits to determine what to do, in this case where to store the data and what data to store.

The 'Set DDRAM address' instruction, which is used to create custom characters, is defined by a '1' at DB6. This leaves the remaining 6 bits (DB5 -DB0) to determine the address at which to store the character and the character itself. The address info goes into DB5-DB3 and the character info goes into DB2-DB0.

We only have three bits available to specify where to store characters which is why we are limited to 8 of those characters.

The reason that address 8 can be used is due to the fact that only the lowest three bits are considered during the evaluation of the instruction.
0 is 0000
8 is 1000
Note that the lower three bits are the same in both cases.

This addressing information is summarized in Table 5 of the HD44780 data sheet.
The term for multiple addresses accessing the same memory location is 'memory foldback' if you want to search for more information.

Don

The argument type being passed to print() in this case is a char *
which is treated as a C string by the Print class.
It is not possible to have a zero character inside a C string.

For the way you have currently defined your data, the simplest thing would be call write() instead.
i.e.

  lcd.write(myChar, sizeof(myChar));

Alternatively if you want to use print() there are some alternatives to use the zero location custom character.

You can pass print() each character separately as a char type. i.e.

lcd.print(mychar[0]);
lcd.pritn(mychar[1]);

Or define your C string in a way that it can be used as C string to print the 0 location custom character by using the alternate/duplicate custom character positions. i.e. '\010' is the same custom character on the LCD as '\0'

char myChar[] = {'\010', '\010', 0};
lcd.print(myChar);

or

char *myChar = "\010\010";
lcd.print(myChar);

or

lcd.print("\010\010");

If you install the hd44780 library, there is an example sketch called LCDCustomChars that shows many tips/tricks for how to use custom characters.

And unlike the LiquidCrystal library you can also do this for custom character 0:

lcd.write(0);

--- bill

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.