🌡️ Guia Didàctica: DHT11 i DHT22 amb ESP32 (S3, Nano, XIAO) — Arduino IDE

Coneix els sensors de temperatura i humitat DHT11/DHT22, com connectar‑los correctament a un ESP32 i com programar‑los amb explicacions pas a pas.

📑 Continguts

1. Introducció als sensors DHT

Els sensors DHT11 i DHT22 (també anomenats AM2302) mesuren temperatura i humitat relativa. Utilitzen un protocol digital d’un sol fil (one‑wire) propi, no compatible amb 1‑Wire de Dallas. Les diferències principals:

DHT11
DHT22 / AM2302

Tots dos requereixen una resistència pull‑up externa al pin de dades (excepte si el mòdul breakout ja la porta). A la secció següent veuràs el perquè.

2. Material i connexions

🛠️ Material necessari
📌 Assignació de pins (mòdul de 3 pins)
Pin DHTConnecta a
VCC (+)3.3 V de l’ESP32 (evita 5 V)
DATA (out)Qualsevol GPIO disponible, p. ex. GPIO 4, 15, 16
GND (-)GND de l’ESP32

Esquema de connexions (sense mòdul breakout)

ESP32 3.3V ----+----[ R 4.7k~10k ]----+---- GPIO (ex. 4) | | DHT22 VCC DHT22 DATA | | GND ------------------- DHT22 GND

Si utilitzes un mòdul que ja inclou la resistència a la PCB, connecta directament VCC, GND i DATA als pins de l’ESP32.

⚠️ Per què 3.3 V i no 5 V?
L’ESP32 funciona amb lògica de 3.3 V. Tot i que els DHT11/DHT22 poden tolerar 5 V d’alimentació, el seu pin de dades retornarà un nivell proper al de la tensió d’alimentació. Fer servir 5 V podria danyar els GPIO de l’ESP32 o provocar comunicacions erràtiques. Alimenta’ls sempre amb 3.3 V per seguretat i compatibilitat.

3. Per què necessitem una resistència pull‑up?

El protocol del DHT funciona deixant el pin de dades en estat alt (HIGH) per defecte. Quan el microcontrolador o el sensor volen iniciar comunicació, estiren la línia cap a baix (LOW). Sense una resistència que mantingui la línia en HIGH quan ningú l’activa, la tensió quedaria flotant i es produirien lectures erràtiques o fallades totals.

Per tant:

4. Instal·lació de llibreries a Arduino IDE

Per treballar amb el DHT necessites dues llibreries que gestionen el protocol i les lectures. Instal·la‑les des del Library Manager (menú Eines → Gestiona les llibreries):

  1. Busca i instal·la “Adafruit Unified Sensor” (proporciona tipus de dades comuns per a sensors).
  2. Busca i instal·la “DHT sensor library” d’Adafruit (conté la classe DHT).
Si al compilar apareix fatal error: Adafruit_Sensor.h: No such file or directory, assegura’t d’haver instal·lat primer la llibreria Adafruit Unified Sensor.

5. Codi complet explicat pas a pas

Utilitzarem el DHT22 per la seva millor precisió. El codi val tant per ESP32‑S3 com per ESP32 Nano; només cal canviar el número de pin.

5.1 Versió senzilla (amb delay())


// 1. Incloure la llibreria
#include "DHT.h"

// 2. Definir pin i tipus de sensor
#define DHTPIN 15        // GPIO on connectes el DATA
#define DHTTYPE DHT22    // O DHT11 si fas servir el model bàsic

// 3. Crear l'objecte DHT
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);   // Inicialitza comunicació sèrie
  delay(1000);            // Petita pausa per estabilitzar l'alimentació
  dht.begin();            // Inicialitza el sensor
  Serial.println("DHT22 inicialitzat. Començant lectures...");
}

void loop() {
  // 4. Llegir humitat i temperatura
  float humitat = dht.readHumidity();
  float temperatura = dht.readTemperature();  // Per defecte en Celsius

  // 5. Comprovar si la lectura ha fallat (retorna NaN)
  if (isnan(humitat) || isnan(temperatura)) {
    Serial.println("Error: no s'ha pogut llegir el DHT. Revisa les connexions.");
    delay(2500);
    return;               // Sortir d'aquesta iteració
  }

  // 6. Mostrar resultats
  Serial.print("Humitat: ");
  Serial.print(humitat);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(temperatura);
  Serial.println(" °C");

  // 7. Esperar el temps mínim entre lectures (DHT22 ≈ 2 s)
  delay(2500);
}
Comentari didàctic: La funció readTemperature() retorna la temperatura en graus Celsius. Si vols Fahrenheit, fes servir dht.readTemperature(true).

