#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ================== CẤU HÌNH CHÂN ==================
#define DHTPIN 13
#define DHTTYPE DHT22
#define SDA_PIN 12
#define SCL_PIN 14
#define PIR_PIN 27
#define DUST_PIN 36
#define LED_PIR 0
#define LED_HEATER 25
#define LED_FAN 33
#define LED_AC 32
#define LED_HUMIDIFIER 26
#define RGB_RED 15
#define RGB_GREEN 2
#define RGB_BLUE 4
#define SW_MODE 35
#define BTN_AC 19
#define BTN_FAN 23
#define BTN_HEATER 22
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
float tempRoom = 0;
float humidity = 0;
bool heaterOn = false;
bool acOn = false;
bool humidifierOn = false;
int fanLevel = 0; // 0, 1, 2, 3
bool lastAutoMode = true;
int dustLevel = 0;
String dustStatus = "";
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
dht.begin();
lcd.init();
lcd.backlight();
pinMode(PIR_PIN, INPUT);
pinMode(DUST_PIN, INPUT);
pinMode(SW_MODE, INPUT);
pinMode(BTN_AC, INPUT_PULLUP);
pinMode(BTN_FAN, INPUT_PULLUP);
pinMode(BTN_HEATER, INPUT_PULLUP);
pinMode(LED_PIR, OUTPUT);
pinMode(LED_HEATER, OUTPUT);
pinMode(LED_FAN, OUTPUT);
pinMode(LED_AC, OUTPUT);
pinMode(LED_HUMIDIFIER, OUTPUT);
pinMode(RGB_RED, OUTPUT);
pinMode(RGB_GREEN, OUTPUT);
pinMode(RGB_BLUE, OUTPUT);
lcd.setCursor(0, 0);
lcd.print("HE THONG SMART");
lcd.setCursor(0, 1);
lcd.print("HOME READY");
delay(2000);
lcd.clear();
tempRoom = dht.readTemperature();
humidity = dht.readHumidity();
Serial.println("Log: He thong khoi dong thanh cong.");
}
void loop() {
handleDustSensor();
handlePIRLight();
handleSmartHome();
}
void handleDustSensor() {
dustLevel = analogRead(DUST_PIN);
if (dustLevel < 1800) {
dustStatus = "TOT";
digitalWrite(RGB_RED, HIGH);
digitalWrite(RGB_GREEN, HIGH);
digitalWrite(RGB_BLUE, HIGH);
Serial.print("Bui: TOT - TRANG (");
}
else if (dustLevel < 2000) {
dustStatus = "TB";
digitalWrite(RGB_RED, LOW);
digitalWrite(RGB_GREEN, HIGH);
digitalWrite(RGB_BLUE, LOW);
Serial.print("Bui: TRUNG BINH - XANH LA (");
}
else if (dustLevel < 2100) {
dustStatus = "KEM";
digitalWrite(RGB_RED, HIGH);
digitalWrite(RGB_GREEN, HIGH);
digitalWrite(RGB_BLUE, LOW);
Serial.print("Bui: KEM - VANG (");
}
else {
dustStatus = "XAU";
digitalWrite(RGB_RED, HIGH);
digitalWrite(RGB_GREEN, LOW);
digitalWrite(RGB_BLUE, LOW);
Serial.print("Bui: XAU - DO (");
}
Serial.print(dustLevel);
Serial.println(")");
}
void handlePIRLight() {
bool hasMotion = digitalRead(PIR_PIN);
digitalWrite(LED_PIR, hasMotion ? HIGH : LOW);
static bool lastMotion = false;
if (hasMotion != lastMotion) {
Serial.print("PIR: Den ");
Serial.println(hasMotion ? "ON" : "OFF");
lastMotion = hasMotion;
}
}
void handleSmartHome() {
bool autoMode = digitalRead(SW_MODE);
if (lastAutoMode && !autoMode) {
heaterOn = false;
acOn = false;
fanLevel = 0;
Serial.println("Mode: MANUAL - Temp Control Reset (Humidifier stays AUTO)");
}
lastAutoMode = autoMode;
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t)) {
if (t > 100) {
Serial.println("!!! CANH BAO CHAY: NHIET DO > 100 !!!");
heaterOn = false; acOn = false;
}
if (heaterOn) tempRoom += 0.05;
if (acOn) tempRoom -= 0.05;
if (abs(t - tempRoom) > 1.0) tempRoom = t;
}
if (!isnan(h)) {
humidity = h;
}
// --- ĐIỀU KHIỂN MÁY TẠO ẨM (Luôn tự động) ---
// Bật khi độ ẩm < 40% HOẶC bụi ở mức KÉM/XẤU (>= 2000)
humidifierOn = (humidity < 40) || (dustLevel >= 2000);
// --- XỬ LÝ AUTO/MANUAL CHO NHIỆT ĐỘ ---
if (autoMode) {
// Điều khiển nhiệt độ
if (tempRoom >= 28) {
acOn = true; heaterOn = false;
} else if (tempRoom <= 18) {
heaterOn = true; acOn = false;
} else if (tempRoom >= 20 && tempRoom <= 22) {
acOn = false; heaterOn = false;
}
// Điều khiển quạt
fanLevel = (tempRoom > 25) ? 1 : 0;
} else {
handleManualButtons();
}
digitalWrite(LED_HEATER, heaterOn);
digitalWrite(LED_AC, acOn);
digitalWrite(LED_FAN, fanLevel > 0);
digitalWrite(LED_HUMIDIFIER, humidifierOn);
lcd.setCursor(0, 0);
lcd.print(autoMode ? "AUTO" : "MAN ");
lcd.print(" T:");
lcd.print(tempRoom, 1);
lcd.print(" H:");
lcd.print((int)humidity);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(dustStatus);
if (dustStatus == "TB") {
lcd.print(" ");
} else if (dustStatus == "KEM") {
lcd.print(" ");
} else {
lcd.print(" ");
}
lcd.print(heaterOn ? "H" : " ");
lcd.print(acOn ? "A" : " ");
lcd.print(humidifierOn ? "M" : " ");
lcd.print(" F:");
lcd.print(fanLevel);
lcd.print(" ");
delay(200);
}
void handleManualButtons() {
static unsigned long lastPress = 0;
if (millis() - lastPress < 250) return;
if (digitalRead(BTN_AC) == LOW) {
acOn = !acOn;
if (acOn) heaterOn = false;
lastPress = millis();
Serial.println("Manual: Toggle AC");
}
if (digitalRead(BTN_FAN) == LOW) {
fanLevel++;
if (fanLevel > 3) fanLevel = 0;
lastPress = millis();
Serial.print("Manual: Fan Level "); Serial.println(fanLevel);
}
if (digitalRead(BTN_HEATER) == LOW) {
heaterOn = !heaterOn;
if (heaterOn) acOn = false;
lastPress = millis();
Serial.println("Manual: Toggle Heater");
}
}