#include <WiFi.h>
#include "PubSubClient.h"
#include "DHTesp.h"
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <ArduinoJson.h>
//Kênh gửi
const char * MQTTServer = "broker.emqx.io";
const char* data_ldr_topic = "iot50percent_ldr"; //LDR
const char* data_gas_topic = "iot50percent_gas"; //GAS
const char* data_pir_topic = "iot50percent_pir"; //PIR
const char* data_ultra_topic = "iot50percent_ultrasonic"; //ultrasonic
const char* data_rain_topic = "iot50percent_rain"; //rain
const char* data_dht_topic = "iot50percent_dht"; //TEMP & HUMI
// Kênh nhận
const char* rem_cua_topic = "iot50percent/remcua";
const char* rem_cua_topic_response = "iot50percent/remcua/response";
const char* cua_so_topic = "iot50percent/cuaso";
const char* cua_so_topic_response = "iot50percent/cuaso/response";
const char* cua_nha_topic = "iot50percent/cuanha";
const char* cua_nha_topic_response = "iot50percent/cuanha/response";
const char* gian_phoi_topic = "iot50percent/gianphoi";
const char* gian_phoi_topic_response = "iot50percent/gianphoi/response";
const char* den_wc_topic = "iot50percent/denwc";
const char* den_wc_topic_response = "iot50percent/denwc/response";
const char* den_war_topic = "iot50percent/denwar";
const char* den_war_topic_response = "iot50percent/denwar/response";
const char* den_nha_topic = "iot50percent/dennha";
const char* den_nha_topic_response = "iot50percent/dennha/response";
const char* dieu_hoa_topic = "iot50percent/dieuhoa";
const char* dieu_hoa_topic_response = "iot50percent/dieuhoa/response";
// Tạo ID ngẫu nhiên tại: https://www.guidgen.com/
const char * MQTT_ID = "c5afa5ae-d3a0-48b7-b850-92015a281909";
int Port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
//............................................................................................................
LiquidCrystal_I2C lcd(0x27, 20, 4);
//Các đèn led báo hiệu
const int ledAir = 16; //led xanh lam : máy điều hòa
const int ledHome = 17; //led trắng
const int ledWar = 4; //led đỏ
const int ledWC = 32; //led cam
//DHT22
const int DHT_PIN = 23;
DHTesp dht;
//Buzzer
const int buzzer = 14;
//Gas Sensor không có cảm biến này nên lấy "wokwi-slide-switch Reference" tượng trưng cho 2 mức cao thấp tương ứng với việc
//có gas hoặc không có gas
const int gasPin = 12;
//PIR
const int pir = 25;
//LDR
const int LDR_PIN = 34;
int ldrVal = 0; // Value of LDR
int ledPin = 2; // Build in LED pin
// LDR Characteristics
const float GAMMA = 0.7;
const float RL10 = 50;
//Rain Sensor
const int RAIN_ANALOG = 18;
const int RAIN_DIGITAL = 19;
//Ultrasonic
const int TRIG_PIN = 27;
const int ECHO_PIN = 26;
float duration_us, distance_cm;
bool ultrasonicPersonDetected = false; // Trạng thái để theo dõi nếu có người được phát hiện liên tục
unsigned long ultrasonicDetectionStartTime = 0; // Thời gian khi người được phát hiện lần đầu
//Servo
const int servoRemCua = 15;
Servo remCua; //Rèm cửa
const int servoCuaSo = 13;
Servo cuaSo; //Cửa sổ
const int servoCuaNha = 2;
Servo cuaNha; //Cửa nhà
const int servoGianPhoi = 5;
Servo gianPhoi; //Giàn phơi đồ
bool gasDetected = false;
bool rainDetected = false;
void WIFIConnect() {
Serial.println("Connecting to SSID: Wokwi-GUEST");
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected");
Serial.print(", IP address: ");
Serial.println(WiFi.localIP());
}
void MQTT_Reconnect() {
while (!client.connected()) {
if (client.connect(MQTT_ID)) {
Serial.print("MQTT Topic: ");
client.subscribe(data_ldr_topic);
client.subscribe(data_gas_topic);
client.subscribe(data_pir_topic);
client.subscribe(data_ultra_topic);
client.subscribe(data_rain_topic);
client.subscribe(data_dht_topic);
client.subscribe(rem_cua_topic);
client.subscribe(rem_cua_topic_response);
client.subscribe(cua_so_topic);
client.subscribe(cua_so_topic_response);
client.subscribe(cua_nha_topic);
client.subscribe(cua_nha_topic_response);
client.subscribe(gian_phoi_topic);
client.subscribe(gian_phoi_topic_response);
Serial.println(" connected");
Serial.println("");
} else {
Serial.print("failed, rc = ");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);
Serial.print("Message: ");
String receivedMessage;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
receivedMessage += (char)message[i];
}
// Kiểm tra và xử lý các thông điệp điều khiển từ web
}
void setup() {
Serial.begin(115200);
//LCD
lcd.init();
lcd.backlight();
noTone(buzzer);
//Rain Sensor
pinMode(RAIN_ANALOG, INPUT);
pinMode(RAIN_DIGITAL, INPUT);
analogReadResolution(10);
//Ultrasonic
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
//DHT22
dht.setup(DHT_PIN, DHTesp::DHT22);
//Led và buzzer
pinMode(ledAir, OUTPUT); //led xanh lam: máy điều hòa
pinMode(ledHome, OUTPUT); // led trắng: đèn ở khu vực luôn sáng khi trời tối như cửa ngoài, cổng...
pinMode(ledWar, OUTPUT); //led đỏ: cảnh báo có khí gas
pinMode(ledWC, OUTPUT); //led cam: đèn cửa trong nhà, nhà vệ sinh, khu ít người qua lại
digitalWrite(ledAir, LOW);
digitalWrite(ledHome, LOW);
digitalWrite(ledWar, LOW);
digitalWrite(ledWC, LOW);
//Servo
remCua.attach(15);
cuaSo.attach(13);
gianPhoi.attach(5);
cuaNha.attach(2);
//Buzzer
pinMode(buzzer, OUTPUT);
//Gas Sensor
pinMode(gasPin, INPUT);
//LDR
pinMode(LDR_PIN, INPUT);
//PIR
pinMode(pir, INPUT);
WIFIConnect();
client.setServer(MQTTServer, Port);
client.setCallback(callback);
remCua.write(90);
cuaSo.write(90);
gianPhoi.write(90);
cuaNha.write(90);
}
//LDR sensor
void ldrSensor() {
ldrVal = analogRead(LDR_PIN); // Read the analog value of the LDR
float voltage = ldrVal / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
if (lux > 1000) {
remCua.write(180); // mở rèm cửa
lcd.setCursor(0, 0);
lcd.print("RemCua: Mo ");
digitalWrite(ledHome, LOW); // tắt đèn trong nhà
client.publish(rem_cua_topic, "Đang mở rèm");
client.publish(den_nha_topic, "Đang bật");
} else {
remCua.write(90); // đóng rèm cửa
lcd.setCursor(0, 0);
lcd.print("RemCua: Dong");
digitalWrite(ledHome, HIGH); // bật đèn trong nhà
client.publish(rem_cua_topic, "Đang đóng rèm");
client.publish(den_nha_topic, "Đang tắt");
}
Serial.println(lux);
// Chuyển đổi giá trị lux thành chuỗi và gửi qua MQTT
String luxStr = String(lux);
client.publish(data_ldr_topic, luxStr.c_str());
delay(1000);
}
//GAS sensor
void gasSensor() {
int gasVal = digitalRead(gasPin);
if (gasVal == HIGH) { // Phát hiện khí gas
gasDetected = true;
tone(buzzer, 1000); // Bật còi báo động
digitalWrite(ledWar, HIGH); // Bật đèn cảnh báo
lcd.setCursor(0, 1);
lcd.print("Co khi Gas ");
delay(1000);
client.publish(data_gas_topic, "Phát hiện có khí Gas");
client.publish(den_war_topic, "Đang bật");
} else {
gasDetected = false;
noTone(buzzer); // Tắt còi báo động
digitalWrite(ledWar, LOW); // Tắt đèn cảnh báo
lcd.setCursor(0, 1);
lcd.print("Khong co khi Gas");
client.publish(data_gas_topic, "Không phát hiện có khí Gas");
client.publish(den_war_topic, "Đang tắt");
}
Serial.print("Giá trị của gas: ");
Serial.println(gasVal);
delay(1000);
}
//RAIN sensor
void rainSensor() {
int rainAnalog = analogRead(RAIN_ANALOG);
int rainDigital = digitalRead(RAIN_DIGITAL);
if (rainDigital == 1) { // Phát hiện mưa
gianPhoi.write(90); // Thu giàn phơi đồ vào
lcd.setCursor(0, 2);
lcd.print("Co mua:Thu gian phoi");
client.publish(data_rain_topic, "Có mưa");
client.publish(gian_phoi_topic, "Thu giàn phơi");
} else { // Không mưa
gianPhoi.write(180); // Kéo giàn phơi đồ ra
lcd.setCursor(0, 2);
lcd.print("Ko mua:Keo gian phoi");
client.publish(data_rain_topic, "Không có mưa");
client.publish(gian_phoi_topic, "Kéo giàn phơi");
}
Serial.print("Gia tri mua ");
Serial.println(rainDigital);
delay(1000);
}
//PIR sensor
void pirSensor() {
int pirVal = digitalRead(pir);
if (pirVal == HIGH) { // Phát hiện chuyển động
digitalWrite(ledWC, HIGH); // Bật đèn nhà vệ sinh
client.publish(data_pir_topic, "Có chuyển động");
client.publish(den_wc_topic, "Đang bật");
} else { // Không phát hiện chuyển động
digitalWrite(ledWC, LOW); // Tắt đèn nhà vệ sinh
client.publish(data_pir_topic, "Không có chuyển động");
client.publish(den_wc_topic, "Đang tắt");
}
delay(1000);
}
//ULTRA sensor
void ultrasonicSensor() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration_us = pulseIn(ECHO_PIN, HIGH);
distance_cm = 0.017 * duration_us;
if (distance_cm < 200) {
if (!ultrasonicPersonDetected) { // Nếu vừa bắt đầu phát hiện người
ultrasonicDetectionStartTime = millis();
ultrasonicPersonDetected = true;
} else {
if ((millis() - ultrasonicDetectionStartTime) >= 3000) { // 3 giây phát hiện liên tục
tone(buzzer, 1000); // Bật còi báo động
lcd.setCursor(0, 3);
lcd.print("Co nguoi truoc nha");
client.publish(data_ultra_topic, "Có người đứng gần cửa nhà!");
}
}
} else {
ultrasonicPersonDetected = false;
lcd.setCursor(0, 3);
noTone(buzzer); // Tắt còi báo động
lcd.print("... ");
client.publish(data_ultra_topic, ". . .");
}
delay(1000);
Serial.print("khoangcach: ");
Serial.println(distance_cm);
}
//DHT sensor
void dhtSensor() {
TempAndHumidity data = dht.getTempAndHumidity();
if (data.temperature > 38 && data.humidity > 70) {
digitalWrite(ledAir, HIGH); // Bật điều hòa
client.publish(dieu_hoa_topic, "Đang bật");
} else {
digitalWrite(ledAir, LOW); // Tắt điều hòa
client.publish(dieu_hoa_topic, "Đang tắt");
}
delay(1000);
Serial.print("Nhiet do/Do am ");
Serial.print(data.temperature);
Serial.print(" / ");
Serial.println(data.humidity);
//Gửi dữ liệu sang web
DynamicJsonDocument doc(128);
doc["nhietDo"] = data.temperature;
doc["doAm"] = data.humidity;
String jsonString;
serializeJson(doc, jsonString);
client.publish(data_dht_topic, jsonString.c_str());
}
//--------------------------------------------------------
void process() {
pirSensor();
ldrSensor();
gasSensor();
ultrasonicSensor();
rainSensor();
dhtSensor();
}
void loop() {
if (!client.connected()) {
MQTT_Reconnect();
}
client.loop();
process();
delay(1000);
}