#include <Adafruit_Sensor.h>
#include <DHT_U.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
#include <FastLED.h>
// ---------------------------
// Pin Definitions
// ---------------------------
#define DHTPIN 12
#define DHTTYPE DHT22
#define LED_PIN_SIMPLE 26 // Normal LED
#define SERVO_PIN 2
#define NEOPIXEL_PIN 4
#define NUM_LEDS 16
// ---------------------------
// Sensor / Devices
// ---------------------------
DHT_Unified dht(DHTPIN, DHTTYPE);
Servo servo;
CRGB leds[NUM_LEDS];
// ---------------------------
// WiFi + MQTT
// ---------------------------
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "broker.emqx.io";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastPublish = 0;
// ---------------------------
// Read Temperature Function
// ---------------------------
float getTemperature() {
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) return -1;
return event.temperature;
}
// ---------------------------
// Read Humidity Function
// ---------------------------
float getHumidity() {
sensors_event_t event;
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) return -1;
return event.relative_humidity;
}
// ---------------------------
// WiFi Setup
// ---------------------------
void setup_wifi() {
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println("\nWiFi Connected!");
}
// ---------------------------
// MQTT Reconnect
// ---------------------------
void reconnect() {
while (!client.connected()) {
Serial.print("MQTT connecting... ");
if (client.connect("ESP32-Dashboard-Device")) {
Serial.println("connected");
client.subscribe("lights");
client.subscribe("servo");
client.subscribe("lights/neopixel");
} else {
Serial.print("Failed (rc=");
Serial.print(client.state());
Serial.println("). Retry in 5 sec...");
delay(5000);
}
}
}
// ---------------------------
// MQTT Callback
// ---------------------------
void callback(char* topic, byte* payload, unsigned int len) {
String data = "";
for (int i = 0; i < len; i++) data += (char)payload[i];
Serial.print("Topic: ");
Serial.println(topic);
Serial.print("Payload: ");
Serial.println(data);
// ---------------------------
// LED ON/OFF
// ---------------------------
if (String(topic) == "lights") {
if (data == "ON") digitalWrite(LED_PIN_SIMPLE, HIGH);
else digitalWrite(LED_PIN_SIMPLE, LOW);
}
// ---------------------------
// Servo Control
// ---------------------------
if (String(topic) == "servo") {
int degree = data.toInt();
servo.write(degree);
Serial.printf("Servo → %d degrees\n", degree);
}
// ---------------------------
// RGB Parsing for Neopixel
// Format: "R,G,B"
// ---------------------------
if (String(topic) == "lights/neopixel") {
int r, g, b;
sscanf(data.c_str(), "%d,%d,%d", &r, &g, &b);
Serial.printf("Neopixel → R:%d G:%d B:%d\n", r, g, b);
fill_solid(leds, NUM_LEDS, CRGB(r, g, b));
FastLED.show();
}
}
// ---------------------------
// Setup
// ---------------------------
void setup() {
Serial.begin(115200);
// Sensors
dht.begin();
// Simple LED
pinMode(LED_PIN_SIMPLE, OUTPUT);
digitalWrite(LED_PIN_SIMPLE, LOW);
// Servo
servo.attach(SERVO_PIN);
servo.write(0);
// Neopixel
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(leds, NUM_LEDS);
// WiFi & MQTT
setup_wifi();
client.setServer(mqttServer, 1883);
client.setCallback(callback);
}
// ---------------------------
// Loop
// ---------------------------
void loop() {
if (!client.connected()) reconnect();
client.loop();
unsigned long now = millis();
if (now - lastPublish > 1000) { // every 1 second
lastPublish = now;
float t = getTemperature();
float h = getHumidity();
Serial.printf("Temp: %.2f | Hum: %.2f\n", t, h);
client.publish("temperature", String(t).c_str());
client.publish("humidity", String(h).c_str());
}
}