// le minh
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <PubSubClient.h>
#include "DHTesp.h"
// ====== CẤU HÌNH WiFi ======
const char* WIFI_SSID = "Wokwi-GUEST"; // hoặc WiFi nhà bạn
const char* WIFI_PASS = ""; // mật khẩu nếu có
// ====== CẤU HÌNH MQTT (HiveMQ Cloud cá nhân) ======
const char* MQTT_BROKER = "374b0d9b23b64681be6c6dea1f14472c.s1.eu.hivemq.cloud";
const int MQTT_PORT = 8883; // Port bảo mật TLS
// ⚠️ NHẬP USERNAME & PASSWORD của bạn trong Access Management
const char* MQTT_USER = "python";
const char* MQTT_PASS = "Python123";
const char* MQTT_TOPIC = "esp32/demo/dht";
WiFiClientSecure netClient; // Dùng kết nối bảo mật SSL/TLS
PubSubClient mqtt(netClient);
// ====== CẤU HÌNH HTTP ======
const char* HTTP_URL = "https://webhook.site/67d2ea27-2c9a-450e-9bd4-30ec4751f105";
// ====== CẢM BIẾN DHT ======
const int DHT_PIN = 15;
DHTesp dht;
// ====== BIẾN THỐNG KÊ ======
unsigned long cntSend = 0;
unsigned long mqttOK = 0, httpOK = 0;
unsigned long sumMqttMs = 0, sumHttpMs = 0;
// ====== KẾT NỐI WIFI ======
void wifiConnect() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("[WiFi] Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(300);
Serial.print(".");
}
Serial.printf("\n[WiFi] Connected. IP: %s\n", WiFi.localIP().toString().c_str());
}
// ====== KẾT NỐI MQTT (HiveMQ Cloud) ======
void mqttReconnect() {
while (!mqtt.connected()) {
Serial.print("[MQTT] Connecting to HiveMQ Cloud...");
String cid = "ESP32-" + String((uint32_t)ESP.getEfuseMac(), HEX);
if (mqtt.connect(cid.c_str(), MQTT_USER, MQTT_PASS)) {
Serial.println("OK");
mqtt.subscribe(MQTT_TOPIC);
} else {
Serial.printf("fail rc=%d, retry...\n", mqtt.state());
delay(2000);
}
}
}
// ====== SETUP ======
void setup() {
Serial.begin(115200);
dht.setup(DHT_PIN, DHTesp::DHT22); // Nếu dùng DHT11 thật: DHTesp::DHT11
wifiConnect();
netClient.setInsecure(); // bỏ kiểm tra chứng chỉ SSL cho test nhanh
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
}
// ====== LOOP ======
void loop() {
if (!mqtt.connected()) mqttReconnect();
mqtt.loop();
// Đọc cảm biến
TempAndHumidity s = dht.getTempAndHumidity();
if (isnan(s.temperature) || isnan(s.humidity)) {
Serial.println("[DHT] Read error!");
delay(2000);
return;
}
// ===== GỬI MQTT =====
unsigned long t0 = millis();
bool okMqtt = mqtt.publish(MQTT_TOPIC, "test");
unsigned long mqttMs = millis() - t0;
if (okMqtt) mqttOK++;
sumMqttMs += mqttMs;
// ===== GỬI HTTP =====
unsigned long httpMs = 0;
bool okHttp = false;
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(HTTP_URL);
http.addHeader("Content-Type", "application/json");
unsigned long h0 = millis();
int code = http.POST("{}");
httpMs = millis() - h0;
okHttp = (code > 0 && code < 400);
http.end();
if (okHttp) httpOK++;
sumHttpMs += httpMs;
}
// ===== TẠO PAYLOAD JSON =====
String payload = String("{\"temp\":") + String(s.temperature, 2) +
",\"hum\":" + String(s.humidity, 2) +
",\"mqtt_ms\":" + String(mqttMs) +
",\"http_ms\":" + String(httpMs) +
",\"ts\":" + String(millis()) + "}";
// Gửi payload thật lên MQTT
mqtt.publish(MQTT_TOPIC, payload.c_str());
cntSend++;
// ===== In log =====
Serial.println("------------------------------------------------");
Serial.println("Payload: " + payload);
Serial.printf("[MQTT] %s | time = %lums\n", okMqtt ? "OK" : "FAIL", mqttMs);
Serial.printf("[HTTP] %s | time = %lums\n", okHttp ? "OK" : "FAIL", httpMs);
// ===== Thống kê sau mỗi 10 lần =====
if (cntSend % 10 == 0) {
float avgMqtt = (cntSend ? (float)sumMqttMs / cntSend : 0);
float avgHttp = (cntSend ? (float)sumHttpMs / cntSend : 0);
Serial.println("============== SUMMARY ==============");
Serial.printf("Sends: %lu | MQTT OK: %lu | HTTP OK: %lu\n", cntSend, mqttOK, httpOK);
Serial.printf("Avg MQTT time: %.1f ms | Avg HTTP time: %.1f ms\n", avgMqtt, avgHttp);
Serial.println("=====================================");
}
delay(3000);
}