#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"
// Thông tin kết nối MQTT
const char* mqtt_server = "broker.emqx.io";
const int mqtt_port = 1883;
const char* mqtt_topic = "nhietdoam"; // Topic cho dữ liệu gốc
const char* mqtt_topic1 = "nhietdoam_trungbinh"; // Topic cho giá trị trung bình
const char* mqtt_topic2 = "nhietdoam_canhbao"; // Topic cho cảnh báo
const char* MQTT_ID = "1cf9d474-41f9-458d-970e-15ec958ed4ac";
WiFiClient espClient;
PubSubClient client(espClient);
// Thông tin kết nối Wi-Fi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Cấu hình cảm biến DHT22
const int DHTPIN = 15;
#define DHTTYPE DHT22
DHTesp dhtSensor; // Khởi tạo đối tượng DHT
// Cấu hình LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C là 0x27, màn hình 16x2
// Mảng lưu 3 giá trị nhiệt độ và độ ẩm gần nhất
float temperatureValues[3] = {0};
float humidityValues[3] = {0};
int currentIndex = 0; // Chỉ số vị trí mảng
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.print("MQTT Topic: ");
Serial.print(mqtt_topic1);
Serial.println(" connected");
Serial.print("MQTT Topic: ");
Serial.print(mqtt_topic2);
Serial.println(" connected");
} 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];
}
lcd.setCursor(0,1);
lcd.print(" ");
lcd.print(stMessage);
Serial.println();
}
void setup() {
Serial.begin(115200);
dhtSensor.setup(DHTPIN, DHTesp::DHT22); // Sử dụng phương thức setup() để chỉ định chân DHT
WIFIConnect();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
lcd.init();
lcd.backlight();
// Hiển thị chào mừng
lcd.setCursor(3, 0);
lcd.print("Welcome!");
// Kết nối với MQTT và đăng ký topic
client.subscribe(mqtt_topic2);
}
void loop() {
delay(10);
if (!client.connected()) {
MQTT_Reconnect();
client.subscribe(mqtt_topic2);
}
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;
}
// Lưu giá trị vào mảng (3 giá trị gần nhất)
temperatureValues[currentIndex] = temperature;
humidityValues[currentIndex] = humidity;
currentIndex = (currentIndex + 1) % 3; // Vị trí sẽ quay lại 0 sau khi đạt 3
// Tính giá trị trung bình
float avgTemperature = (temperatureValues[0] + temperatureValues[1] + temperatureValues[2]) / 3.0;
float avgHumidity = (humidityValues[0] + humidityValues[1] + humidityValues[2]) / 3.0;
// Gửi giá trị hiện tại lên MQTT
String message = String(temperature) + "|" + String(humidity);
client.publish(mqtt_topic, message.c_str()); // Gửi thông tin nhiệt độ và độ ẩm vào topic gốc
// Gửi giá trị trung bình lên MQTT
String avgMessage = String(avgTemperature) + "|" + String(avgHumidity);
client.publish(mqtt_topic1, avgMessage.c_str());
// Cảnh báo nếu nhiệt độ trung bình cao
if (avgTemperature >= 60) {
client.publish(mqtt_topic2, "Cảnh báo nhiệt độ cao!");
} else {
client.publish(mqtt_topic2, "Bình thường");
}
// Hiển thị dữ liệu trê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(avgTemperature);
lcd.print(" C");
lcd.setCursor(0, 1); // Chuyển con trỏ xuống dòng tiếp theo
lcd.print("Humidity: ");
lcd.print(avgHumidity);
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 mỗi 1 giây
}
// <!DOCTYPE html>
// <html lang="en">
// <head>
// <meta charset="UTF-8">
// <meta name="viewport" content="width=device-width, initial-scale=1.0">
// <title>Temperature and Humidity Dashboard</title>
// <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
// <style>
// body {
// font-family: Arial, sans-serif;
// background-color: #f4f4f9;
// padding: 20px;
// }
// .dashboard {
// text-align: center;
// }
// .data {
// font-size: 24px;
// margin: 20px;
// }
// .alert {
// color: red;
// font-weight: bold;
// }
// .normal {
// color: green;
// font-weight: bold;
// }
// </style>
// </head>
// <body>
// <div class="dashboard">
// <h1>Nhiệt Độ Và Độ Ẩm</h1>
// <div class="data">
// <p><strong>Nhiệt độ : </strong><span id="temperature">Loading...</span> °C</p>
// <p><strong>Độ ẩm : </strong><span id="humidity">Loading...</span> %</p>
// <p><strong>Nhiệt độ trung bình : </strong><span id="avgTemperature">Loading...</span> °C</p>
// <p><strong>Độ ẩm trung bình : </strong><span id="avgHumidity">Loading...</span> %</p>
// <p><strong>Trạng thái : </strong><span id="status">Loading...</span></p>
// </div>
// </div>
// <script>
// // Khai báo MQTT thông tin kết nối
// const mqttServer = 'wss://broker.emqx.io:8084/mqtt'; // Broker MQTT hỗ trợ WebSockets
// const clientId = 'webClient-' + Math.random().toString(36).substr(2, 9); // Tạo ID ngẫu nhiên cho client
// const mqttTopic = 'nhietdoam'; // Topic nhiệt độ và độ ẩm
// const mqttTopic1 = 'nhietdoam_trungbinh'; // Topic giá trị trung bình
// const mqttTopic2 = 'nhietdoam_canhbao'; // Topic cảnh báo
// const client = mqtt.connect(mqttServer, {
// clientId: clientId,
// clean: true
// });
// let temperature = 0;
// let humidity = 0;
// let avgTemperature = 0;
// let avgHumidity = 0;
// // Khi kết nối thành công với broker
// client.on('connect', function () {
// console.log('Connected to MQTT broker');
// client.subscribe([mqttTopic, mqttTopic1, mqttTopic2], function (err) {
// if (!err) {
// console.log('Subscribed to topics');
// } else {
// console.log('Subscription error: ', err);
// }
// });
// });
// // Khi nhận được tin nhắn từ broker
// client.on('message', function (topic, message) {
// let msg = message.toString();
// if (topic === mqttTopic) {
// // Nhận thông điệp nhiệt độ và độ ẩm
// const [temp, hum] = msg.split('|').map(parseFloat);
// // Lưu giá trị và hiển thị
// temperature = temp;
// humidity = hum;
// document.getElementById('temperature').textContent = temperature.toFixed(2);
// document.getElementById('humidity').textContent = humidity.toFixed(2);
// } else if (topic === mqttTopic1) {
// // Nhận giá trị trung bình từ topic nhietdoam_trungbinh
// const [avgTemp, avgHum] = msg.split('|').map(parseFloat);
// avgTemperature = avgTemp;
// avgHumidity = avgHum;
// document.getElementById('avgTemperature').textContent = avgTemperature.toFixed(2);
// document.getElementById('avgHumidity').textContent = avgHumidity.toFixed(2);
// } else if (topic === mqttTopic2) {
// // Nhận cảnh báo từ topic cảnh báo
// document.getElementById('status').textContent = msg;
// if (msg === "Cảnh báo nhiệt độ cao!") {
// document.getElementById('status').classList.add('alert');
// document.getElementById('status').classList.remove('normal');
// } else {
// document.getElementById('status').classList.add('normal');
// document.getElementById('status').classList.remove('alert');
// }
// }
// });
// </script>
// </body>
// </html>