#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ตั้งรีเลย์ 16 ตัว
const int relayPins[16] = {
30, 31, 32, 33, 34, 35, 36, 37, // Zone 1: Relay 1–8
38, 39, 40, 41, 42, 43, 44, 45 // Zone 2: Relay 9–16
};
// ปุ่ม Zone 1
#define BUTTON_ON_1 22
#define BUTTON_OFF_1 23 // ใช้ NC
// ปุ่ม Zone 2
#define BUTTON_ON_2 24
#define BUTTON_OFF_2 25 // ใช้ NC
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool relayOnZone1 = false;
bool relayOnZone2 = false;
bool lastBtnOn1 = HIGH;
bool lastBtnOff1 = LOW; // สำหรับปุ่ม NC
bool lastBtnOn2 = HIGH;
bool lastBtnOff2 = LOW; // สำหรับปุ่ม NC
unsigned long startTime1 = 0;
unsigned long startTime2 = 0;
const unsigned long duration = 3600000; // 60 นาที
unsigned long lastDisplayTime = 0;
void setup() {
for (int i = 0; i < 16; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], HIGH); // ปิดทั้งหมด
}
pinMode(BUTTON_ON_1, INPUT_PULLUP);
pinMode(BUTTON_OFF_1, INPUT_PULLUP);
pinMode(BUTTON_ON_2, INPUT_PULLUP);
pinMode(BUTTON_OFF_2, INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Zone 1: OFF ");
lcd.setCursor(0, 1);
lcd.print("Zone 2: OFF ");
Serial.begin(9600);
}
void loop() {
bool btnOn1 = digitalRead(BUTTON_ON_1);
bool btnOff1 = digitalRead(BUTTON_OFF_1);
bool btnOn2 = digitalRead(BUTTON_ON_2);
bool btnOff2 = digitalRead(BUTTON_OFF_2);
// Zone 1 ON (NO)
if (lastBtnOn1 == HIGH && btnOn1 == LOW) {
startTime1 = millis();
for (int i = 0; i < 8; i++) {
digitalWrite(relayPins[i], HIGH);
}
relayOnZone1 = true;
Serial.println("✅ Zone 1 ON");
lcd.setCursor(0, 0);
lcd.print("Zone 1: ON ");
delay(200);
}
// Zone 1 OFF (NC)
if (lastBtnOff1 == LOW && btnOff1 == HIGH) {
for (int i = 0; i < 8; i++) {
digitalWrite(relayPins[i], LOW);
}
relayOnZone1 = false;
Serial.println("🛑 Zone 1 OFF");
lcd.setCursor(0, 0);
lcd.print("Zone 1: OFF ");
delay(200);
}
// Zone 2 ON (NO)
if (lastBtnOn2 == HIGH && btnOn2 == LOW) {
startTime2 = millis();
for (int i = 8; i < 16; i++) {
digitalWrite(relayPins[i], HIGH);
}
relayOnZone2 = true;
Serial.println("✅ Zone 2 ON");
lcd.setCursor(0, 1);
lcd.print("Zone 2: ON ");
delay(200);
}
// Zone 2 OFF (NC)
if (lastBtnOff2 == LOW && btnOff2 == HIGH) {
for (int i = 8; i < 16; i++) {
digitalWrite(relayPins[i], LOW);
}
relayOnZone2 = false;
Serial.println("🛑 Zone 2 OFF");
lcd.setCursor(0, 1);
lcd.print("Zone 2: OFF ");
delay(200);
}
lastBtnOn1 = btnOn1;
lastBtnOff1 = btnOff1;
lastBtnOn2 = btnOn2;
lastBtnOff2 = btnOff2;
// แสดงเวลาคงเหลือ
if (millis() - lastDisplayTime >= 1000) {
lastDisplayTime = millis();
if (relayOnZone1) {
unsigned long rem = duration - (millis() - startTime1);
unsigned int m = rem / 60000;
unsigned int s = (rem % 60000) / 1000;
lcd.setCursor(11, 0);
if (m < 10) lcd.print("0"); lcd.print(m); lcd.print(":");
if (s < 10) lcd.print("0"); lcd.print(s);
}
if (relayOnZone2) {
unsigned long rem = duration - (millis() - startTime2);
unsigned int m = rem / 60000;
unsigned int s = (rem % 60000) / 1000;
lcd.setCursor(11, 1);
if (m < 10) lcd.print("0"); lcd.print(m); lcd.print(":");
if (s < 10) lcd.print("0"); lcd.print(s);
}
}
// Timeout Zone 1
if (relayOnZone1 && millis() - startTime1 >= duration) {
for (int i = 0; i < 8; i++) {
digitalWrite(relayPins[i], LOW);
}
relayOnZone1 = false;
lcd.setCursor(0, 0);
lcd.print("Zone 1: OFF ");
Serial.println("⏱️ Zone 1 OFF (Timeout)");
}
// Timeout Zone 2
if (relayOnZone2 && millis() - startTime2 >= duration) {
for (int i = 8; i < 16; i++) {
digitalWrite(relayPins[i], LOW);
}
relayOnZone2 = false;
lcd.setCursor(0, 1);
lcd.print("Zone 2: OFF ");
Serial.println("⏱️ Zone 2 OFF (Timeout)");
}
}