/****************************************************
* IoT Weather Station – ESP32 (Wokwi Simulator)
* Autores: Roberto Armuelles y Sergio Rivera
* Funcional: DHT22 + Potenciómetro (presión) + POST
****************************************************/
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
// ---------------------------
// WiFi para Wokwi
// ---------------------------
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ---------------------------
// Backend
// ---------------------------
const char* serverUrl = "https://iot-weather.com/insert.php";
const char* deviceId = "wokwi_esp32_dht22_pot_01";
// ---------------------------
// DHT22 GPIO 15
// ---------------------------
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ---------------------------
// Presión simulada (potenciómetro GPIO 34)
// ---------------------------
#define PRESS_PIN 34 // ADC
int adcRaw = 0;
// Mapeo presión barométrica simulada
float mapPressure(int raw) {
return 990.0 + (raw / 4095.0) * (1030.0 - 990.0);
}
// ---------------------------
// Intervalos
// ---------------------------
const unsigned long SEND_INTERVAL_MS = 15000; // 15s
const unsigned long DEBUG_INTERVAL_MS = 5000; // 5s
unsigned long lastSend = 0;
unsigned long lastDebug = 0;
// ---------------------------
// Timestamp simbólico
// ---------------------------
String nowAsIso() {
unsigned long s = millis() / 1000;
return String("sim-") + s;
}
// ---------------------------
// Lecturas
// ---------------------------
bool readEnvironment(float &tOut, float &hOut, float &pOut) {
float h = dht.readHumidity();
float t = dht.readTemperature();
// Si falla → simulación suave
if (isnan(h) || isnan(t)) {
static float simT = 25.0;
static float simH = 60.0;
simT += random(-5, 6) * 0.05;
simH += random(-5, 6) * 0.05;
if (simT < 18) simT = 18;
if (simT > 34) simT = 34;
if (simH < 20) simH = 20;
if (simH > 90) simH = 90;
t = simT;
h = simH;
Serial.println("[WARN] DHT22 devolvió NaN → usando simulación.");
}
// Leer ADC para presión
adcRaw = analogRead(PRESS_PIN);
float pres = mapPressure(adcRaw);
tOut = t;
hOut = h;
pOut = pres;
return true;
}
// ---------------------------
// SETUP
// ---------------------------
void setup() {
delay(1500);
Serial.begin(115200);
delay(300);
Serial.println("\n=======================================");
Serial.println(" ESP32 – IoT Weather Station");
Serial.println(" (Wokwi Simulator)");
Serial.println("=======================================\n");
// --- DHT22 ---
Serial.println("[INFO] Iniciando sensor DHT22...");
dht.begin();
// --- WiFi ---
Serial.print("[INFO] Conectando a ");
Serial.print(ssid);
WiFi.begin(ssid, password, 6);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println(" conectado!");
Serial.print("[INFO] IP local: ");
Serial.println(WiFi.localIP());
lastSend = millis() - SEND_INTERVAL_MS;
lastDebug = millis();
}
// ---------------------------
// LOOP PRINCIPAL
// ---------------------------
void loop() {
unsigned long now = millis();
// ---------------------------
// Debug cada 5 segundos
// ---------------------------
if (now - lastDebug >= DEBUG_INTERVAL_MS) {
lastDebug = now;
Serial.print("[DEBUG] millis = ");
Serial.println(now);
}
// ---------------------------
// Envío cada 15s
// ---------------------------
if (now - lastSend >= SEND_INTERVAL_MS) {
lastSend = now;
// Reintentar WiFi si cae
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[WARN] WiFi desconectado → Reintentando...");
WiFi.disconnect();
WiFi.begin(ssid, password, 6);
unsigned long t0 = millis();
while (WiFi.status() != WL_CONNECTED && millis() - t0 < 8000) {
delay(200);
Serial.print(".");
}
Serial.println();
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[ERROR] No se pudo reconectar. Saltando envío.");
return;
}
Serial.println("[OK] Reconectado.");
}
float t, h, p;
if (!readEnvironment(t, h, p)) {
Serial.println("[ERROR] No se pudo leer sensores.");
return;
}
// --- LOG DE LECTURAS ---
Serial.println("\n>> Lecturas:");
Serial.printf(" Temp = %.2f °C\n", t);
Serial.printf(" Hum = %.2f %%\n", h);
Serial.printf(" Pres = %.2f hPa\n", p);
// --- Construir JSON ---
String payload = "{";
payload += "\"device_id\":\"wokwi_esp32_dht22_pot_01\",";
payload += "\"temperature_c\":" + String(t, 2) + ",";
payload += "\"humidity_pct\":" + String(h, 2) + ",";
payload += "\"pressure_hpa\":" + String(p, 2) + ",";
payload += "\"ts\":\"" + nowAsIso() + "\"";
payload += "}";
Serial.println(">> Enviando payload:");
Serial.println(payload);
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-DEVICE-ID", deviceId);
int httpCode = http.POST(payload);
String body = http.getString();
Serial.print("HTTP status: ");
Serial.println(httpCode);
if (httpCode < 0) {
Serial.print("HTTP error: ");
Serial.println(http.errorToString(httpCode));
}
Serial.print("Respuesta: ");
Serial.println(body);
Serial.println("---------------------------------------");
http.end();
}
delay(40);
}