5.2 Versió no bloquejant (amb millis()) – recomanada per a projectes reals

Fer servir delay() atura completament el microcontrolador durant segons. Això impedeix, per exemple, actualitzar una pantalla o respondre a botons. Aquí tens una versió que respecta l’interval mínim sense bloquejar el bucle.


#include "DHT.h"

#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

unsigned long ultimLectura = 0;          // quan vam fer l'última lectura
const unsigned long interval = 2500;     // 2500 ms = 2.5 segons (marge extra)

void setup() {
  Serial.begin(115200);
  delay(1000);
  dht.begin();
}

void loop() {
  // Obtenim el "temps actual" en mil·lisegons
  unsigned long ara = millis();

  // Si ha passat prou temps des de l'última lectura, fem una de nova
  if (ara - ultimLectura >= interval) {
    ultimLectura = ara;   // actualitzem el marcador de temps

    float h = dht.readHumidity();
    float t = dht.readTemperature();

    if (isnan(h) || isnan(t)) {
      Serial.println("Error de lectura");
    } else {
      Serial.print("Humitat: ");
      Serial.print(h);
      Serial.print(" %\tTemperatura: ");
      Serial.print(t);
      Serial.println(" °C");
    }
    // No fem delay; el programa segueix executant-se
  }

  // Aquí pots posar altres tasques (llegir botons, actualitzar un display…)
  // …
}

6. Eina ràpida de diagnòstic

Si no obtens lectures, prova aquest esbós de diagnòstic que també verifica la presència del sensor:


#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  delay(1000);
  dht.begin();
  Serial.println("--- Test DHT ---");
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Lectura: ");
  Serial.print(millis());
  Serial.print(" ms -> ");
  if (isnan(h) || isnan(t)) {
    Serial.println("ERROR - Comprova cablejat, pull-up i voltatge.");
    delay(3000);
  } else {
    Serial.print("H=");
    Serial.print(h);
    Serial.print("%, T=");
    Serial.print(t);
    Serial.println("°C");
    delay(2500);
  }
}

Si el missatge d’error apareix immediatament al cap d’un segon, probablement el sensor no es comunica. Revisa la resistència, els cables i l’alimentació.

7. Problemes comuns i com resoldre’ls

🔴 “Failed to read from DHT sensor” o valors NaN
🟡 Lectures erràtiques o valors fora de rang

8. Notes per a ESP32‑S3 i ESP32 Nano

Les connexions i el codi són pràcticament idèntics en ambdues famílies. Tot i això:

Per a una referència ràpida dels pins recomanats, visita la guia de pinout ESP32 de Random Nerd Tutorials.

9. Notes per a ESP32 XIAO

Les plaques Seeed Studio XIAO ESP32C3 i XIAO ESP32S3 són de les més compactes del mercat. Tot i la seva mida, treballen perfectament amb els sensors DHT, sempre que es tinguin en compte unes poques particularitats.

Pinout segur per al DHT

XIAO ESP32C3

Evita el pin D7 (GPIO9) ja que és un pin de strapping (boot) i pot impedir l’arrencada si té algun nivell imposat.

XIAO ESP32S3

Comprova sempre la serigrafia de la teva placa. A la XIAO ESP32S3, el GPIO0 pot funcionar sense problemes sempre que no tingui una resistència de pull‑up o pull‑down externa que alteri el mode d’arrencada.

Esquema de connexions (exemple XIAO ESP32C3)

XIAO C3 3V3 ----+----[ R 4.7k~10k ]----+---- D2 (GPIO4) | | DHT22 VCC DHT22 DATA | | GND ------------------- DHT22 GND
💡 Consells per a la XIAO

Exemple de codi per a XIAO ESP32C3 (pin D2)


// Codi per a Seeed XIAO ESP32C3 amb DHT22 a D2 (GPIO4)
#include "DHT.h"

#define DHTPIN D2       // D2 = GPIO4 en XIAO ESP32C3
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  delay(1000);
  dht.begin();
  Serial.println("XIAO + DHT22 en marxa");
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    Serial.println("Error de lectura");
  } else {
    Serial.print("Humitat: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperatura: ");
    Serial.print(t);
    Serial.println(" °C");
  }
  delay(2500);
}

Per a la XIAO ESP32S3, defineix el pin com D0, D2 o D4 segons on hagis connectat el DATA, i recorda que els GPIOs són directament els números impresos (per exemple, #define DHTPIN D2).

10. Recursos i referències