#include <WiFi.h>
#include "PubSubClient.h"
#include "DHTesp.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DHT.h>
#include <Keypad.h>
// --- Cấu hình ---
#define DHT_PIN 15
#define DHT_TYPE DHT22
#define LCD_SDA 21
#define LCD_SCL 22
#define LDR_PIN 4
#define PIR_PIN 2
#define LED_LOSUOI 16
#define LED_DIEUHOA 17
#define LED_REM 5
#define LED_MOCUA 19
#define LED_CANHBAO 23
#define LED_DEN 18
// WiFi và MQTT
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* MQTT_ID = "c5afa5ae-d3a0-48b7-b850-92015a281909";
WiFiClient espClient;
PubSubClient client(espClient);
// Chủ đề MQTT
const char* topicTempHumidity = "Iot/Nhietdoam";
const char* topicLightStatus = "Iot/Rem";
const char* topicMotionStatus = "Iot/Den";
const char* topicDoorStatus = "Iot/Cua";
const char* topicKeypadStatus = "Iot/Keypad";
// Cảm biến DHT
DHTesp dhtSensor;
DHT dht(DHT_PIN, DHT_TYPE);
// LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Keypad
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27};
byte colPins[COLS] = {26, 25, 33, 32};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Biến ngưỡng và trạng thái
float tempThresholdLow = 18.0;
float tempThresholdHigh = 30.0;
int delayTime = 5000; // Mặc định 5 giây
int lightThreshold = 800;
int timeoutLight = 10000; // Thời gian chờ cho đèn
String correctPassword = "1234";
String enteredPassword = "";
int failCount = 0;
int maxFail = 3;
unsigned long lastMotionTime = 0;
unsigned long lastAutoTime = 0;
bool autoMode = true;
void WIFIConnect() {
Serial.println("Đang kết nối tới WiFi: Wokwi-GUEST");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi đã kết nối, IP: ");
Serial.println(WiFi.localIP());
}
void MQTT_Reconnect() {
while (!client.connected()) {
if (client.connect(MQTT_ID)) {
Serial.println("Đã kết nối MQTT");
client.subscribe(topicKeypadStatus);
client.subscribe(topicDoorStatus);
} else {
delay(5000);
}
}
}
void sendMQTT(const char* topic, String payload) {
client.publish(topic, payload.c_str());
}
void handleKeypadInput() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (enteredPassword == correctPassword) {
digitalWrite(LED_MOCUA, HIGH);
sendMQTT(topicKeypadStatus, "Mật khẩu đúng, cửa đã mở");
} else {
failCount++;
if (failCount >= maxFail) {
sendMQTT(topicKeypadStatus, "Quá nhiều lần nhập sai, hệ thống bị khóa");
delay(30000);
}
digitalWrite(LED_CANHBAO, HIGH);
delay(500);
digitalWrite(LED_CANHBAO, LOW);
}
enteredPassword = ""; // Đặt lại mật khẩu
} else if (key == '*') {
enteredPassword = ""; // Xóa đầu vào
} else {
enteredPassword += key;
}
}
}
void handleTemperatureHumidity() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Không thể đọc cảm biến DHT!");
return;
}
lcd.setCursor(0, 0);
lcd.print("Nhiet do: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Do am: ");
lcd.print(humidity);
lcd.print(" %");
String tempHumPayload = "{";
tempHumPayload += "\"temperature\": ";
tempHumPayload += temperature;
tempHumPayload += ", \"humidity\": ";
tempHumPayload += humidity;
tempHumPayload += "}";
sendMQTT(topicTempHumidity, tempHumPayload);
if (temperature < tempThresholdLow) {
digitalWrite(LED_LOSUOI, HIGH);
lcd.setCursor(0, 2);
lcd.print("Bat lo suoi ");
} else if (temperature > tempThresholdHigh) {
digitalWrite(LED_DIEUHOA, HIGH);
lcd.setCursor(0, 2);
lcd.print("Bat dieu hoa ");
} else {
digitalWrite(LED_LOSUOI, LOW);
digitalWrite(LED_DIEUHOA, LOW);
lcd.setCursor(0, 2);
lcd.print("Nhiet do binh thuong ");
}
}
void handleLight() {
int lightValue = analogRead(LDR_PIN);
if (lightValue > lightThreshold) {
digitalWrite(LED_REM, HIGH);
sendMQTT(topicLightStatus, "Ánh sáng cao, rèm đã đóng");
} else {
digitalWrite(LED_REM, LOW);
sendMQTT(topicLightStatus, "Ánh sáng thấp, rèm đã mở");
}
}
void handleMotion() {
bool motionDetected = digitalRead(PIR_PIN);
int lightValue = analogRead(LDR_PIN);
if (motionDetected && lightValue < lightThreshold) {
digitalWrite(LED_DEN, HIGH);
lastMotionTime = millis();
sendMQTT(topicMotionStatus, "Phát hiện chuyển động, bật đèn");
}
if (millis() - lastMotionTime > timeoutLight) {
digitalWrite(LED_DEN, LOW);
sendMQTT(topicMotionStatus, "Không có chuyển động, tắt đèn");
}
}
void setup() {
Serial.begin(115200);
WIFIConnect();
client.setServer(mqtt_server, mqtt_port);
client.setCallback([](char* topic, byte* payload, unsigned int length) {
Serial.print("Tin nhắn nhận được trên chủ đề: ");
Serial.println(topic);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
});
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
dht.begin();
lcd.init();
lcd.backlight();
pinMode(LDR_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
pinMode(LED_LOSUOI, OUTPUT);
pinMode(LED_DIEUHOA, OUTPUT);
pinMode(LED_REM, OUTPUT);
pinMode(LED_MOCUA, OUTPUT);
pinMode(LED_CANHBAO, OUTPUT);
pinMode(LED_DEN, OUTPUT);
digitalWrite(LED_LOSUOI, LOW);
digitalWrite(LED_DIEUHOA, LOW);
digitalWrite(LED_REM, LOW);
digitalWrite(LED_MOCUA, LOW);
digitalWrite(LED_CANHBAO, LOW);
digitalWrite(LED_DEN, LOW);
}
void loop() {
if (!client.connected()) {
MQTT_Reconnect();
}
client.loop();
handleKeypadInput();
handleTemperatureHumidity();
handleLight();
handleMotion();
delay(1000);
}