Unwanted characters when displaying text on the LCD screen

Hi all.

I am in the process of optimizing the program. I'm moving some of the messages to EEPROM and using the EEPROM library :slight_smile: Each text in EEPROM is a block of 20 characters, and the text string is terminated with zero (``x00`), e.g.

const char menuView[] = { 
//        +-- string termination
//        v v- filled by space 
  "Current\0            "
  "Minimum\0            "
  "Average\0            "
  "Maximum\0            "
};

I created myself a simple procedure that fetches the content into a global variable char str[32] , whose parameter is the starting address (of the EEPROM). I retrieve the text as a structure, using EEPROM.get(adr,str);

char str[32];

void getEStr(int adr) { EEPROM.get(adr,str); }

void eprint(int adr) { getEStr(adr); lcd.print(str); }

I have a problem with unwanted characters when displaying text on the LCD screen after using the eprint procedure. The following appear at the end of the displayed text: a blank character and (probably) a x01 character. I say probably, because I just happen to have this character defined as my own (using lcd.createChar().

Earlier I also made a more long-winded procedure getEStr:

void getEStr(int adr) {
  byte spos=0;
  byte data=255;
  while ((data!=0) & (spos<20)) {
    data=EEPROM.read(adr++);
    str[spos++]=data;
  }
  while (spos<32) { str[spos++]=0; }
}

Unfortunately, this one, despite deleting the rest of the string as far as possible, also gave unwanted characters when displayed by lcd.print

I'll be honest and say that C++ is not my forte, but.... I no longer know what could be the cause of this behavior.

Why all the messing around with EEPROM.read() in a loop when EEPROM.get() can do it with a single command ?

I wrote that it was an earlier version, which I changed to EEPROM.get().

It was about the fact that no matter what method I use, I always have garbage at the end of the retrieved text, after displaying it on the screen.

Where is the code that put the string in EEPROM? maybe it has a mistake.

You could display the 32 data bytes on Serial Monitor to make sure that the bytes you are getting from EEPROM are what you expect.

Could some other part of your code be writing a blank and a 0x01 after you display the string from EEPROM?

The code that writes EEPROM is a separate sketch that only writes data to EEPROM.

const char menuView[] = {
  "Current\0            "
  "Minimum\0            "
  "Average\0            "
  "Maximum\0            "
};

int adr=0;

void setup() { 
  Serial.println(adr); EEPROM.put(adr,menuView); adr+=sizeof(menuView); 
}

In a nutshell, it looks like the above. Of course, there is more data input :slight_smile:

I rule out such a situation because it happens in different parts of the code.


I think I have stumbled upon the cause.

1 In the code presented in the first post, responsible for displaying the string (procedure eprint), a small error crept in. Instead of lcd.println(str); I gave lcd.print(str);.

2 Namely, when it uses lcd.println(str); additional characters appear on the LCD screen.

I conclude that this is a bug in the LiquidCrystal library, which uses the Print class. In this class, there is a println method that adds println codes to the end of the displayed text. Perhaps, instead of the null and x01 characters I assumed, these were the characters.

3 However, after changing in my code from lcd.println to lcd.print, the problem of unwanted characters disappeared.

Unfortunately, the way the Print class works, the lower level library that uses the Print class has no knowledge that println() is called.
The lower level class write() function in the library using the Print (LiquidCrystal in this case) is called for each individual character, which includes CR and LF/NL when println() is called.
The LiquidCrystal library can't tell if println() was called or if the sketch intentionally sent 0xd and 0xa
And since the neither the LiquidCrystal library nor the hd44780 chipset supports line endings, the 0d and 0a characters will map to custom characters 5 and 2
since 0x08 to 0x0f are the same as 0x00 to 0x07 custom characters.

The "bug" is technically in the way the Print class is defined and implemented and it can't be fixed in other libraries like LiquidCrystal

There are some potential work arounds for this.

The hd44780 library does some gcc foo inside its classes to force an error to break the compile if sketch code attempts to call println() to prevent the user from using it.
At some point the hd44780 library will support line endings by doing line wrapping and scrolling in the library code. When line endings are supported, println() will be enabled.

--- bill

1 Like

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