#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include "PubSubClient.h"
#include "DHTesp.h"
const char * MQTTServer = "broker.emqx.io";
const char * MQTT_Topic = "ktIoT/display";
const char * MQTT_Topic1 = "ktIoT/data";
const char * MQTT_Topic2 = "ktIoT/avgTemp";
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define led 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
WiFiClient espClient;
PubSubClient client(espClient);
// Tạo ID ngẫu nhiên tại: https://www.guidgen.com/
const char * MQTT_ID = "8e3691e9-39c3-44f8-bfe1-9a3aed16126a";
int Port = 1883;
const int DHT_PIN = 15;
DHTesp dhtSensor;
// Khai báo để tính nhiệt độ trung bình
const int numReadings = 3;
float temperatures[numReadings];
int readIndex = 0;
float total = 0;
float average = 0;
int numValidReadings = 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");
Serial.print(", IP address: ");
Serial.println(WiFi.localIP());
}
void MQTT_Reconnect() {
while (!client.connected()) {
if (client.connect(MQTT_ID)) {
Serial.print("MQTT Topic: ");
Serial.print(MQTT_Topic);
Serial.println(" connected");
Serial.println("");
Serial.print("MQTT Topic: ");
Serial.print(MQTT_Topic1);
Serial.println(" connected");
Serial.println("");
Serial.print("MQTT Topic: ");
Serial.print(MQTT_Topic2);
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 stMessage;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
stMessage += (char)message[i];
}
Serial.println();
}
void setup() {
Serial.begin(115200);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
WIFIConnect();
client.setServer(MQTTServer, Port);
client.setCallback(callback);
lcd.init();
lcd.backlight();
// Print something
lcd.setCursor(3, 0);
lcd.print("Welcome!");
Serial.begin(115200);
pinMode(led, OUTPUT);
//Khởi tạo mảng lưu nhiệt độ trung bình
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
temperatures[thisReading] = NAN;
}
}
void loop() {
delay(10);
if (!client.connected()) {
MQTT_Reconnect();
}
client.loop();
// Đọc dữ liệu từ cảm biến DHT22
float humidity = dhtSensor.getHumidity();
float temperature = dhtSensor.getTemperature();
// Kiểm tra dữ liệu có hợp lệ không
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
//Thực hiện tính trung bình
// Cập nhật mảng và số lượng đọc hợp lệ
if (!isnan(temperatures[readIndex])) {
// Nếu giá trị cũ là hợp lệ, giảm số lượng đọc hợp lệ
numValidReadings--;
}
temperatures[readIndex] = temperature;
if (!isnan(temperature)) {
// Nếu giá trị mới là hợp lệ, tăng số lượng đọc hợp lệ
numValidReadings++;
}
readIndex = (readIndex + 1) % numReadings;
// Tính trung bình
float total = 0;
for (int i = 0; i < numReadings; i++) {
if (!isnan(temperatures[i])) {
total += temperatures[i];
}
}
float average = numValidReadings > 0 ? total / numValidReadings : NAN;
// Gửi dữ liệu nếu có đủ giá trị hợp lệ
if (!isnan(average)) {
String message = String(average);
client.publish(MQTT_Topic2, message.c_str());
}
//gửi dữ liệu lên mqtt
if (!isnan(humidity) && !isnan(temperature)) {
// Tạo chuỗi tin nhắn
String message = String(temperature) + "|" + String(humidity);
// Gửi tin nhắn
client.publish(MQTT_Topic1, message.c_str());
}
if (temperature > 35 && humidity < 40) {
client.publish(MQTT_Topic,"Báo động");
digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
delay(100);
}
else if(temperature > 60){
client.publish(MQTT_Topic,"cảnh báo nhiệt độ cao!");
digitalWrite(led,LOW);
}
else{
client.publish(MQTT_Topic,"Bình thường");
digitalWrite(led,LOW);
}
// Hiển thị dữ liệu lên LCD
lcd.clear(); // Xóa nội dung cũ trên LCD
lcd.setCursor(0, 0); // Đặt con trỏ tại vị trí đầu tiên của LCD
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1); // Chuyển con trỏ xuống dòng tiếp theo
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print(" %");
// Thêm delay để giữ dữ liệu trên màn hình một thời gian
delay(1000); // Cập nhật dữ liệu mỗi 2 giây
}
/*
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Giám sát</title>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
</head>
<body>
<h1>Theo dõi nhiệt độ và độ ẩm</h1>
<div id="dataDisplay">Đang chờ dữ liệu .....</div>
<div id="averageTempDisplay"></div>
<div id="alertDisplay">Đang chờ cảnh báo .....</div>
<!-- <button></button> -->
<script>
// Kết nối tới MQTT broker
const client = mqtt.connect("ws://broker.emqx.io:8083/mqtt");
client.on("connect", function () {
console.log("Connected to MQTT broker");
client.subscribe("ktIoT/display");
client.subscribe("ktIoT/data");
client.subscribe("ktIoT/avgTemp");
});
client.on("message", function (topic, message) {
console.log("Received message:", message.toString());
if (topic === "ktIoT/display") {
document.getElementById("alertDisplay").innerHTML =
"Alert: " + message.toString();
} else if (topic === "ktIoT/data") {
const [temperature, humidity] = message
.toString()
.split("|");
document.getElementById("dataDisplay").innerHTML =
"Temperature: " +
temperature +
"°C<br> Humidity: " +
humidity
}
// else if (topic == "ktIoT/avgTemp"){
// document.getElementById("averageTempDisplay").innerHTML = "Average Temp: " + message.toString() + "°C";
// }
});
</script>
</body>
</html>
*/