// Código: ESP32 -> DHT11 + LDR -> MQTT, com timestamp NTP
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
// ========== CONFIG ==========
const char* ssid = "SEU_SSID";
const char* password = "SUA_SENHA_WIFI";
const char* mqtt_server = "test.mosquitto.org"; // broker público para testes
const uint16_t mqtt_port = 1883;
const char* mqtt_user = NULL; // se houver usuário
const char* mqtt_pass = NULL; // se houver senha
const char* deviceId = "esp32_001";
String topicTelem = String("esp32/sensores/") + deviceId + "/telemetry";
String topicCmd = String("esp32/sensores/") + deviceId + "/commands";
String topicStatus= String("esp32/sensores/") + deviceId + "/status";
// Pins
#define DHTPIN 15
#define DHTTYPE DHT11
#define LDR_PIN 35
#define LED_PIN
// Intervalos
const unsigned long publishInterval = 15000; // 15s
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);
// NTP
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000); // 0 = UTC, ajuste se quiser offset
unsigned long lastPublish = 0;
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Conectando a ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int tries = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
tries++;
if (tries > 40) { // timeout
Serial.println("\nFalha ao conectar WiFi — reiniciando...");
ESP.restart();
}
}
Serial.println("");
Serial.println("WiFi conectado");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
// Recebe comandos do MyMQTT
String msg;
for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
Serial.print("Recebido em [");
Serial.print(topic);
Serial.print("] -> ");
Serial.println(msg);
// exemplo: {"cmd":"led","state":"on"}
if (String(topic) == topicCmd) {
if (msg.indexOf("led") >= 0) {
if (msg.indexOf("on") >= 0) {
digitalWrite(LED_PIN, HIGH);
client.publish(topicStatus.c_str(), "{\"led\":\"on\"}");
} else if (msg.indexOf("off") >= 0) {
digitalWrite(LED_PIN, LOW);
client.publish(topicStatus.c_str(), "{\"led\":\"off\"}");
}
}
// pode adicionar mais comandos aqui
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Conectando MQTT...");
String clientId = String("ESP32Client-") + String(random(0xffff), HEX);
if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
Serial.println("Conectado");
// subscribe
client.subscribe(topicCmd.c_str());
// publicar status inicial
client.publish(topicStatus.c_str(), "{\"status\":\"online\"}");
} else {
Serial.print("falha, rc=");
Serial.print(client.state());
Serial.println(" tentando novamente em 5s");
delay(5000);
}
}
}
String iso8601Time() {
timeClient.update();
unsigned long epoch = timeClient.getEpochTime();
// Converte epoch para string ISO (UTC)
char buf[30];
struct tm *ptm = gmtime((time_t*)&epoch);
sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ",
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
return String(buf);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
dht.begin();
setup_wifi();
timeClient.begin();
timeClient.update();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
float readLuminosityPercent() {
int raw = analogRead(LDR_PIN); // 0..4095
// em algumas placas ESP32 a resolução default é 12 bits (0..4095)
// Ajuste o mapeamento conforme seu divisor (LDR + 10k)
// Consideramos raw-> 0 (escuro) .. 4095 (claro)
float perc = ( (float)raw / 4095.0 ) * 100.0;
return perc;
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
setup_wifi();
}
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastPublish >= publishInterval) {
lastPublish = now;
float h = dht.readHumidity();
float t = dht.readTemperature(); // Celsius
float lum = readLuminosityPercent();
// verificar leitura válida
if (isnan(h) || isnan(t)) {
Serial.println("Falha ao ler DHT11!");
} else {
String timestamp = iso8601Time();
// montar json simples
String payload = "{";
payload += "\"temperature\":" + String(t,1) + ",";
payload += "\"humidity\":" + String(h,1) + ",";
payload += "\"luminosity\":" + String(lum,0) + ",";
payload += "\"timestamp\":\"" + timestamp + "\"";
payload += "}";
Serial.print("Publicando em ");
Serial.print(topicTelem);
Serial.print(" -> ");
Serial.println(payload);
client.publish(topicTelem.c_str(), payload.c_str());
}
}
}