'Corrupt' LCD special characters

I’m working on a project with an LCD display, which includes a few special characters.

It all works as expected, but occasionally when I upload fresh code and/or reset the Ardiuno, one or more of my special characters renders incorrectly - the pixels for that character just look messed up. Resetting the Arduino will sort it out and the character will display correctly again without any changes to the code.

What could be causing this? Is there anything I can do in my code to prevent this?

Also, what is the max number of special characters I can define? It appears that if I define more than 8 (0 to 7) I start overwriting ones already defined.

Please show us your code, in code tags, please. It's virtually impossible to help with the information you've given us.

Also, what is the max number of special characters I can define? It appears that if I define more than 8 (0 to 7) I start overwriting ones already defined.

That’s because the limit is 8.

Thanks. Below is my code as it currently stands. (Note I’ve recently moved this from a 16x2 LCD to this 20x4 and had the same problem on both.)

I’ve also attached a photo showing the display with the corrupt character top right of screen. It should be a ‘F’ reversed out like the ‘E’ at the other end of the scale. The bottom half seems to be borrowed from my degrees centigrade special character.

/*
 
  LiquidCrystal Library
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 */

// include the library code:

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// SET UP SENSOR VARIABLES

float Lvolt = 0.00; // leisure battery voltage
float Svolt = 0.00; // starter battery voltage
float Itemp = 0.00; // inside temperature
float Etemp = 0.00; // external temperature

// SET UP SPECIAL CHARACTERS

// Boxed L

byte Lbox[8] = {
  B11111, B10111, B10111, B10111, B10111, B10001, B11111, B00000
};

// Boxed S
byte Sbox[8] = {
  B11111, B10001, B10111, B10001, B11101, B10001, B11111, B00000
};

// Boxed F
byte Fbox[8] = { 
  B11111, B10001, B10111, B10011, B10111, B10111, B11111, B00000  
};

// degress centigrade symbol
byte degreessymbol[8] = {
  B01000, B10100, B01000, B00011, B00100, B00100, B00011, B00000
};

// Boxed E
byte Ebox[8] = { 
  B11111, B10001, B10111, B10011, B10111, B10001, B11111, B00000  
};

// Empty battery bar
byte emptybattbar[8] = { 
  B11011, B00000, B00000, B00000, B00000, B00000, B11011, B00000  
};

// half full battery bar
byte halfbattbar[8] = { 
  B11011, B11000, B11000, B11000, B11000, B11000, B11011, B00000  
};

// half full battery bar
byte fullbattbar[8] = { 
  B11011, B11011, B11011, B11011, B11011, B11011, B11011, B00000  
};


void setup() {
  
// create the special characters

  lcd.createChar(0, emptybattbar);
  lcd.createChar(1, halfbattbar);
  lcd.createChar(2, fullbattbar);
  lcd.createChar(3, Lbox);
  lcd.createChar(4, Sbox);
  lcd.createChar(5, Ebox);
  lcd.createChar(6, Fbox);
  lcd.createChar(7, degreessymbol);
  
// set up the LCD's number of columns and rows: 

  lcd.begin(20, 4);
  
// Print a splash message to the LCD.

  lcd.setCursor(5, 1);
  lcd.print("BONGOSTATS");
  lcd.setCursor(8, 2);
  lcd.print("v0.1");
  delay (1000);
  
// clear the screen
  
  lcd.clear();
 
}

void loop() {
  
  // read the leisure battery voltage
  
  int Lvalue = analogRead(A0);
  float Lvolt = Lvalue * (17.0 / 1023.0); 
  
  // read the starter battery voltage
    
  int Svalue = analogRead(A1);
  float Svolt = Svalue * (17.0 / 1023.0);
  
  //get the voltage reading from the internal temperature sensor and convert to degrees centigrade
  
  int Itempreading = analogRead(A2);
  float Itempvoltage = Itempreading * 5.0;
  Itempvoltage /= 1024.0;
  float Itemp = (Itempvoltage - 0.50) * 100 ; //converting from 10 mv per degree wit 500 mV offset
  
  //get the voltage reading from the external temperature sensor and convert to degrees centigrade
  
  int Etempreading = analogRead(A3);
  float Etempvoltage = Etempreading * 5.0;
  Etempvoltage /= 1024.0;
  float Etemp = (Etempvoltage - 0.50) * 100 ; //converting from 10 mv per degree wit 500 mV offset
  
  //set up the LB volt field titles
  
  lcd.setCursor(0, 0);
  lcd.write(byte(3));
  
  // display the LB charge level graphic
  
  lcd.setCursor(8, 0);
  lcd.write(byte(5));
  
  if (Lvolt >= 11.51){
  lcd.write(byte(2));
  } else if (Lvolt >= 11.00){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }

  if (Lvolt >= 11.66){
  lcd.write(byte(2));
  } else if (Lvolt >= 11.58){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 11.81){
  lcd.write(byte(2));
  } else if (Lvolt >= 11.73){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 11.96){
  lcd.write(byte(2));
  } else if (Lvolt >= 11.88){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.10){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.03){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.24){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.17){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.37){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.30){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.50){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.44){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.62){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.56){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }
  
  if (Lvolt >= 12.73){
  lcd.write(byte(2));
  } else if (Lvolt >= 12.68){
  lcd.write(byte(1));
  } else {
  lcd.write(byte(0));
  }

  lcd.setCursor(19, 0);
  lcd.write(byte(6));
  
  //set up the SB volt field titles
  
  lcd.setCursor(0, 1);
  lcd.write(byte(4));

  // display the volt data
  
  lcd.setCursor(1, 0);
  lcd.print(Lvolt,2);
  lcd.print("v");
  
  // display the internal temperature data
  
  lcd.setCursor(0, 2);
  lcd.write("In ");
  lcd.print(Itemp,1);
  lcd.write(byte(7));
  
  // display the external temperature
  
  lcd.setCursor(0, 3);
  lcd.write("Out ");
  lcd.print(Etemp,1);
  lcd.write(byte(7));
  lcd.write(" ");
  
  // add ice symbol if external temperature below 4 degrees
  
  if(Etemp <= 4)
  {
  lcd.write("*");
  }
  else 
  {
  lcd.write(" ");
  }
  
  // wait a second before updating the display again
  
  delay (1000);
}

IMG_7445.jpg

I had a similar issue and fixed it by turning LCD updates off while I loaded the characters or refreshed the data for the display and then turned it back on. Not sure why (speed or timing?) but it has worked reliably since.