#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include "RTClib.h"
#define DHTPIN 13 // กำหนดขา DHT22
#define DHTTYPE DHT22 // กำหนดชนิดของเซ็นเซอร์ DHT22
// กำหนดรีเลย์ที่ใช้ควบคุมอุปกรณ์
#define RELAY_FAN 12
#define RELAY_PUMP 14
#define RELAY_LAMP 27
// กำหนดขาสำหรับปุ่ม
#define BUTTON_PIN 26
// กำหนดที่อยู่ของ LCD 0x27 ขนาด 20x4
LiquidCrystal_I2C lcd(0x27, 20, 4);
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;
int displayMode = 0; // สถานะการแสดงผล (0 = แสดง temp/hum/date/time, 1 = แสดงสถานะ fan/pump/lamp)
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 200;
unsigned long lastLCDUpdate = 0; // เก็บเวลาที่จอ LCD ถูกอัปเดตครั้งล่าสุด
const long lcdInterval = 500; // เวลาหน่วงระหว่างการอัปเดตจอ LCD (0.5 วินาที)
void setup() {
// เริ่มต้นการเชื่อมต่อกับ LCD
lcd.init();
lcd.backlight(); // เปิดไฟ backlight
// เริ่มต้นเซ็นเซอร์ DHT22
dht.begin();
// เริ่มต้น RTC
if (!rtc.begin()) {
lcd.print("RTC Error");
while (1);
}
// กำหนดเวลาตอนเริ่มต้นหาก RTC ไม่ทำงาน
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // ตั้งค่าเวลาจากคอมพิวเตอร์
}
// กำหนดขารีเลย์และปุ่มเป็น OUTPUT/INPUT
pinMode(RELAY_FAN, OUTPUT);
pinMode(RELAY_PUMP, OUTPUT);
pinMode(RELAY_LAMP, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // ใช้ปุ่มแบบ pull-up เพื่อลดสัญญาณรบกวน
// เริ่มต้นการเชื่อมต่อ Serial Monitor
Serial.begin(115200);
}
void loop() {
// อ่านค่าจากปุ่ม
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW && millis() - lastDebounceTime > debounceDelay) {
displayMode = (displayMode + 1) % 2; // เปลี่ยนโหมดการแสดงผลระหว่าง 0 และ 1
lastDebounceTime = millis();
}
// อ่านค่าอุณหภูมิและความชื้นจาก DHT22
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
// อ่านวันที่และเวลาจาก RTC
DateTime now = rtc.now();
// ควบคุมรีเลย์ตามเงื่อนไขอุณหภูมิและความชื้น (active high)
bool fanState = (temperature > 30);
bool pumpState = (humidity < 80);
digitalWrite(RELAY_FAN, fanState ? HIGH : LOW); // เปิด/ปิดพัดลม
digitalWrite(RELAY_PUMP, pumpState ? HIGH : LOW); // เปิด/ปิดปั๊ม
digitalWrite(RELAY_LAMP, (now.hour() == 14 && now.minute() >= 16 && now.minute() <= 17) ? HIGH : LOW); // เปิด/ปิด lamp
// อัปเดตการแสดงผลบน LCD ตามช่วงเวลา lcdInterval (0.5 วินาที)
if (millis() - lastLCDUpdate > lcdInterval) {
lastLCDUpdate = millis();
lcd.clear();
if (displayMode == 0) {
// แสดงผลอุณหภูมิ ความชื้น วันที่ และเวลา
lcd.setCursor(0, 0); // แสดงผลที่แถวที่ 1
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1); // แสดงผลที่แถวที่ 2
lcd.print("Hum: ");
lcd.print(humidity);
lcd.print(" %");
lcd.setCursor(0, 2); // แสดงผลที่แถวที่ 3
lcd.print("Date: ");
lcd.print(now.day(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.year(), DEC);
lcd.setCursor(0, 3); // แสดงผลที่แถวที่ 4
lcd.print("Time: ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
} else if (displayMode == 1) {
// แสดงสถานะของ fan, pump, และ lamp
lcd.setCursor(0, 0); // แสดงผลที่แถวที่ 1
lcd.print("Fan: ");
lcd.print(fanState ? "ON" : "OFF");
lcd.setCursor(0, 1); // แสดงผลที่แถวที่ 2
lcd.print("Pump: ");
lcd.print(pumpState ? "ON" : "OFF");
lcd.setCursor(0, 2); // แสดงผลที่แถวที่ 3
lcd.print("Lamp: ");
lcd.print(digitalRead(RELAY_LAMP) == HIGH ? "ON" : "OFF");
}
}
}