#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <DHT.h>
#include <NewPing.h>
// --- Configuration ---
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;
#define DHTPIN 19
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define TRIGGER_PIN 5
#define ECHO_PIN 4
#define MAX_DISTANCE 400
#define ITERATIONS 7
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
const int relay1 = 12; // FAN (Temp Control)
const int relay2 = 13; // PUMP (Humid Control)
const int relay3 = 14; // DISTANCE CONTROL (New!)
// --- Timer Variables ---
unsigned long lastSensorRead = 0;
const unsigned long interval = 1000;
// --- Global Status Variables ---
float t = 0, h = 0;
int distance = 0;
bool r1_status = false;
bool r2_status = false;
bool r3_status = false;
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
rtc.begin();
dht.begin();
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
lcd.clear();
}
void loop() {
unsigned long currentMillis = millis();
// --- 1. อ่านค่าจาก Sensor ทุกๆ 1 วินาที ---
if (currentMillis - lastSensorRead >= interval) {
lastSensorRead = currentMillis;
// อ่านค่า DHT22
float newT = dht.readTemperature();
float newH = dht.readHumidity();
if (!isnan(newT)) t = newT;
if (!isnan(newH)) h = newH;
// อ่านค่าระยะทาง
unsigned int uS = sonar.ping_median(ITERATIONS);
distance = sonar.convert_cm(uS);
if (distance == 0 && uS == 0) distance = MAX_DISTANCE;
// --- 2. Hysteresis Logic ---
// R1: พัดลม (Temp >= 30.0 ON / <= 29.5 OFF)
if (t >= 30.0) r1_status = true;
else if (t <= 29.5) r1_status = false;
// R2: ปั๊ม (Humid <= 50.0 ON / >= 52.0 OFF)
if (h <= 50.0) r2_status = true;
else if (h >= 52.0) r2_status = false;
// R3: ระยะทาง (Distance <= 30 ON / >= 35 OFF)
if (distance <= 30 && distance != 0) r3_status = true;
else if (distance >= 35) r3_status = false;
// สั่งงาน Relay
digitalWrite(relay1, r1_status ? HIGH : LOW);
digitalWrite(relay2, r2_status ? HIGH : LOW);
digitalWrite(relay3, r3_status ? HIGH : LOW);
}
// --- 3. อัปเดตจอ LCD ---
updateLCD();
}
void updateLCD() {
DateTime now = rtc.now();
char lineBuffer[21];
// บรรทัดที่ 1: วันที่และเวลา
lcd.setCursor(0, 0);
snprintf(lineBuffer, sizeof(lineBuffer), "%02d/%02d/%04d %02d:%02d:%02d",
now.day(), now.month(), now.year(),
now.hour(), now.minute(), now.second());
lcd.print(lineBuffer);
// บรรทัดที่ 2: ระยะทาง
lcd.setCursor(0, 1);
snprintf(lineBuffer, sizeof(lineBuffer), "Distance: %3d cm ", distance);
lcd.print(lineBuffer);
// บรรทัดที่ 3: อุณหภูมิและความชื้น
lcd.setCursor(0, 2);
char tStr[6], hStr[6];
dtostrf(t, 4, 1, tStr);
dtostrf(h, 4, 1, hStr);
snprintf(lineBuffer, sizeof(lineBuffer), "T:%sC H:%s%% ", tStr, hStr);
lcd.print(lineBuffer);
// บรรทัดที่ 4: สถานะ Relay ทั้ง 3 ตัว
lcd.setCursor(0, 3);
// ใช้ตัวย่อเพื่อให้พอดีกับ 20 ช่อง: R1, R2, R3
snprintf(lineBuffer, sizeof(lineBuffer), "R1:%s R2:%s R3:%s ",
(r1_status ? "ON " : "OFF"),
(r2_status ? "ON " : "OFF"),
(r3_status ? "ON " : "OFF"));
lcd.print(lineBuffer);
}PUMP
FAN
PIN13
PIN12
+5V
GDN
TRIG Pin5
ECHO Pin4
SDA Pin21
SCL Pin22
DHT Pin19
MOTOR
PIN14