/*
non blocking scrolling on any LCD line
https://forum.arduino.cc/t/help-on-my-simple-lcd-project/1094641/5
2023-02-25 noiasca
... and yes I know - that's awful code...
*/
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(32, 16, 2); // set the LCD address to 0x3F for a 16 chars and 2 line display
int PB = 2;
/*
void scrollMessage(int row, String message, int delayTime, int totalColumns)
{
for (int i = 0; i < totalColumns; i++)
{
message = " " + message;
}
message = message + " ";
for (int position = 0; position < message.length(); position++)
{
lcd.setCursor(0, row);
lcd.print(message.substring(position, position + totalColumns));
delay(delayTime);
}
}
*/
struct Scroll {
String message;
uint32_t previousMillis = 0;
uint16_t interval = 250; // former delayTime
uint8_t position = 0;
} scroll[2]; // two rows
void scrollMessageSet(byte row, String msg) {
scroll[row].message = msg;
}
void scrollMessageDo (byte row, uint32_t currentMillis = millis()) {
if (currentMillis - scroll[row].previousMillis > scroll[row].interval) {
scroll[row].previousMillis = currentMillis;
byte totalColumns = 16; // hardcoded, but you could make an parameter also
lcd.setCursor(0, row);
String message;
for (int i = 0; i < totalColumns; i++) {
message = " " + message;
}
message += scroll[row].message + " ";
lcd.print(message.substring(scroll[row].position, scroll[row].position + totalColumns));
if (scroll[row].position < message.length())
scroll[row].position++;
else
scroll[row].position = 0;
}
}
void setup() {
pinMode(PB, INPUT_PULLUP);
lcd.init();
lcd.clear();
lcd.backlight();
for (auto & i : scroll) i.message.reserve(16);
}
void loop() {
static uint8_t previousButtonState = LOW;
uint8_t currentButtonState = digitalRead(PB);
if (previousButtonState == LOW && currentButtonState == HIGH) {
lcd.setCursor(1, 0);
lcd.print("Hello World");
scrollMessageSet (1, "Welcome!");
delay(50); // dirty delay to debounce
} else if (previousButtonState == HIGH && currentButtonState == LOW) {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Let's begin!");
delay(50); // dirty delay to debounce
}
if (currentButtonState == HIGH) {
scrollMessageDo(1); // call the this to let the text scroll
}
previousButtonState = currentButtonState; // remember button state for next loop
}