#include <WiFi.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
const char* MQTT_SERVER = "test.mosquitto.org";
const uint16_t MQTT_PORT = 1883;
const char* TOPIC_SET = "home/room1/led/set";
const char* TOPIC_STATE = "home/room1/led/state";
const char* TOPIC_LDR = "home/room1/ldr/value";
#define LED_PIN 2
#define LDR_PIN 34
WiFiClient espClient;
PubSubClient mqtt(espClient);
bool ledOn = false;
bool blinkMode = false;
unsigned long lastBlink = 0;
unsigned long lastLdrPublish = 0;
// =========================
// Hàm xuất trạng thái LED
// =========================
void publishState(bool retain = true) {
mqtt.publish(TOPIC_STATE, ledOn ? "ON" : "OFF", retain);
}
// =========================
// Đảo lại logic bật/tắt LED
// =========================
void setLed(bool on) {
ledOn = on;
digitalWrite(LED_PIN, on ? LOW : HIGH); // đảo logic: LOW = sáng, HIGH = tắt
publishState(true);
}
// =========================
void onMqttMessage(char* topic, byte* payload, unsigned int length) {
String msg;
for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
msg.trim(); msg.toUpperCase();
if (String(topic) == TOPIC_SET) {
if (msg == "ON") {
blinkMode = false;
setLed(true); // ON → sáng
}
else if (msg == "OFF") {
blinkMode = false;
setLed(false); // OFF → tắt
}
else if (msg == "TOGGLE") {
blinkMode = false;
setLed(!ledOn);
}
else if (msg == "BLINK") {
blinkMode = true;
Serial.println("LED BLINK MODE");
}
}
}
// =========================
void wifiConnect() {
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
Serial.print("Connecting WiFi: ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
int retry = 0;
while (WiFi.status() != WL_CONNECTED && retry < 30) {
delay(500);
Serial.print(".");
retry++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("\nWiFi OK, IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWiFi FAILED.");
}
}
// =========================
void mqttReconnect() {
while (!mqtt.connected()) {
String cid = "ESP32-" + String((uint32_t)ESP.getEfuseMac(), HEX);
if (mqtt.connect(cid.c_str())) {
mqtt.subscribe(TOPIC_SET);
publishState(true);
} else {
delay(2000);
}
}
}
// =========================
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH); // khởi đầu tắt đèn (vì LOW = sáng)
wifiConnect();
mqtt.setServer(MQTT_SERVER, MQTT_PORT);
mqtt.setCallback(onMqttMessage);
}
// =========================
void loop() {
if (WiFi.status() != WL_CONNECTED) wifiConnect();
if (!mqtt.connected()) mqttReconnect();
mqtt.loop();
unsigned long now = millis();
if (now - lastLdrPublish > 1000) {
int lightVal = analogRead(LDR_PIN);
Serial.print("LDR: ");
Serial.println(lightVal);
char msg[16];
snprintf(msg, sizeof(msg), "%d", lightVal);
mqtt.publish(TOPIC_LDR, msg);
// ⚙️ Khi sáng thì tắt đèn, khi tối thì bật đèn
if (lightVal > 1500) {
setLed(true); // Tối → sáng
} else {
setLed(false); // Sáng → tắt
}
lastLdrPublish = now;
}
if (blinkMode) {
if (now - lastBlink > 500) {
ledOn = !ledOn;
digitalWrite(LED_PIN, ledOn ? LOW : HIGH); // Đảo logic luôn ở đây
lastBlink = now;
}
}
}