#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
char ssid[] = "Wokwi-GUEST";
char password[] = "";
const char* mqtt_server = "demo.thingsboard.io";
const char* token = "HVXzPxbGDfuaqqkoGZbz";
WiFiClient wifiClient;
PubSubClient client(wifiClient);
#define LDR_PIN A0 // Raspberry Pi Pico W: sử dụng A0 (GPIO26) cho analog
#define RELAY_PIN 17 // GPIO2 cho relay (có thể thay đổi)
int threshold = 800;
bool manualControl = false;
String currentStatus = "OFF";
String controlMode = "AUTO";
unsigned long onCount = 0;
unsigned long startTime;
const char* model = "RaspberryPi-LDR-V1";
void setup_wifi() {
WiFi.begin(ssid, password);
Serial.print("🔌 Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n✅ WiFi connected");
}
void reconnect() {
while (!client.connected()) {
Serial.print("🔄 Connecting to MQTT...");
if (client.connect("RaspberryPiClient", token, NULL)) {
Serial.println("✅ Connected");
client.subscribe("v1/devices/me/rpc/request/+");
} else {
Serial.print("❌ Failed. Retry in 5s. Code: ");
Serial.println(client.state());
delay(5000);
}
}
}
void sendTelemetry(int light) {
unsigned long uptime = millis() / 1000;
StaticJsonDocument<256> doc;
doc["ambient_light"] = light;
doc["status"] = currentStatus;
doc["uptime"] = uptime;
doc["mode"] = controlMode;
doc["on_count"] = onCount;
doc["model"] = model;
char buffer[256];
serializeJson(doc, buffer);
client.publish("v1/devices/me/telemetry", buffer);
Serial.println("📤 Sent telemetry: " + String(buffer));
}
void callback(char* topic, byte* payload, unsigned int length) {
payload[length] = '\0';
StaticJsonDocument<200> doc;
deserializeJson(doc, payload);
String method = doc["method"];
String param = doc["params"];
String topicStr = String(topic);
int lastSlash = topicStr.lastIndexOf('/');
String requestId = topicStr.substring(lastSlash + 1);
String responseTopic = "v1/devices/me/rpc/response/" + requestId;
if (method == "setStatus") {
manualControl = true;
controlMode = "MANUAL";
if (param == "ON") {
digitalWrite(RELAY_PIN, HIGH);
if (currentStatus != "ON") onCount++;
currentStatus = "ON";
} else {
digitalWrite(RELAY_PIN, LOW);
currentStatus = "OFF";
}
sendTelemetry(analogRead(LDR_PIN));
client.publish(responseTopic.c_str(), "true");
}
if (method == "setMode") {
controlMode = param;
manualControl = (controlMode == "MANUAL");
client.publish(responseTopic.c_str(), controlMode.c_str());
sendTelemetry(analogRead(LDR_PIN));
}
}
void setup() {
Serial.begin(115200);
delay(1000); // đợi Serial ổn định
pinMode(LDR_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
startTime = millis();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
int light = analogRead(LDR_PIN);
if (!manualControl) {
controlMode = "AUTO";
if (light < threshold && currentStatus != "ON") {
digitalWrite(RELAY_PIN, HIGH);
currentStatus = "ON";
onCount++;
} else if (light >= threshold && currentStatus != "OFF") {
digitalWrite(RELAY_PIN, LOW);
currentStatus = "OFF";
}
}
sendTelemetry(light);
delay(2000);
}