#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int upButtonPin = 10;
const int okButtonPin = 11;
const int downButtonPin = 9;
const int cancelButtonPin = 8;
const int AC = 7;
int batteryPercentage = 0;
float chargingPower = 0;
float chargingTime = 0;
float numberchargingTime = 0;
int numberBatteryPercentage = 0;
float numberChargingPower = 0;
int cancelCount = 0;
int okCount = 0;
bool buttonPressed = false;
bool conditionUsed = false;
bool newDigit = false;
bool isLedOn = false;
int delayButtonClick = 200;
int deleteLetters = 2000;
int On_Off_LCD = 2000;
void setup() {
lcd.init();
lcd.begin(16, 2);
lcd.backlight();
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(okButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
pinMode(cancelButtonPin, INPUT_PULLUP);
pinMode(AC, OUTPUT);
digitalWrite(AC, HIGH);
conditionUsed = true;
isLedOn = true;
displayNumber();
}
void loop() {
if (okCount == 0) {
if (numberChargingPower == 0 && !buttonPressed) {
if (digitalRead(cancelButtonPin) == LOW && !buttonPressed) {
delay(delayButtonClick);
switch (cancelCount) {
case 0:
buttonPressed = false;
lcd.noBacklight();
cancelCount = 1;
break;
case 1:
buttonPressed = false;
lcd.backlight();
cancelCount = 0;
break;
default:
cancelCount = 0;
break;
}
}
}
if (!conditionUsed) {
if (digitalRead(cancelButtonPin) == LOW && !conditionUsed) {
delay(delayButtonClick);
switch (cancelCount) {
case 0:
digitalWrite(AC, HIGH);
cancelCount = 1;
isLedOn = true;
break;
case 1:
lcd.backlight();
conditionUsed = true;
buttonPressed = false;
cancelCount = 0;
break;
}
}
}
}
handleOkPress();
handleNumberControl();
if (okCount == 6) {
//displayNumber();
handleNumberControl();
chargingPower = numberChargingPower;
batteryPercentage = numberBatteryPercentage;
calculateChargingTime();
countDownTimer();
}
}
void handleOkPress() {
if (digitalRead(okButtonPin) == LOW) {
delay(delayButtonClick);
okCount++;
if (!isLedOn) {
conditionUsed = true;
if (digitalRead(AC) == LOW) {
digitalWrite(AC, HIGH);
isLedOn = true;
}
}
switch (okCount) {
case 1:
newDigit = true;
if (numberChargingPower == 0) {
numberChargingPower = 0;
} else {
numberChargingPower *= 10;
}
lcd.backlight();
displayNumber();
break;
case 2:
newDigit = true;
if (numberChargingPower == 0) {
numberChargingPower = 0;
} else {
numberChargingPower *= 10;
}
displayNumber();
break;
case 3:
if (numberChargingPower > 120.0) {
numberChargingPower = 120.0;
}
numberChargingPower = (float)numberChargingPower;
displayNumber();
break;
case 4:
newDigit = false;
numberBatteryPercentage = 0;
displayNumber();
break;
case 5:
newDigit = true;
numberBatteryPercentage *= 10;
displayNumber();
break;
}
}
}
void handleNumberControl() {
static unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = delayButtonClick;
// If charging power is greater than 0, show the display and set cancelCount to 1
if (numberChargingPower > 0) {
lcd.backlight();
cancelCount = 1;
}
if (okCount < 4) {
// Handle the up button press
if (digitalRead(upButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (!isLedOn) {
buttonPressed = false;
buttonPressed = 0;
conditionUsed = true;
if (digitalRead(AC) == LOW) {
digitalWrite(AC, HIGH);
isLedOn = true;
}
}
if (okCount == 3) {
float decimalPart = numberChargingPower - (int)numberChargingPower;
if (decimalPart < 0.9) {
numberChargingPower += 0.1;
} else {
numberChargingPower -= 0.9;
}
} else {
if (newDigit) {
if ((int)numberChargingPower % 10 < 9) {
numberChargingPower++;
} else {
numberChargingPower -= 9;
}
} else {
if ((int)numberChargingPower < 9) {
numberChargingPower++;
} else {
numberChargingPower = 0;
}
}
}
if (numberChargingPower > 120.0) numberChargingPower = 120.0;
displayNumber();
}
// Handle the down button press
if (digitalRead(downButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (!isLedOn) {
buttonPressed = false;
buttonPressed = 0;
conditionUsed = true;
if (digitalRead(AC) == LOW) {
digitalWrite(AC, HIGH);
isLedOn = true;
} else {
isLedOn = true;
}
}
if (okCount == 3) {
float decimalPart = numberChargingPower - (int)numberChargingPower;
if (decimalPart > 0.0) {
numberChargingPower -= 0.1;
} else {
numberChargingPower += 0.9;
}
} else {
if (newDigit) {
if ((int)numberChargingPower % 10 > 0) {
numberChargingPower--;
} else {
numberChargingPower += 9;
}
} else {
if ((int)numberChargingPower > 0) {
numberChargingPower--;
} else {
numberChargingPower = 9;
}
}
}
if (numberChargingPower > 120.0) numberChargingPower = 120.0;
displayNumber();
}
// Handle the cancel button press
if (digitalRead(cancelButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (okCount > 0) {
if (okCount == 3) {
numberChargingPower = (int)numberChargingPower;
okCount--;
} else {
numberChargingPower = (int)(numberChargingPower / 10);
okCount--;
}
} else {
numberChargingPower = 0.0;
okCount = 0;
}
newDigit = false;
displayNumber();
}
}
// Handle control when okCount is greater than 3
if (okCount > 3) {
// Handle the up button press for battery percentage
if (digitalRead(upButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (newDigit) {
if (numberBatteryPercentage % 10 < 9) {
numberBatteryPercentage++;
} else {
numberBatteryPercentage -= 9;
}
} else {
if (numberBatteryPercentage < 9) {
numberBatteryPercentage++;
} else {
numberBatteryPercentage = 0;
}
}
displayNumber();
}
// Handle the down button press for battery percentage
if (digitalRead(downButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (newDigit) {
if (numberBatteryPercentage % 10 > 0) {
numberBatteryPercentage--;
} else {
numberBatteryPercentage += 9;
}
} else {
if (numberBatteryPercentage > 0) {
numberBatteryPercentage--;
} else {
numberBatteryPercentage = 9;
}
}
displayNumber();
}
// Handle the cancel button press for battery percentage
if (digitalRead(cancelButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (okCount > 0) {
if (okCount == 3) {
numberBatteryPercentage = numberBatteryPercentage;
okCount--;
} else {
numberBatteryPercentage = numberBatteryPercentage / 10;
okCount--;
}
} else {
numberBatteryPercentage = 0;
okCount = 0;
}
newDigit = false;
displayNumber();
}
}
}
void displayNumber() {
if (okCount < 4) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Power: ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
char buffer[8]; // ใช้เก็บค่าที่จัดรูปแบบ
if (okCount == 1) {
// แสดงตัวเลข 2 หลัก เช่น "01", "05"
sprintf(buffer, "%02d", (int)numberChargingPower);
} else if (okCount == 2) {
// แสดงตัวเลข 3 หลัก เช่น "001", "105"
sprintf(buffer, "%03d", (int)numberChargingPower);
} else if (okCount == 3) {
// แสดงตัวเลขแบบ 3 หลัก + ทศนิยม เช่น "001.0"
sprintf(buffer, "%03d.%01d", (int)numberChargingPower, (int)((numberChargingPower - (int)numberChargingPower) * 10));
} else {
// แสดงตัวเลขปกติ (ไม่มีศูนย์นำหน้า)
sprintf(buffer, "%d", (int)numberChargingPower);
}
lcd.print(buffer); // แสดงผลตามรูปแบบที่กำหนด
lcd.print("W"); // เพิ่ม "W" เพื่อแสดง Watt หลังตัวเลข
}
if (okCount > 3) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Battery: ");
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.setCursor(9, 0);
if (numberBatteryPercentage < 10 && newDigit) {
lcd.print("0");
}
lcd.print(numberBatteryPercentage);
lcd.print("%"); // เพิ่มเครื่องหมาย % หลังตัวเลข
}
}
void calculateChargingTime() {
if (chargingPower > 120.0) chargingPower = 120.0;
float remainingPercentage = 100 - batteryPercentage;
float energyToCharge = 19.0 * remainingPercentage / 100.0;
numberchargingTime = energyToCharge / chargingPower;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Charging time:");
digitalWrite(AC, HIGH);
if (numberchargingTime>= 1) {
int hours = (int)numberchargingTime;
int minutes = (int)((numberchargingTime - hours) * 60);
int seconds = (int)((numberchargingTime - hours) * 3600 - minutes * 60);
lcd.setCursor(0, 1);
lcd.print(hours);
lcd.print("Hr ");
lcd.print(minutes);
lcd.print("min ");
lcd.print(seconds);
lcd.print("sec");
} else if (numberchargingTime < 1 && numberchargingTime >= (1.0 / 60)) {
int minutes = (int)(numberchargingTime * 60);
int seconds = (int)((numberchargingTime * 3600) - minutes * 60);
lcd.setCursor(0, 1);
lcd.print(minutes);
lcd.print("min ");
lcd.print(seconds);
lcd.print("sec");
} else {
int seconds = (int)(numberchargingTime * 3600);
lcd.setCursor(0, 1);
lcd.print(seconds);
lcd.print("sec");
}
delay(3000);
chargingTime = numberchargingTime;
lcd.clear();
}
void countDownTimer() {
lcd.setCursor(0, 0);
lcd.print("Finished in:");
lcd.noBacklight();
unsigned long startTime = millis();
int buttonStateOK = 0;
unsigned long lastOkPressTime = 0;
while (true) {
long remainingTime = (chargingTime * 3600000) - (millis() - startTime);
if (digitalRead(okButtonPin) == LOW) {
buttonStateOK = 1;
} else {
buttonStateOK = 0;
}
if (digitalRead(cancelButtonPin) == LOW) {
lcd.clear();
lcd.backlight();
lcd.print("Cancelled!");
digitalWrite(AC, HIGH);
numberChargingPower = 0;
numberBatteryPercentage = 0;
okCount = 0;
chargingPower = 0;
chargingTime = 0;
cancelCount = 0;
delay(1000);
lcd.clear();
buttonPressed = false;
conditionUsed = true;
newDigit = false;
displayNumber();
return;
}
switch (buttonStateOK) {
case 1:
if (millis() - lastOkPressTime) {
lastOkPressTime = millis();
lcd.backlight();
}
break;
default:
if (millis() - lastOkPressTime >= On_Off_LCD) {
lcd.noBacklight();
}
break;
}
switch (remainingTime <= 0) {
case true:
lcd.clear();
lcd.print("Finished!");
digitalWrite(AC, LOW);
numberChargingPower = 0;
numberBatteryPercentage = 0;
okCount = 0;
chargingPower = 0;
chargingTime = 0;
cancelCount = 0;
delay(deleteLetters);
lcd.noBacklight();
isLedOn = false;
newDigit = false;
buttonPressed = true;
conditionUsed = false;
displayNumber();
return;
case false:
break;
}
int hours = remainingTime / 3600000;
int minutes = (remainingTime % 3600000) / 60000;
int seconds = ((remainingTime % 3600000) % 60000) / 1000;
lcd.setCursor(0, 1);
char buffer[9];
sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
lcd.print(buffer);
}
}