#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include "PubSubClient.h"
#include "DHTesp.h"
const char *MQTTServer = "broker.emqx.io";
const char *MQTT_TopicTB = "tri/canhbao";//Canhbao
const char *MQTT_Topic = "tri/dht";//nhietdo,doam
const char *MQTT_Topic2 = "tri/nhietdotb";//NhietDoTB
const char *MQTT_TopicMotion = "testtopic/motionsensor";
const char *MQTT_TopicLed = "tri/batden";
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define led 4//chan led nd,da
#define led1 19 // chan led hc-rs04
#define led2 16 //led as
#define led3 25 // led mua
#define PIR_PIN 35 // Chân cho cảm biến mua
#define TRIGGER_PIN 5 // chan hcrs04
#define ECHO_PIN 18 // chan hcrs04
#define LIGHT_SENSOR_PIN 32 // Chân analog để kết nối với cảm biến độ sáng
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
WiFiClient espClient;
PubSubClient client(espClient);
const char *MQTT_ID = "1ddba09e-fb84-44cb-b740-da102a7f8a92";
int Port = 1883;
const int DHT_PIN = 15;//chan dht22
DHTesp dhtSensor;
const int numReadings = 3;
float temperatures[numReadings];
int readIndex = 0;
float total = 0;
float average = 0;
int numValidReadings = 0;
int per_light = 0;
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, IP address: ");
Serial.println(WiFi.localIP());
}
void MQTT_Reconnect() {
while (!client.connected()) {
if (client.connect(MQTT_ID)) {
client.subscribe(MQTT_TopicLed);
Serial.println("MQTT connected");
} else {
Serial.print("MQTT connection failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
bool ledStateFromTemperature = LOW; //
bool mqttMessageReceived = false; //
bool ledStateFromTemperature1 = LOW; //
bool ledStateFromTemperature2 = LOW; //
void callback(char *topic, byte *message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);
Serial.print("Message: ");
String stMessage;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
stMessage += (char)message[i];
}
Serial.println();
mqttMessageReceived = true;
if (stMessage == "on") {
ledStateFromTemperature = HIGH;
}
else if (stMessage == "off") {
ledStateFromTemperature = LOW;
}
else if (stMessage == "on1") {
ledStateFromTemperature1 = HIGH;
}
else if (stMessage == "off1") {
ledStateFromTemperature1 = LOW;
}
else if (stMessage == "on2") {
ledStateFromTemperature2 = HIGH;
}
else if (stMessage == "off2") {
ledStateFromTemperature2 = LOW;
}
}
void setup() {
Serial.begin(115200);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
WIFIConnect();
client.setServer(MQTTServer, Port);
client.setCallback(callback);
lcd.init();
lcd.backlight();
pinMode(led, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LIGHT_SENSOR_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
// Đăng ký để nhận dữ liệu từ topic mới
client.subscribe(MQTT_TopicLight);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
temperatures[thisReading] = NAN;
}
}
void loop() {
delay(10);
if (!client.connected()) {
MQTT_Reconnect();
}
client.loop();
int motionValue = digitalRead(PIR_PIN); // Đọc giá trị từ cảm biến mua
String motionSensorMessage;
Serial.print("ledStateFromTemperature: ");
Serial.println(ledStateFromTemperature);
if (motionValue == 1) {
motionSensorMessage = "Có mưa ";
digitalWrite(led3, HIGH);
} else {
motionSensorMessage = "Không mưa";
digitalWrite(led3, LOW);
}
client.publish(MQTT_TopicMotion, motionSensorMessage.c_str()); // Gửi giá trị qua MQTT
Serial.print("Motion Sensor Value: ");
Serial.println(motionSensorMessage);
float humidity = dhtSensor.getHumidity();// nhiet do
float temperature = dhtSensor.getTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
if (!isnan(temperatures[readIndex])) {
numValidReadings--;
}
temperatures[readIndex] = temperature;
if (!isnan(temperature)) {
numValidReadings++;
}
readIndex = (readIndex + 1) % numReadings;
float total = 0;
for (int i = 0; i < numReadings; i++) {
if (!isnan(temperatures[i])) {
total += temperatures[i];
}
}
float average = numValidReadings > 0 ? total / numValidReadings : NAN;
if (!isnan(average)) {
String message = String(average);
Serial.println(message);
client.publish(MQTT_Topic2, message.c_str());
}
int light_value = analogRead(LIGHT_SENSOR_PIN);
per_light = map(light_value, 4095, 0, 0, 100);// anhsang
String lightSensorMessage = String(per_light);
client.publish(MQTT_TopicLight, lightSensorMessage.c_str());
Serial.print("Light Sensor Value: ");
Serial.println(per_light);
//led cam bien as
if (!mqttMessageReceived) {
if (per_light < 20) {
ledStateFromTemperature2 = HIGH;
} else if (per_light>=50) {
ledStateFromTemperature2 = LOW;
}}
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);// cam bien nuoc
float distance = (duration * 0.0343) / 2;
if (!mqttMessageReceived) {
if (distance < 100) {
ledStateFromTemperature1 = HIGH;
} else if (distance >= 350) {
ledStateFromTemperature1 = LOW;
}}
String message = String(temperature) + "|" + String(humidity) + "|" + String(distance);
client.publish(MQTT_Topic, message.c_str());
// canh bao
if (!mqttMessageReceived) { //////
if (temperature >= 60) {
client.publish(MQTT_TopicTB, "Cảnh Báo Nhiệt Độ Cao");
ledStateFromTemperature = HIGH;
} else if (temperature < 20) {
client.publish(MQTT_TopicTB, "Cảnh Báo Nhiệt Độ Thấp");
ledStateFromTemperature = HIGH;
} else {
client.publish(MQTT_TopicTB, "Bình thường");
ledStateFromTemperature = LOW;
}
}
digitalWrite(led, ledStateFromTemperature);
digitalWrite(led1, ledStateFromTemperature1);
digitalWrite(led2, ledStateFromTemperature2);
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print(" %");
lcd.setCursor(0, 2);
lcd.print("Distance: ");
lcd.print(distance);
lcd.print(" cm");
delay(1000);
}