Transforma el teu ESP32 en un servidor web que mostra les dades del DHT22 (o DHT11) al navegador de qualsevol dispositiu, inclòs el telèfon mòbil.
Un ESP32 pot funcionar com un petit servidor web que entrega pàgines HTML al navegador. Així, sense necessitat de pantalles ni cables, pots consultar la temperatura i humitat des de qualsevol dispositiu connectat a la mateixa xarxa Wi‑Fi (ordinador, tauleta, mòbil).
En aquesta guia aprendràs a:
| DHT | ESP32 |
|---|---|
| VCC | 3.3 V |
| DATA | GPIO 15 (o un altre GPIO lliure) |
| GND | GND |
Resistència pull‑up entre DATA i VCC si el mòdul no la té.
Si necessites recordar tots els detalls, consulta la nostra guia completa dels sensors DHT.
Perquè el navegador del mòbil pugui veure la pàgina, l’ESP32 ha d’estar connectat a la mateixa xarxa que el telèfon (o bé crear la seva pròpia xarxa, veure Mode AP).
#include <WiFi.h>
const char* ssid = "el_teu_ssid";
const char* password = "la_teva_contrasenya";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("Connectant a Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnectat!");
Serial.print("Adreça IP: ");
Serial.println(WiFi.localIP()); // Apunta aquesta IP
}
Fem servir la llibreria WebServer (inclosa en el paquet ESP32 per Arduino). El servidor escoltarà al port 80 i respondrà a les peticions HTTP.
#include <WebServer.h>
WebServer server(80); // Servidor al port HTTP estàndard
void setup() {
// ... connexió Wi-Fi ...
// Indiquem quina funció s'executa quan algú demana la pàgina principal "/"
server.on("/", handleRoot);
server.begin();
Serial.println("Servidor web iniciat");
}
void loop() {
server.handleClient(); // Escolta i respon les peticions entrants
}
void handleRoot() {
// Enviar una pàgina HTML simple
String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>";
html += "<title>ESP32 Web Server</title></head><body>";
html += "<h1>Hola des de l'ESP32!</h1>";
html += "</body></html>";
server.send(200, "text/html", html);
}
Ara combinem el DHT i el servidor. La funció handleRoot() llegeix el sensor i insereix els valors dins de l'HTML. Per evitar recàrregues manuals, afegim un petit script JavaScript que demana les dades actualitzades cada 2 segons (AJAX). Així el mòbil només ha de mostrar la pàgina un cop i les xifres es refresquen soles.
Crearem dues rutes:
/ → pàgina principal amb HTML + JavaScript./data → retorna les dades en format JSON (per a l'AJAX).
// dins de setup():
server.on("/", handleRoot);
server.on("/data", handleData);
// ...
void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DHT22 – ESP32</title>
<style>
body { font-family: Arial; text-align: center; margin-top: 2rem; }
.dada { font-size: 3rem; font-weight: bold; }
.unit { font-size: 1.5rem; color: #555; }
</style>
</head>
<body>
<h1>🌡️ Temperatura i Humitat</h1>
<div>
<span id="temp" class="dada">--</span>
<span class="unit">°C</span>
</div>
<div style="margin-top:1rem;">
<span id="hum" class="dada">--</span>
<span class="unit">% HR</span>
</div>
<script>
function actualitza() {
fetch('/data')
.then(r => r.json())
.then(d => {
document.getElementById('temp').innerText = d.temperatura;
document.getElementById('hum').innerText = d.humitat;
})
.catch(e => console.error(e));
}
setInterval(actualitza, 2500); // cada 2,5 segons
actualitza(); // primera càrrega immediata
</script>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}
void handleData() {
float t = dht.readTemperature();
float h = dht.readHumidity();
// Protecció si falla la lectura
if (isnan(t) || isnan(h)) {
server.send(500, "text/plain", "Error de lectura");
return;
}
String json = "{";
json += "\"temperatura\": " + String(t, 1) + ",";
json += "\"humitat\": " + String(h, 1);
json += "}";
server.send(200, "application/json", json);
}
A continuació tens el programa complet per copiar i enganxar a l’Arduino IDE. Inclou tot: Wi‑Fi, DHT, servidor web amb ruta JSON.
// Incloure llibreries necessàries
#include <WiFi.h>
#include <WebServer.h>
#include "DHT.h"
// Configuració Wi‑Fi – canvia pel teu SSID i contrasenya
const char* ssid = "EL_TEU_SSID";
const char* password = "LA_TEVA_CONTRASENYA";
// Configuració del DHT
#define DHTPIN 15 // GPIO on connectes el DATA
#define DHTTYPE DHT22 // O DHT11
DHT dht(DHTPIN, DHTTYPE);
// Servidor web al port 80
WebServer server(80);
// --------------------------------------------------
void setup() {
Serial.begin(115200);
delay(1000);
// Inicia el sensor
dht.begin();
// Connexió Wi‑Fi
WiFi.begin(ssid, password);
Serial.print("Connectant a Wi‑Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnectat!");
Serial.print("Adreça IP: ");
Serial.println(WiFi.localIP());
// Configura les rutes del servidor
server.on("/", handleRoot); // Pàgina principal
server.on("/data", handleData); // Dades en JSON
// Inicia el servidor
server.begin();
Serial.println("Servidor web en marxa!");
}
// --------------------------------------------------
void loop() {
server.handleClient(); // Atén les peticions dels navegadors
}
// --------------------------------------------------
// Pàgina HTML amb JavaScript per al refresc automàtic
void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DHT22 – ESP32</title>
<style>
body { font-family: Arial; text-align: center; margin-top: 2rem; }
.dada { font-size: 3rem; font-weight: bold; }
.unit { font-size: 1.5rem; color: #555; }
.error { color: red; }
</style>
</head>
<body>
<h1>🌡️ Temperatura i Humitat</h1>
<div>
<span id="temp" class="dada">--</span>
<span class="unit">°C</span>
</div>
<div style="margin-top:1rem;">
<span id="hum" class="dada">--</span>
<span class="unit">% HR</span>
</div>
<script>
function actualitza() {
fetch('/data')
.then(r => r.json())
.then(d => {
document.getElementById('temp').innerText = d.temperatura;
document.getElementById('hum').innerText = d.humitat;
})
.catch(e => {
document.getElementById('temp').innerText = 'Error';
document.getElementById('hum').innerText = '';
});
}
setInterval(actualitza, 2500);
actualitza();
</script>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}
// --------------------------------------------------
// Retorna les dades del sensor en format JSON
void handleData() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) {
server.send(500, "text/plain", "Error de lectura");
return;
}
String json = "{";
json += "\"temperatura\":" + String(t, 1) + ",";
json += "\"humitat\":" + String(h, 1);
json += "}";
server.send(200, "application/json", json);
}
EL_TEU_SSID i LA_TEVA_CONTRASENYA pels de la teva xarxa. Assegura't que el pin DHTPIN coincideix amb la teva connexió. Si fas servir DHT11, canvia DHTTYPE a DHT11.
Adreça IP: 192.168.x.x.http://192.168.1.42 (sense “http://” també funciona la majoria de navegadors).WiFi.config()) o reservar-la al router. En cas contrari, hauràs de consultar el monitor sèrie cada cop que es reiniciï l’ESP32.
Si no tens un router a prop, l’ESP32 pot crear la seva pròpia xarxa Wi‑Fi. El mòbil es connecta a aquesta xarxa i accedeix al servidor igualment. Només cal canviar unes línies al codi:
// Substitueix la part de connexió Wi‑Fi per això:
const char* ap_ssid = "ESP32_Sensor"; // Nom de la xarxa que veuràs al mòbil
const char* ap_password = "12345678"; // Almenys 8 caràcters
void setup() {
// ... inicialitza DHT ...
WiFi.softAP(ap_ssid, ap_password);
Serial.print("Punt d'accés creat. IP: ");
Serial.println(WiFi.softAPIP());
// ... resta del codi (server.on, server.begin) ...
}
Des del mòbil, busca la xarxa “ESP32_Sensor”, introdueix la contrasenya i després obre la IP que veus al monitor sèrie (normalment 192.168.4.1).
/data no respon. Comprova el monitor sèrie de l’ESP32 per detectar reinicis o excepcions.