#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// LED pin definitions
const int LED1 = 1;
const int LED2 = 2;
const int LED4 = 4;
const int LED5 = 5;
const int LED6 = 6;
const int LED7 = 7;
const int LED9 = 9;
const int LED10 = 10;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Display texts
const char *LargeText1 = " PHNOME PENH TO POSAT ";
const char *LargeText2 = " POSAT TO BATTAMBANG ";
int iLineNumber = 1;
int iCursor = 0;
// Timer variables
unsigned long previousMillisLCD = 0;
const unsigned long intervalLCD = 200;
unsigned long previousMillisTraffic = 0;
const unsigned long intervalTraffic = 10000;
int KilometerStep = 0;
int NextKilometerStep = 0;
int NextNumber = 0;
bool isZero = false;
void setup() {
lcd.begin(16, 2);
lcd.backlight();
// Initialize LED pins as OUTPUT
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED9, OUTPUT);
pinMode(LED10, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (!isZero) {
setInitialLEDStates();
isZero = true;
}
if (currentMillis - previousMillisLCD >= intervalLCD) {
previousMillisLCD = currentMillis;
if (NextNumber == 1) {
displayLCD(LargeText2, " BUS1: PS-BB");
} else {
displayLCD(LargeText1, " BUS1: PP-PS");
}
}
if (currentMillis - previousMillisTraffic >= intervalTraffic) {
previousMillisTraffic = currentMillis;
updateKilometer();
}
}
void setInitialLEDStates() {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, HIGH);
digitalWrite(LED9, HIGH);
digitalWrite(LED10, LOW);
}
void displayLCD(const char *text, const char *header) {
int textLen = strlen(text);
if (iCursor == (textLen - 1)) {
iCursor = 0;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(header);
lcd.setCursor(0, iLineNumber);
if (iCursor < textLen - 16) {
for (int i = 0; i < 16; i++) {
lcd.print(text[iCursor + i]);
}
} else {
for (int i = iCursor; i < textLen; i++) {
lcd.print(text[i]);
}
for (int i = 0; i < 16 - (textLen - iCursor); i++) {
lcd.print(text[i]);
}
}
iCursor++;
}
void updateKilometer() {
switch (KilometerStep) {
case 0:
setLEDStates(LOW, LOW, HIGH, HIGH, HIGH, LOW, LOW, LOW);
break;
case 1:
setLEDStates(HIGH, HIGH, LOW, HIGH, HIGH, HIGH, LOW, HIGH);
break;
case 2:
setLEDStates(LOW, HIGH, HIGH, HIGH, HIGH, HIGH, LOW, HIGH);
break;
case 3:
setLEDStates(LOW, LOW, HIGH, HIGH, HIGH, LOW, HIGH, HIGH);
break;
case 4:
setLEDStates(LOW, HIGH, HIGH, HIGH, LOW, HIGH, HIGH, HIGH);
break;
case 5:
setLEDStates(HIGH, HIGH, HIGH, HIGH, LOW, HIGH, HIGH, HIGH);
break;
}
KilometerStep++;
if (KilometerStep > 5) {
updateNextKilometer();
NextNumber = 1;
}
}
void updateNextKilometer() {
switch (NextKilometerStep) {
case 0:
setLEDStates(HIGH, HIGH, HIGH, HIGH, LOW, HIGH, HIGH, HIGH);
break;
case 1:
setLEDStates(LOW, LOW, HIGH, HIGH, HIGH, HIGH, LOW, LOW);
break;
case 2:
setLEDStates(HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH);
break;
case 3:
setLEDStates(LOW, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH);
break;
}
NextKilometerStep++;
if (NextKilometerStep > 3) {
updateKilometer();
}
}
void setLEDStates(int led1, int led2, int led4, int led5, int led6, int led7, int led9, int led10) {
digitalWrite(LED1, led1);
digitalWrite(LED2, led2);
digitalWrite(LED4, led4);
digitalWrite(LED5, led5);
digitalWrite(LED6, led6);
digitalWrite(LED7, led7);
digitalWrite(LED9, led9);
digitalWrite(LED10, led10);
}