#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;
float numberChargingPower = 0; // เปลี่ยนเป็น float เพื่อรองรับทศนิยม
bool newDigit = false;
int okCount = 0;
int batteryPercentage = 97;
float chargingPower = 0;
float chargingTime = 0;
void setup() {
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);
displayNumber();
}
void loop() {
handleNumberControl();
if (digitalRead(cancelButtonPin) == LOW) {
digitalWrite(AC , HIGH);
lcd.backlight();
}
if (okCount == 4) {
chargingPower = numberChargingPower; // กำหนดค่า batteryPercentage จากตัวเลขที่เลือก
//number = chargingPower;
calculateChargingTime();
countDownTimer();
}
}
void handleNumberControl() {
static unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 200;
if (digitalRead(upButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
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();
displayNumber();
}
if (digitalRead(downButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
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();
displayNumber();
}
if (digitalRead(okButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
okCount++;
if (numberChargingPower > 120.0) numberChargingPower = 120.0;
switch (okCount) {
case 1:
newDigit = true;
numberChargingPower *= 10;
displayNumber();
break;
case 2:
newDigit = true;
numberChargingPower *= 10;
displayNumber();
break;
case 3:
// เพิ่มทศนิยม .0
numberChargingPower = (float)numberChargingPower; // แปลงเป็น float
displayNumber();
break;
}
}
if (digitalRead(cancelButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (okCount > 0) {
if (okCount == 3) {
// ลบหลักทศนิยม
numberChargingPower = (int)numberChargingPower; // ตัดทศนิยมออก
okCount--; // กลับไปสถานะก่อนเพิ่มทศนิยม
} else {
// ลบเลขหลักสุดท้าย
numberChargingPower = (int)(numberChargingPower / 10); // หาร 10 เพื่อลบหลักสุดท้าย
okCount--; // ลดจำนวนหลักที่ตั้งค่า
}
} else {
// รีเซ็ตค่าทั้งหมดเมื่อเหลือ 0 หลัก
numberChargingPower = 0.0;
okCount = 0;
}
newDigit = false;
displayNumber();
}
}
void displayNumber() {
lcd.setCursor(0, 0);
lcd.print("Power: ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
if (okCount < 3) {
lcd.print((int)numberChargingPower);
} else {
lcd.print(numberChargingPower, 1); // แสดงผล 1 ตำแหน่งทศนิยม
}
lcd.print("W"); // เพิ่ม "W" เพื่อแสดง Watt หลังตัวเลข
}
void calculateChargingTime() {
if (chargingPower > 120.0) chargingPower = 120.0;
float remainingPercentage = 98 - batteryPercentage;
float energyToCharge = 19.0 * remainingPercentage / 100.0;
chargingTime = energyToCharge / chargingPower;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Charging time:");
digitalWrite(AC, HIGH);
if (chargingTime >= 1) {
int hours = (int)chargingTime;
int minutes = (int)((chargingTime - hours) * 60);
int seconds = (int)((chargingTime - 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 (chargingTime < 1 && chargingTime >= (1.0 / 60)) {
int minutes = (int)(chargingTime * 60);
int seconds = (int)((chargingTime * 3600) - minutes * 60);
lcd.setCursor(0, 1);
lcd.print(minutes);
lcd.print("min ");
lcd.print(seconds);
lcd.print("sec");
} else {
int seconds = (int)(chargingTime * 3600);
lcd.setCursor(0, 1);
lcd.print(seconds);
lcd.print("sec");
}
delay(3000);
lcd.clear();
}
void countDownTimer() {
lcd.setCursor(0, 0);
lcd.print("Finished in:");
lcd.noBacklight(); // เริ่มต้นด้วยการปิดไฟแบ็คไลท์
unsigned long startTime = millis();
int buttonStateOK = 0; // ใช้ตัวแปรเพื่อเก็บสถานะการกดปุ่ม OK
unsigned long lastOkPressTime = 0; // ตัวแปรเพื่อเก็บเวลาการกดปุ่ม OK ล่าสุด
while (true) {
long remainingTime = (chargingTime * 3600000) - (millis() - startTime);
// อ่านสถานะปุ่ม OK
if (digitalRead(okButtonPin) == LOW) {
delay(2);
buttonStateOK = 1; // ปุ่ม OK กด
} else {
buttonStateOK = 0; // ปุ่ม OK ไม่กด
}
// อ่านสถานะปุ่ม Cancel
if (digitalRead(cancelButtonPin) == LOW) {
delay(2);
lcd.clear();
lcd.print("Cancelled!");
digitalWrite(AC, HIGH);
lcd.backlight();
numberChargingPower = 0;
okCount = 0;
chargingPower = 0;
chargingTime = 0;
delay(1000);
lcd.clear();
newDigit = false;
displayNumber();
return; // ออกจากฟังก์ชันเมื่อกด Cancel
}
// ใช้ switch สำหรับปุ่ม OK
switch (buttonStateOK) {
case 1:
if (millis() - lastOkPressTime > 200) { // ตรวจสอบการกดใหม่ๆ
lastOkPressTime = millis();
lcd.backlight(); // เปิดไฟแบ็คไลท์เมื่อกด OK
}
break;
default:
if (millis() - lastOkPressTime >= 2000) { // ปิดไฟหลัง 2 วินาที
lcd.noBacklight();
}
break;
}
// ใช้ switch สำหรับตรวจสอบ remainingTime <= 0
switch (remainingTime <= 0) {
case true:
lcd.clear();
lcd.print("Finished!");
digitalWrite(AC, LOW);
numberChargingPower = 0;
okCount = 0;
chargingPower = 0;
chargingTime = 0;
delay(1000);
lcd.clear();
newDigit = 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);
delay(1000);
}
}