#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// กำหนดพินสำหรับ DHT22 และการเชื่อมต่อ
#define DHTPIN_WT 18 // พินสำหรับเซ็นเซอร์อุณหภูมิน้ำ
#define DHTPIN_AT 19 // พินสำหรับเซ็นเซอร์อุณหภูมิอากาศ
#define DHTTYPE DHT22
DHT dhtWT(DHTPIN_WT, DHTTYPE);
DHT dhtAT(DHTPIN_AT, DHTTYPE);
// กำหนดพิน LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// กำหนดพินสำหรับปุ่มกดและรีเลย์
#define BUTTON_MODE 32
#define BUTTON_UP 33
#define BUTTON_DOWN 34
#define RELAY_PUMP 23
#define RELAY_COOLING 25
#define RELAY_FAN 26
#define RELAY_SPRINGER 27 // พินสำหรับควบคุม Springer (วาล์วมอเตอร์ 12VDC)
// ค่าตั้งต้น
float setWT = 28.0; // ตั้งอุณหภูมิน้ำเริ่มต้นที่ 28°C
float setAT = 28.0; // ตั้งอุณหภูมิอากาศเริ่มต้นที่ 28°C
int mode = 0; // โหมดเริ่มต้นเป็นหน้าจอแรก
// ตัวแปรเพื่อเก็บสถานะปุ่มก่อนหน้า
int lastButtonUpState = HIGH;
int lastButtonDownState = HIGH;
unsigned long lastPressTime = 0; // เก็บเวลาการกดปุ่มครั้งสุดท้าย
unsigned long debounceDelay = 50; // หน่วงเวลาเพื่อลดการเด้งของสัญญาณ
void setup() {
pinMode(RELAY_PUMP, OUTPUT);
pinMode(RELAY_COOLING, OUTPUT);
pinMode(RELAY_FAN, OUTPUT);
pinMode(RELAY_SPRINGER, OUTPUT); // กำหนดพินสำหรับ Springer
pinMode(BUTTON_MODE, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
digitalWrite(RELAY_PUMP, HIGH); // เปิดปั๊มน้ำเริ่มต้น
digitalWrite(RELAY_COOLING, LOW); // ปิดระบบทำความเย็นเริ่มต้น
digitalWrite(RELAY_FAN, LOW); // ปิดพัดลมเริ่มต้น
digitalWrite(RELAY_SPRINGER, LOW); // ปิด Springer เริ่มต้น
dhtWT.begin();
dhtAT.begin();
lcd.init();
lcd.backlight();
}
void loop() {
float actWT = dhtWT.readTemperature();
float actAT = dhtAT.readTemperature();
if (isnan(actWT) || isnan(actAT)) {
lcd.clear();
lcd.print("Error: DHT Fail");
return;
}
switchMode();
controlSystems(actWT, actAT);
displayStatus(actWT, actAT);
delay(1000); // รอ 1 วินาที
}
void switchMode() {
if (digitalRead(BUTTON_MODE) == LOW) {
delay(debounceDelay); // เพิ่มการหน่วงเวลาเพื่อลดการเด้งของสัญญาณ
if (digitalRead(BUTTON_MODE) == LOW) { // ตรวจสอบอีกครั้งว่าปุ่มยังถูกกดอยู่
mode++;
if (mode > 3) mode = 0; // สลับโหมดวนไปตั้งแต่ 0 ถึง 3
delay(300); // หน่วงเวลาเพื่อป้องกันการสลับโหมดหลายครั้งเกินไป
}
}
}
void controlSystems(float actWT, float actAT) {
if (actWT > setWT) {
digitalWrite(RELAY_COOLING, HIGH); // เปิดระบบทำความเย็น
} else {
digitalWrite(RELAY_COOLING, LOW); // ปิดระบบทำความเย็น
}
if (actAT > setAT) {
digitalWrite(RELAY_FAN, HIGH); // เปิดพัดลม
digitalWrite(RELAY_SPRINGER, HIGH); // เปิด Springer
} else {
digitalWrite(RELAY_FAN, LOW); // ปิดพัดลม
digitalWrite(RELAY_SPRINGER, LOW); // ปิด Springer
}
}
void displayStatus(float actWT, float actAT) {
lcd.clear();
if (mode == 0) {
// แสดงสถานะหน้าจอเริ่มต้น
lcd.setCursor(0, 0);
lcd.print("P: ON C: ");
lcd.print(digitalRead(RELAY_COOLING) == HIGH ? "ON" : "OFF");
lcd.setCursor(0, 1);
lcd.print("F: ");
lcd.print(digitalRead(RELAY_FAN) == HIGH ? "ON" : "OFF");
lcd.print(" S: ");
lcd.print(digitalRead(RELAY_SPRINGER) == HIGH ? "ON" : "OFF");
} else if (mode == 1) {
// แสดงค่า Act WT และ Act AT
lcd.setCursor(0, 0);
lcd.print("Act WT: ");
lcd.print(actWT);
lcd.setCursor(0, 1);
lcd.print("Act AT: ");
lcd.print(actAT);
} else if (mode == 2) {
// แสดงค่า Act AT และ Set AT
lcd.setCursor(0, 0);
lcd.print("Act AT: ");
lcd.print(actAT);
lcd.setCursor(0, 1);
lcd.print("Set AT: ");
lcd.print(setAT);
adjustTemperature(&setAT);
} else if (mode == 3) {
// แสดงค่า Act WT และ Set WT
lcd.setCursor(0, 0);
lcd.print("Act WT: ");
lcd.print(actWT);
lcd.setCursor(0, 1);
lcd.print("Set WT: ");
lcd.print(setWT);
adjustTemperature(&setWT);
}
}
void adjustTemperature(float *setTemp) {
int currentButtonUpState = digitalRead(BUTTON_UP);
int currentButtonDownState = digitalRead(BUTTON_DOWN);
unsigned long currentTime = millis();
// ป้องกันการลดอุณหภูมิเองโดยไม่ตั้งใจ
if (currentButtonDownState == LOW && lastButtonDownState == HIGH) {
delay(debounceDelay); // หน่วงเวลาเพื่อลดการเด้งของสัญญาณ
if (digitalRead(BUTTON_DOWN) == LOW) { // ตรวจสอบอีกครั้งว่าปุ่มยังถูกกดอยู่
*setTemp -= 0.5; // ลดค่า Set ทีละ 0.5°C
lastPressTime = currentTime;
delay(300); // หน่วงเวลาเพื่อป้องกันการกดปุ่มหลายครั้งเกินไป
}
} else if (currentButtonDownState == LOW && currentTime - lastPressTime > 500) {
*setTemp -= 0.5;
lastPressTime = currentTime;
}
if (currentButtonUpState == LOW && lastButtonUpState == HIGH) {
delay(debounceDelay); // หน่วงเวลาเพื่อลดการเด้งของสัญญาณ
if (digitalRead(BUTTON_UP) == LOW) { // ตรวจสอบอีกครั้งว่าปุ่มยังถูกกดอยู่
*setTemp += 0.5; // เพิ่มค่า Set ทีละ 0.5°C
lastPressTime = currentTime;
delay(300); // หน่วงเวลาเพื่อป้องกันการกดปุ่มหลายครั้งเกินไป
}
} else if (currentButtonUpState == LOW && currentTime - lastPressTime > 500) {
*setTemp += 0.5;
lastPressTime = currentTime;
}
// อัปเดตสถานะปุ่มสุดท้าย
lastButtonUpState = currentButtonUpState;
lastButtonDownState = currentButtonDownState;
}