16x2 lcd display 8 custom character limit

custom character - cc

The classic 16x2 LCD display can remember 8 cc

I want to fill the entire screen with unique cc

What I wanted to do is create a cc, write it to the screen, overwrite the memory of the previous cc, move on position to the right on the screen and write the new cc to the screen.

Problem: When I overwrite the memory of cc, it changes the previous cc on the screen I had.

Example: I write a heart icon to memory, I display a heart in the first position, I overwrite the heart with a skull in memory, and I want to have the skull in the second position, but changing the memory also updates the cc in the first position. (This is not a problem with 2 characters, it becomes a problem when I want to have 32 cc)

The library I use to control the LCDis "LiquidCrystal.h"

Is there any workaround I can use that would allow me to have a custom character in every position?

I don't know about a workaround, but I suspect the code you didn't post may be at fault.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//my pins, dont matter
// make some custom characters:
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

byte Heart2[8] = {
0b00000,
0b11111,
0b11111,
0b11111,
0b01110,
0b00100,
0b10101,
0b00000
};

byte Heart3[8] = {
0b00000,
0b11111,
0b11111,
0b11111,
0b01110,
0b00100,
0b11111,
0b01010
};

void setup()
{
    Serial.begin(9600);
    lcd.begin(16, 2);
    lcd.clear();


    for (int i = 1; i <= 7; i++) {//creating 7 "custom" characters
        lcd.createChar(i, Heart);
        lcd.setCursor(i, 0);
        lcd.write(byte(i));
    }

    lcd.createChar(8, Heart2);//creating 8th truly custom character
    lcd.setCursor(8, 0);
    lcd.write(byte(8));

    lcd.createChar(9, Heart3);//overwrites memory, heart in position 1 is now this new one
    lcd.setCursor(9, 0);
    lcd.write(byte(9));
}

Don't custom characters start at zero?

The question I really have is if it is the library or the hardware that does this rewriting (will reply in a second to the second message)

There is no work around for having more than 8 custom characters.
It is the way the hd44780 h/w works.
If you need that much control/flexibility you will need to use a graphic lcd.
The hd44780 display chip sets are very old from the days when h/w was expensive and memory and processing power was very very limited.
The hd44780 h/w is limited to 8 custom characters.
The custom characters are character value code points 0-7 and repeated at 8-15
I.e. 0 is the same as 8, 1 is the same as 9 etc...
Characters are rendered on the display based on the character value code point.
The display re-renders the character based on its code point as the display is refreshed each and every time the display is refreshed which is happening many times per second.

i.e. the dots for a character are not stored on the display but the pixel pattern for a character is constantly fetched from its font table and redrawn.

What this means is if you write a custom character to the screen, the display will change that character on the display in realtime if/when you change its font definition.

--- bill

for (int i = 0; i < 8; i++) {//creating 7 "custom" characters
        lcd.createChar(i, Heart);
        lcd.setCursor(i, 0);
        lcd.write(byte(i));
    }

    lcd.createChar(8, Heart2);//creating 8th truly custom character
    lcd.setCursor(8, 0);
    lcd.write(byte(8));

    lcd.createChar(9, Heart3);//overwrites memory, heart in position 1 is now this new one
    lcd.setCursor(9, 0);
    lcd.write(byte(9));

now first position (0) icon is heart2, position (1) is heart3, position 2 through 7 are the hearts I set in the for loop because their memory has not been overwritten, position 8 has heart2, 9 has heart3

Because you created eight identical custom characters.

Maybe I've misunderstood something.

There is no custom character 8.

And since the 0-7 are the same as 8-15 if you change 8 you are changing 0
if you change 1 you change 9 etc ...

The h/w only looks at the lower 3 bits of the character address for custom characters.
It is a h/w limitation.

--- bill

There is no custom character 8.

Yes there is.
It is the same as 0.
8-15 is a duplicate of 0-7

--- bill

So, it's not a custom character.

I see, it is a hardware thing. I would have been much happier without the display refreshing, maybe then I could write new characters only in the places where I need them and not be concerned about the LCD rewriting characters I don't want to touch. I guess a graphic LCD is what I need. I wanted to make a game on the 16x2 char display, but it's very hard when you can only have 8 custom characters. I thought of the display as a 516 by 82 pixel display at first before I figured out about the 8 cc limit. I would prefer a display that is 1.5 by 6.5 cm wide for my little game console project (because I can't sadly use the 16x2 char one), are any displays like that available or would I need a custom one?

ALL LCD displays constantly refresh. They have to or you wouldn't see any pixels.
Character displays / chipsets can save RAM memory by only storing character values in the display RAM rather than bit patterns and then having a ROM to store the pattern for each character value.
They can create the bit patterns on the fly to drive the pixels on the physical display based on the character values in ram which is used to look up the bit pattern in a font table for the column/row as needed.

The hd44780 has 128 bytes of DDRAM to hold the display characters and 64 bytes of CGRAM for the 8 custom characters.
The primary font table for character values code points 16 to 255 is in ROM and can't be modified.
The font table entries for character code points 8-15 pull from the same CGRAM locations as code points 0-7

What can be confusing is that you technically can not define custom characters 8 to 15 as there is no way to address CGRAM beyond location 64 for the definition of those code points.
But you can display custom characters 8 to 15 as the internal h/w wraps them to correspond to the CGRAM entries for code points 0 to 7.
If you look at the creatChar() code in libraries they often truncate the custom character value code point to its lower 3 bits. But if they didn't and only limited to the value to 0-15 instead, it would still work since the extra bit created when doing the math for the CGRAM address would land where the 1 bit is in the set CGRAM address instruction.
i.e. the overlflow created by attempting to address the 8-15 custom character CGRAM (which does not exist) still works but wraps back to 0 to 7 memory locations.

So while there are only 8 custom characters, there are 16 custom character code points that can be displayed on the display.
0-7 and 8-15 where 8-15 duplicate 0 to 7.

--- bill