LCD Special characters on EEPROM

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};

void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);  
  lcd.write(byte(0));
}

void loop() {}

Is it possible to read/write the byte smiley to EEPROM of Arduino Nano? This could help save ROM space by storing more than 8 special characters in the eeprom. And then reading from the EEPROM to reconfigure the special characters and set the bytes on the LCD. Is there a example code for it m

lcd.createChar Expects data in RAM so you would have to bring the array from PROGMEM or eeprom in RAM before calling the function. I suggest you look at PROGMEM.

They have code to store an array in flash and they show how to read it back

1 Like

I want to store the array in EEPROM instead of flash(program) memory.

You would need to either copy the array from EEPROM to ram before calling createChar(), or modify the library function to read from EEPROM. If you are not going to use the EEPROM for anything else, it might take less flash memory to directly store the arrays in PROGMEM instead of including the EEPROM library.

Note that you are still limited to displaying eight custom characters at a time on the LCD.

Any reason for this?
You’ll need a code to get them there (unless you use avrdude) and then another code (if you don’t want the memory usage) to read them out. You won’t save much flash memory doing so.

1 Like

I am using the eeprom to store some data.

I am running out of program memory. If I could use the eeprom memory it would help. The code provided is only an example. I have 32 special characters

Yes. You can certainly use EEPROM.put() and EEPROM.get() to store a byte array.

The limit of 8 special characters is a limitation of the LCD itself. Using EEPROM won't help. You can have as many special characters as you like stored in ROM (Flash), RAM or EEPROM, but you can only have a maximum of 8 displayed on the LCD at any moment.

What are you trying to achieve? Maybe a graphic LCD would be what you need.

Yes you are right,the LCD has a limitation of 8 special characters but I can redefine them and get new characters to display. Graphic LCD would be a good option but I am already using 20x4 LCD display. If I don't get a proper alternative then I may have to use 2 Arduino nano due to physical size limitation.

Can you please provide a code example using special characters. I am not an expert in programming.

I don't understand what you are saying. A proper alternative to what? What makes using 2 Nano a better alternative? I am very skeptical about that. What size limitation are you taking about?

As other have said, I don't think this will improve your memory situation but here's something to try.

You should study the examples in the eeprom library to see how to use the .put() and .get() programs.

You will need to write a separate program to load the characters into the eeprom.

Then you will load your program which uses the characters. Read them from the addresses where stored and create the custom characters.

Here's some example code for .put() and .get() with the character arrays. I have not broken this example up into the separate code for writing the eeprom to use before accessing the characters in your program.

#include <EEPROM.h>
// make some custom characters and store them
byte heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000
};

byte smiley[8] = {
  0b00000,
  0b00000,
  0b01010,
  0b00000,
  0b00000,
  0b10001,
  0b01110,
  0b00000
};

//specify eeprom storage locations
//must be 8 bytes appart for each character
int smileyAddress = 0;
int heartAddress = 8;

void setup() {

  Serial.begin(115200);

  byte get_smiley[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  byte get_heart[8] = {0, 0, 0, 0, 0, 0, 0, 0};

  EEPROM.put(smileyAddress, smiley);
  EEPROM.put(heartAddress, heart);

  EEPROM.get(smileyAddress, get_smiley);
  EEPROM.get(heartAddress, get_heart);


  //verify what you stored
  Serial.println("Smiley:");
  for (byte i = 0; i < 8; i++)
  {
    Serial.println(get_smiley[i], BIN);
  }

  Serial.println("Heart:");
  for (byte i = 0; i < 8; i++)
  {
    Serial.println(get_heart[i], BIN);
  }
  //create custom chars from retreived arrays
}

void loop() {}
1 Like

If you define a character, display it, redefine it and display it again then the previously displayed character will immediately change to the new definition on screen

The only way that your plan could work would be if a maximum of 8 different user defined characters are on display at a time

Here is an example of the code from @cattledog, using a modified version of the createChar() function so that no buffer is needed when reading the custom character out of EEPROM. This assumes you are using the LiquidCrystal library that is bundled with the Arduino IDE, there are other libraries that use the same name and may not function properly with this code.

#include <LiquidCrystal.h>
#include <EEPROM.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// make some custom characters and store them
byte heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000
};

byte smiley[8] = {
  0b00000,
  0b00000,
  0b01010,
  0b00000,
  0b00000,
  0b10001,
  0b01110,
  0b00000
};

//specify eeprom storage locations
//must be 8 bytes appart for each character
const int smileyAddress = 0;
const int heartAddress = 8;

//custom function to load custom character from EEProm
//this is a modified version of LiquidCrystal::createChar()
void createCharEEProm(uint8_t location, int charAddress) {
  location &= 0x7; // we only have 8 locations 0-7
  lcd.command(LCD_SETCGRAMADDR | (location << 3));
  for (int i = 0; i < 8; i++) {
    lcd.write(EEPROM.read(charAddress + i));
  }
}

void setup() {
  Serial.begin(115200);
  EEPROM.put(smileyAddress, smiley);
  EEPROM.put(heartAddress, heart);

  createCharEEProm(0, smileyAddress);
  createCharEEProm(1, heartAddress);

  lcd.begin(16, 2);
  lcd.write(byte(0));
  lcd.write(byte(1));
}

void loop() {}
2 Likes

Thats exactly my plan

I am talking about PHYSICAL SIZE LIMITATION. I can put 2 Nano and use i2c communication but there is no space to put a Mega in my Box that is holding the other hardwares.

thanks this was exactly what i was looking for.

At a similar price point (under $5 USD) and physical size as a nano,
You could switch to another device like an ESP8266 based one like a WEMOS D1 mini or a NodeMCU and then have gobs of flash and RAM and a MUCH faster 32 bit processor with Wifi capability.
Like 128x to 512x the FLASH and 40x the RAM so the storage and access issues go away.

--- bill

Or for also the same price one of the ESP32 C3 mini board - will be much smaller in size than two Nano (even than just one)