#include <WiFi.h> // Thư viện kết nối WiFi
#include <PubSubClient.h> // Thư viện MQTT
#include <DHT.h> // Thư viện DHT
// Thông tin WiFi và MQTT
const char *SSID = "Wokwi-GUEST"; // Tên WiFi
const char *PASSWORD = ""; // Mật khẩu WiFi
const char *MQTT_SERVER = "broker.hivemq.com"; // MQTT Broker
const int MQTT_PORT = 1883; // Cổng MQTT
const char *MQTT_topic = "dobui"; // Chủ đề MQTT cho dữ liệu bụi
const char *MQTT_topic1 = "nhietdo"; // Chủ đề MQTT cho nhiệt độ
const char *MQTT_topic2 = "doam"; // Chủ đề MQTT cho độ ẩm
const char *MQTT_alertTopic = "alert"; // Chủ đề cảnh báo độ bụi cao
const char *MQTT_ID = "66dee282-b6db-452f-ae2d-b61700910fe3"; // ID MQTT
// Cảm biến và chân kết nối
#define DHT_PIN 15 // Chân kết nối DHT22
#define DHT_TYPE DHT22 // Loại cảm biến DHT22
#define LDR_PIN 36 // Chân kết nối LDR
#define BUZZER_PIN 2 // Chân kết nối Buzzer
#define BUTTON_PIN 14 // Chân kết nối nút nhấn
DHT dht(DHT_PIN, DHT_TYPE); // Đối tượng cảm biến DHT
WiFiClient espClient; // Kết nối WiFi
PubSubClient client(espClient);
bool buttonPressed = false; // Trạng thái nút nhấn
unsigned long lastSendTime = 0; // Thời gian gửi dữ liệu lần cuối
const long interval = 1000; // Khoảng thời gian gửi dữ liệu (1 giây)
void WIFIConnect() {
Serial.print("Connecting to WiFi: ");
Serial.println(SSID);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi 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");
Serial.print("MQTT Alert Topic: ");
Serial.print(MQTT_alertTopic);
Serial.println(" connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void sendData() {
// Đọc dữ liệu từ DHT22
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Không thể đọc từ cảm biến DHT22!");
} else {
char tempStr[8], humidityStr[8];
dtostrf(temperature, 1, 2, tempStr); // Chuyển số thành chuỗi
dtostrf(humidity, 1, 2, humidityStr); // Chuyển số thành chuỗi
// Gửi dữ liệu nhiệt độ và độ ẩm qua MQTT
client.publish(MQTT_topic1, tempStr); // Gửi nhiệt độ
client.publish(MQTT_topic2, humidityStr); // Gửi độ ẩm
Serial.printf("Nhiệt độ: %.2f °C, Độ ẩm: %.2f %%\n", temperature, humidity);
}
// Đọc giá trị từ LDR
int ldrValue = analogRead(LDR_PIN);
char ldrStr[8];
itoa(ldrValue, ldrStr, 10); // Chuyển giá trị LDR thành chuỗi
// Gửi giá trị LDR qua MQTT
client.publish(MQTT_topic, ldrStr); // Gửi giá trị LDR
Serial.printf("Giá trị bụi: %d\n", ldrValue);
char payload[50]; // Chuỗi chứa dữ liệu cần gửi
// Gộp dữ liệu thành chuỗi định dạng: "nhietdo|doam|dobui"
snprintf(payload, sizeof(payload), "%.2f|%.2f|%d", temperature, humidity, ldrValue);
// Gửi chuỗi dữ liệu qua MQTT
client.publish("testtopic/data_sg", payload);
// Kiểm tra mức ánh sáng vượt ngưỡng và gửi cảnh báo qua MQTT
if (ldrValue >= 2000) { // Ngưỡng ánh sáng là 2000
Serial.println("Cảnh báo: Độ bụi cao");
client.publish(MQTT_alertTopic, "Cảnh báo: Độ bụi cao!"); // Gửi cảnh báo qua MQTT
if (!buttonPressed) { // Chỉ bật Buzzer nếu nút chưa được xử lý
tone(BUZZER_PIN, 262); // Phát âm thanh tần số 262 Hz
delay(500); // Kêu trong 500ms
noTone(BUZZER_PIN); // Tắt buzzer
}
} else {
noTone(BUZZER_PIN); // Đảm bảo buzzer tắt khi không vượt ngưỡng
}
}
void setup() {
Serial.begin(115200);
pinMode(LDR_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // Sử dụng Pull-Up cho nút nhấn
pinMode(BUZZER_PIN, OUTPUT);
dht.begin(); // Khởi động cảm biến DHT22
Serial.println("Hệ thống bắt đầu...");
WIFIConnect();
client.setServer(MQTT_SERVER, MQTT_PORT);
}
void loop() {
if (!client.connected()) {
MQTT_Reconnect(); // Kiểm tra và kết nối lại nếu MQTT bị ngắt kết nối
}
client.loop(); // Đảm bảo rằng MQTT tiếp tục chạy
// Gửi dữ liệu chỉ khi đủ khoảng thời gian
unsigned long currentMillis = millis();
if (currentMillis - lastSendTime >= interval) {
lastSendTime = currentMillis;
sendData(); // Gửi dữ liệu
}
}