I will get to my question after this intro.
I bought a 4 line by 40 character LCD display module with and I2C module included (and soldered) from AliExpress. (https://www.aliexpress.us/item/2251832722412443.html?spm=a2g0o.productlist.main.1.38f9RBWTRBWTdC&algo_pvid=fa9b48e4-c3f4-4bd6-a4e7-3bada83e51d0&algo_exp_id=fa9b48e4-c3f4-4bd6-a4e7-3bada83e51d0-0&pdp_ext_f={"order"%3A"337"%2C"eval"%3A"1"%2C"fromPage"%3A"search"}&pdp_npi=6%40dis!USD!19.99!10.99!!!19.99!10.99!%402101dedf17818364099575145ef848!66912239675!sea!US!4141740272!X!1!0!n_tag%3A-29919%3Bd%3Af238f64e%3Bm03_new_user%3A-29895&curPageLogUid=uMeVW7h14EbV&utparam-url=scene%3Asearch|query_from%3A|x_object_id%3A32908727195|_p_origin_prod%3A)
The manufacturer is Surenoo. I did see several 40x4 LCD libraries on github, but I had trouble getting them to display 4 lines with 40 characters. Some only displayed two lines. But rather than troubleshoot why my code wasn't doing what I wanted, I looked for and found the manufacturer's documentation and Arduino library.
Surenoo's page for this product is Surenoo 4004 Character LCD Module Display Panel Screen . Norton didn't like that URL, but I told Norton to make an exception.
The software libraries for this are on a Google drive, SLC4004 Series - Google Drive
The Arduino example sketch demonstrates most of the functions for this LCD display. The one feature I thought would be useful but is not in the *.h file is a function that would scroll lines up and down.
So I decided to script a way to do that. My script takes a long string, breaks it up into line-sized substrings and scrolls existing lines up as new line segments are added to the bottom line.
This is my problem: The first line substring does move up to display the second substring. But when the third substring is added, the previous lines move up, but the first line apparently does not display on the second row as expected.
I do see that it does flicker in the correct place, but that line immediately goes blank. The same is true as new lines are added to the bottom. The top two lines briefly flicker the display of the correct substrings but go blank.
So I only have the text showing on the bottom two lines of the display. I added four serial monitor print lines to confirm that I am handling the breaking up of the text into substrings properly. But I cannot see why the top two lines show the correct substrings briefly and then go blank.
Here is my code:
/*
Sketch Name: LCD_40x4_Scroll_Text_Up
Takes a large text string, breaks it into lines of 40 or fewer characters and
scrolls it up the display.
*/
#include <LiquidCrystal_I2C_4004.h>
#include <avr/pgmspace.h>
bool DEBUG = true; // Set to false to disable debugging prints to the serial monitor
const byte lcdAddr = 0x27; // Address of I2C backpack
const byte lcdCols = 40; // Number of character in a row
const byte lcdRows = 4; // Number of lines
LiquidCrystal_I2C lcd(lcdAddr, lcdCols, lcdRows); // set the LCD address to 0x27 for a 16 chars and 2 line display
int currPosition = 0; // the beginning of the next 40-character substring
int currLine = 3; // Put the most recent substring on the last line (3) of the display and scroll up.
String line0 = "";
String line1 = "";
String line2 = "";
String line3 = "";
String thisLine = ""; // The next substring to be added to the dispolay
/* ----------------- A test string to display ----------------- */
String text = "Tomorrow, and tomorrow, and tomorrow, "
"Creeps in this petty pace from day to day, " "To the last syllable of recorded time; " "And all our yesterdays have lighted fools " "The way to dusty death. Out, out, brief candle! " "Life's but a walking shadow, a poor player, " "That struts and frets his hour upon the stage, " "And then is heard no more. It is a tale " "Told by an idiot, full of sound and fury, " "Signifying nothing.";int msgLength = text.length(); // To stop the parsing when the entire input text is processed.
String getNextSubstring(int startPos) { // Get substrings of the message text, breaking at the last space in the next 40 characters.
String thisLine = text.substring(startPos, startPos + 40); // the 40 will be trimmed to the last space in those 40 characters
int lastSpace = thisLine.lastIndexOf(' ');
if (lastSpace == -1) {
thisLine = text.substring(startPos, startPos + thisLine.length());} else {
thisLine = text.substring(startPos, startPos + lastSpace); // This is the line to display}
if (DEBUG) {
Serial.print("startPos = "); Serial.print(startPos); Serial.print(" -- lastSpace = "); Serial.println(lastSpace); Serial.print("thisLine = "); Serial.println(thisLine);}
currPosition = startPos + thisLine.length() + 1; // where the next substring starts
if (DEBUG) {
Serial.print("currPosition = "); Serial.println(currPosition);}
return thisLine;
}
void scrollLinesUp(String lastLine) {
if (DEBUG) { Serial.println("------------ Scroll Lines Up ------------------");}
line0 = line1;
line1 = line2;
line2 = line3;
line3 = lastLine;
/* Just to prove that the display lines are being parsed correctly from the sample text.
Serial.print("Line0: ");
Serial.println(line0);
Serial.print("Line1: ");
Serial.println(line1);
Serial.print("Line2: ");
Serial.println(line2);
Serial.print("Line3: ");
Serial.println(line3);
*/
//lcd.clear(0); // Clear the first line
lcd.setCursor(0, 0);
lcd.print(line0);
lcd.clear(1); // Clear the second line
lcd.setCursor(0, 1);
lcd.print(line1);
lcd.clear(2); // Clear the third line
lcd.setCursor(0, 2);
lcd.print(line2);
lcd.clear(3); // Clear the fourth line
lcd.setCursor(0, 3);
lcd.print(line3);
}
void setup() {
lcd.begin();
Serial.begin(9600);
delay(1000);
lcd.home();
lcd.backlight();
lcd.setCursor(0, 0);
Serial.print("text length = ");
Serial.println(text.length());
}
void loop() {
if (DEBUG) {
Serial.print("Main loop -- currPosition = "); Serial.print(currPosition); Serial.print(" -- currLine = "); Serial.println(currLine);}
if (currPosition < msgLength) { // Stop parsing when the full text has been displayed
String thisLine = getNextSubstring(currPosition); scrollLinesUp(thisLine);}
delay(500);
if (currPosition > msgLength) { DEBUG = false; } //Stop printing to the monitor when the message has been completed.
}