#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define LCD_WIDTH 16
LiquidCrystal_I2C lcd(0x27, LCD_WIDTH, 2);
// define variables
String txtMsg = "Arduino";
int i, j;
unsigned long previousMillis = 0;
const long interval = 50;
const long holdInterval = 5000;
enum State {
MOVE_CHAR_IN,
MOVE_CHAR_OUT,
WAIT_BETWEEN_CHARS,
HOLD_DISPLAY,
WAIT_BETWEEN_CHARS_OUT,
HOLD_DISPLAY_OUT
};
State currentState = MOVE_CHAR_IN;
void setup() {
Serial.begin(115200);
lcd.init();
lcd.clear();
lcd.backlight();
i = txtMsg.length() - 1; // start from last character
j = 0; // start from first LCD position
}
void loop() {
unsigned long currentMillis = millis();
switch (currentState) {
case MOVE_CHAR_IN:
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
lcd.setCursor(j, 1);
lcd.print(txtMsg[i]);
Serial.print(j);
Serial.print("--");
Serial.print(i);
Serial.print("--");
Serial.println(txtMsg[i]);
Serial.println("******************");
if (j > 0) {
lcd.setCursor(j - 1, 1);
lcd.print(' ');
}
j++;
if (j == i + 2) {
currentState = WAIT_BETWEEN_CHARS;
}
}
break;
case WAIT_BETWEEN_CHARS:
if (currentMillis - previousMillis >= interval) {
i--;
j = 0;
previousMillis = currentMillis;
if (i < 0) {
currentState = HOLD_DISPLAY;
} else {
currentState = MOVE_CHAR_IN;
}
}
break;
case WAIT_BETWEEN_CHARS_OUT:
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
i--;
j = i+1; // offset on screen
if (i < 0) {
currentState = HOLD_DISPLAY_OUT;
} else {
currentState = MOVE_CHAR_OUT;
}
}
break;
case HOLD_DISPLAY:
if (currentMillis - previousMillis >= holdInterval) {
i = txtMsg.length() - 1; // Setup for chars out
j = i+1; // offset on screen
previousMillis = currentMillis;
// lcd.clear();
currentState = MOVE_CHAR_OUT;
}
break;
case HOLD_DISPLAY_OUT:
if (currentMillis - previousMillis >= holdInterval) {
i = txtMsg.length() - 1; // Setup for chars out
j = 0; // start from first LCD position
previousMillis = currentMillis;
currentState = MOVE_CHAR_IN;
}
break;
case MOVE_CHAR_OUT:
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
lcd.setCursor(j, 1);
lcd.print(' ');
lcd.setCursor(j+1, 1);
lcd.print(txtMsg[i]);
j++;
if (j >=LCD_WIDTH)
currentState = WAIT_BETWEEN_CHARS_OUT;
}
break;
}
}