#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int buttonPin = A1;
int currentPage = 0;
const int totalPages = 5;
int truckDamage = 0;
int trailerDamage = 0;
byte truckIcon[8] = {B00000,B01111,B01001,B01001,B01111,B00111,B01111,B00110};
byte truckIcon2[8] = {B11000,B11000,B11000,B11000,B10000,B11111,B11111,B00000};
byte truckIcon3[8] = {B00000,B00000,B00000,B00000,B11100,B11110,B11110,B01100};
byte trailerIcon[8] = {B00000,B00000,B11111,B11111,B11111,B11111,B00000,B00000};
byte trailerIcon2[8] = {B00000,B00000,B11111,B11111,B11111,B11111,B01110,B00000};
byte trailerIcon3[8] = {B00000,B00000,B11111,B11111,B11111,B11111,B00110,B00110};
String cargoLine1 = "";
String cargoLine2 = "";
String prevCargoLine1 = "";
String prevCargoLine2 = "";
unsigned long lastScrollTime = 0;
const unsigned long scrollInterval = 525;
int scrollIndex = 0;
String gameDay = "";
String gameHour = "";
String deliveryDay = "";
String deliveryHour = "";
String predictedKm = "";
String predictedTime = "";
String predictedArrival = "";
int predictedView = 0;
unsigned long lastPredictedSwitch = 0;
const unsigned long predictedSwitchInterval = 3000;
String restTime = "";
String prevRestTime = "";
String input = "";
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(buttonPin, INPUT_PULLUP);
lcd.createChar(0, truckIcon);
lcd.createChar(1, truckIcon2);
lcd.createChar(2, truckIcon3);
lcd.createChar(3, trailerIcon);
lcd.createChar(4, trailerIcon2);
lcd.createChar(5, trailerIcon3);
}
void loop() {
odbierzDaneZPython();
obsluzPrzycisk();
wyswietlStrone();
}
void odbierzDaneZPython() {
while (Serial.available()) {
char c = Serial.read();
if (c == '\n') {
if (input.startsWith("DAMAGE|")) {
int sep = input.indexOf('|', 7);
truckDamage = input.substring(7, sep).toInt();
trailerDamage = input.substring(sep + 1).toInt();
}
else if (input.startsWith("CARGO|")) {
int sep = input.indexOf('|', 6);
String newLine1 = input.substring(6, sep) + " ";
String newLine2 = input.substring(sep + 1) + " ";
if (newLine1 != prevCargoLine1 || newLine2 != prevCargoLine2) {
cargoLine1 = newLine1;
cargoLine2 = newLine2;
prevCargoLine1 = newLine1;
prevCargoLine2 = newLine2;
scrollIndex = 0;
}
}
else if (input.startsWith("TIME|")) {
int sep1 = input.indexOf('|', 5);
int sep2 = input.indexOf('|', sep1 + 1);
int sep3 = input.indexOf('|', sep2 + 1);
gameDay = input.substring(5, sep1);
gameHour = input.substring(sep1 + 1, sep2);
deliveryDay = input.substring(sep2 + 1, sep3);
deliveryHour = input.substring(sep3 + 1);
}
else if (input.startsWith("PREDICTED|")) {
int sep1 = input.indexOf('|', 10);
int sep2 = input.indexOf('|', sep1 + 1);
predictedKm = input.substring(10, sep1) + " km";
predictedTime = input.substring(sep1 + 1, sep2);
predictedArrival = input.substring(sep2 + 1);
}
else if (input.startsWith("REST|")) {
String newRest = input.substring(5);
if (newRest != prevRestTime) {
restTime = newRest;
prevRestTime = newRest;
}
}
input = "";
} else {
input += c;
}
}
}
void obsluzPrzycisk() {
static bool lastState = HIGH;
bool state = digitalRead(buttonPin);
if (lastState == HIGH && state == LOW) {
currentPage++;
if (currentPage >= totalPages) currentPage = 0;
lcd.clear();
}
lastState = state;
}
void wyswietlStrone() {
if (currentPage == 0) stronaUszkodzenia();
else if (currentPage == 1) stronaLadunek();
else if (currentPage == 2) stronaGodzina();
else if (currentPage == 3) stronaPrzewidywany();
else if (currentPage == 4) stronaOdpoczynek();
}
void stronaUszkodzenia() {
lcd.setCursor(3, 0); lcd.write(byte(0));
lcd.setCursor(4, 0); lcd.write(byte(1));
lcd.setCursor(5, 0); lcd.write(byte(2));
lcd.setCursor(10, 0); lcd.write(byte(3));
lcd.setCursor(11, 0); lcd.write(byte(4));
lcd.setCursor(12, 0); lcd.write(byte(5));
lcd.setCursor(3, 1); lcd.print(String(truckDamage) + "%");
lcd.setCursor(10, 1); lcd.print(String(trailerDamage) + "%");
}
void stronaLadunek() {
if (millis() - lastScrollTime >= scrollInterval) {
lastScrollTime = millis();
String toShow1 = cargoLine1.substring(scrollIndex) + cargoLine1.substring(0, scrollIndex);
String toShow2 = cargoLine2.substring(scrollIndex) + cargoLine2.substring(0, scrollIndex);
lcd.setCursor(0, 0); lcd.print(toShow1.substring(0, 16));
lcd.setCursor(0, 1); lcd.print(toShow2.substring(0, 16));
scrollIndex++;
if (scrollIndex >= cargoLine1.length()) scrollIndex = 0;
}
}
void stronaGodzina() {
lcd.setCursor((16 - (gameDay.length() + 1 + gameHour.length())) / 2, 0);
lcd.print(gameDay + " " + gameHour);
lcd.setCursor((16 - (deliveryDay.length() + 1 + deliveryHour.length())) / 2, 1);
lcd.print(deliveryDay + " " + deliveryHour);
}
void stronaPrzewidywany() {
if (millis() - lastPredictedSwitch >= predictedSwitchInterval) {
lastPredictedSwitch = millis();
predictedView = (predictedView + 1) % 3;
lcd.clear();
}
lcd.setCursor((16 - String("Przewidywany").length()) / 2, 0);
lcd.print("Przewidywany");
if (predictedView == 0) {
lcd.setCursor((16 - predictedKm.length()) / 2, 1);
lcd.print(predictedKm);
} else if (predictedView == 1) {
lcd.setCursor((16 - predictedTime.length()) / 2, 1);
lcd.print(predictedTime);
} else {
lcd.setCursor((16 - predictedArrival.length()) / 2, 1);
lcd.print(predictedArrival);
}
}
void stronaOdpoczynek() {
lcd.setCursor((16 - String("Odpoczynek za").length()) / 2, 0);
lcd.print("Odpoczynek za");
lcd.setCursor((16 - restTime.length()) / 2, 1);
lcd.print(restTime + " ");
}