#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define BUZZER_PIN 23 // Chân kết nối còi báo
#define LDR_PIN 34 // Chân kết nối cảm biến ánh sáng (LDR)
#define led1 25 // LED đỏ
#define led2 26 // LED xanh lá
#define led3 27 // LED xanh dương
const float GAMMA = 0.7;
const float RL10 = 33;
// Cấu hình WiFi và MQTT
const char *ssid = "Wokwi-GUEST";
const char *password = "";
const char *mqtt_server = "test.mosquitto.org";
const int mqtt_port = 1883;
const char *topic_led = "21004171/output"; // Chủ đề MQTT cho LED
const char *topic_lcd = "21004171/lcd"; // Chủ đề MQTT cho LCD
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
// Kết nối WiFi
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// Kết nối lại MQTT nếu mất kết nối
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("Connected to MQTT broker");
client.subscribe(topic_led); // Đăng ký lắng nghe chủ đề LED
client.subscribe(topic_lcd); // Đăng ký lắng nghe chủ đề LCD
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(1000);
}
}
}
// Xử lý tin nhắn từ MQTT
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message: ");
Serial.println(message);
// Điều khiển LED
if (strcmp(topic, topic_led) == 0) {
if (message == "1") {
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
Serial.println("LED1 ON");
} else if (message == "2") {
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
Serial.println("LED2 ON");
} else if (message == "3") {
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
Serial.println("LED3 ON");
} else {
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
Serial.println("All LEDs OFF");
}
}
// Hiển thị thông báo lên LCD
if (strcmp(topic, topic_lcd) == 0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Message: ");
lcd.setCursor(0, 1);
lcd.print(message);
}
}
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
Serial.begin(115200);
lcd.init();
lcd.backlight();
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback); // Cấu hình hàm callback cho MQTT
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
// Đọc giá trị ánh sáng từ LDR
int analogValue = analogRead(LDR_PIN);
float voltage = analogValue / 4096.0 * 3.3;
float resistance = 2000 * voltage / (1 - voltage / 3.3);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Hiển thị giá trị ánh sáng và trạng thái trên LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lux: ");
lcd.print(lux);
lcd.setCursor(0, 1);
if (lux < 10) {
lcd.print("Very dark");
} else if (lux >= 10 && lux < 50) {
lcd.print("Low light");
} else if (lux >= 50 && lux < 500) {
lcd.print("Dim light");
} else if (lux >= 500 && lux < 1000) {
lcd.print("Ambient light");
} else if (lux >= 1000 && lux < 10000) {
lcd.print("Strong light");
} else {
lcd.print("Very bright");
}
// Bật còi nếu ánh sáng rất sáng (>10.000 lux)
if (lux > 10000) {
digitalWrite(BUZZER_PIN, HIGH);
} else {
digitalWrite(BUZZER_PIN, LOW);
}
// Gửi giá trị ánh sáng lên MQTT
String luxStr = String(lux, 2);
client.publish("/PTIT_Test/p/lux", luxStr.c_str());
// In ra Serial Monitor
Serial.print("Lux: ");
Serial.println(lux);
}
}