
Sensore di temperatura ed umidità (DHT22)
Ho parlato in precedenti post dei sensori di temperatura ed umidità, nello specifico l’uso del diffusissimo DHT11. L’Arduino Sensor Kit li può usare entrambi, ma nel kit è presente il DHT22.

Caratteristiche tecniche del DHT22
Il DHT22 è un sensore digitale che integra:
- un elemento capacitivo per l’umidità relativa (RH),
- un sensore termico per la temperatura,
- un microcontrollore che invia i dati su un’unica linea (single-wire digitale, non analogica).
- Range tipici e specifiche:
- Temperatura: –40…+80 °C (risoluzione 0,1 °C, tip. ±0,5 °C),
- Umidità relativa: 0…100 % RH (risoluzione 0,1 % RH, tip. ±2 % RH, max ±5 %),
- Alimentazione: 3,3–5 V,
- Frequenza di campionamento: max 0,5 Hz (una misura ogni ~2 s).
Cos’è l’umidità relativa
L’umidità relativa (RH) indica quanta vapor d’acqua è presente nell’aria rispetto alla quantità massima che quell’aria potrebbe contenere alla stessa temperatura.
- 50 % RH = l’aria contiene metà del vapore “possibile” a quella temperatura.
- 100 % RH = saturazione (rischio di condensa).
Poiché la capacità dell’aria di trattenere vapore cresce con la temperatura, la RH dipende dalla temperatura: per questo i sensori come il DHT22 misurano entrambe le grandezze.
Mi è capitato spesso rispondere alla domanda: “ma Prof. cosa è meglio usare il DHT11 o il DHT22”
Se si dispone di entrambi certamente scegliere il DHT22 è da preferire, ma perché?
- Precisione e range migliori: DHT22 copre –40…+80 °C (vs 0…+50 °C del DHT11) con ±0,5 °C tipici; RH 0…100 % con ±2–5 % (DHT11 è meno preciso e più limitato).
- Risoluzione più fine: 0,1 °C / 0,1 % RH (utile per realizzare grafici e verificare trend).
Un vantaggio derivante dall’uso dell’Arduino Sensor Kit è che il DHT22 viene connesso all’Arduino mediante connessione I²C pertanto per il suo utilizzo è possibile collegarlo ad una delle uscite I²C presenti sulla Base Shield.

Veniamo ora agli esempi pratici, ne indico 6 di base, come sempre nei commenti la spiegazione. In classe ne realizzerò altri in cui mostreremo ad esempio la rilevazione della temperatura a media mobile a 10 campioni, attivazione di allarmi e ventole e molto altro.
Connessioni usate in questa lezione:
- Sensore di Temperatura ed Umidità: connesso ad una qualsiasi dei pin I²C della Base Shield.
- Display OLED: connesso ad una qualsiasi dei pin I²C della Base Shield.
- Diodo LED: connesso al D6.
Esempio 01: sensore ambiente – lettura base (temperatura – umidità)
/*
Prof. Maffucci Michele
01.10.2025
Sensore Ambiente – Lettura base (Temperatura + Umidità)
NOTE:
- DHT20 (I2C): decommenta la define Environment_I2C e abilita Wire.begin()
- DHT11 (pin D3 via Base Shield): commenta la define, la libreria gestisce il pin di default
*/
#include <Arduino_SensorKit.h>
// >>> Decommenta se il sensore è DHT20 (I2C) <<<
#define Environment Environment_I2C
void setup() {
Serial.begin(9600);
// Necessario per DHT20 (I2C); non influisce negativamente su DHT11
Wire.begin();
Environment.begin(); // inizializza il sensore ambiente (DHT11 o DHT20)
}
void loop() {
float temperaturaC = Environment.readTemperature(); // °C
float umiditaRH = Environment.readHumidity(); // %RH
// Stampa della temperatura e dell'umidità sulla Serial Monitor ogni secondo
Serial.print("Temperatura: ");
Serial.print(temperaturaC, 1);
Serial.print(" °C Umidità: ");
Serial.print(umiditaRH, 1);
Serial.println(" %");
delay(1000);
}
Esempio 02: Lettura Temperatura e Umidità con allarme su D6 (LED)
In questo esempio utilizziamo il diodo LED connesso al D6 come allarme, pertanto verrà acceso se la temperatura supera un valore di soglia impostato.
/*
Prof. Maffucci Michele
01.10.2025
Lettura Temperatura e Umidità con allarme su D6 (LED)
- Allarme: LED su D6 si accende se T > soglia.
- Messaggi su Serial Monitor: ALERT all'attivazione, DISATTIVATO allo spegnimento.
- DHT20 (I2C): lascia attiva la define Environment_I2C.
- DHT11: commenta la define sotto; la libreria gestisce il pin del Base Shield.
*/
#include "Arduino_SensorKit.h"
#define Environment Environment_I2C
// Configurazione allarme
const int pinLedAllarme = 6; // LED collegato al pin D6
const float sogliaTemperaturaC = 25.0; // soglia in °C
bool allarmeAttivo = false; // stato attuale dell'allarme
void setup() {
Serial.begin(9600);
// Necessario per DHT20 e per eventuali altre periferiche I2C (OLED, ecc.)
Wire.begin();
// Inizializza il sensore ambiente (DHT11 o DHT20 a seconda della define)
Environment.begin();
// LED di allarme
pinMode(pinLedAllarme, OUTPUT);
digitalWrite(pinLedAllarme, LOW);
Serial.println("== Avvio lettura Temperatura & Umidita' con allarme su D6 ==");
Serial.print("Soglia T = ");
Serial.print(sogliaTemperaturaC, 1);
Serial.println(" C");
}
void loop() {
// Letture dal sensore
float temperaturaC = Environment.readTemperature(); // °C
float umiditaRH = Environment.readHumidity(); // %RH
// --- Gestione allarme con isteresi ---
// Usiamo DUE soglie diverse per evitare ON/OFF continui vicino al limite.
// - Soglia di ACCENSIONE (T_on): temperaturaC > sogliaTemperaturaC
// - Soglia di SPEGNIMENTO (T_off): temperaturaC < sogliaTemperaturaC // Finché T resta tra T_off e T_on, manteniamo lo stato attuale (nessun cambiamento). if (!allarmeAttivo && temperaturaC > sogliaTemperaturaC) {
// Caso 1: l'allarme è attualmente OFF e la temperatura SUPERA la soglia di ACCENSIONE.
// Accendiamo l'allarme (LED ON) e stampiamo un messaggio di ALERT.
allarmeAttivo = true;
digitalWrite(pinLedAllarme, HIGH);
Serial.print("!!! ALERT: Temperatura sopra soglia: ");
Serial.print(temperaturaC, 1);
Serial.println(" C");
} else if (allarmeAttivo && temperaturaC < sogliaTemperaturaC) { // Caso 2: l'allarme è attualmente ON e la temperatura SCENDE sotto la soglia di SPEGNIMENTO // Spegniamo l'allarme (LED OFF) e informiamo che è rientrato. allarmeAttivo = false; digitalWrite(pinLedAllarme, LOW); Serial.print("Allarme DISATTIVATO: Temperatura rientrata: "); Serial.print(temperaturaC, 1); Serial.println(" C"); } // Nota sui casi limite: // - Se temperaturaC == sogliaTemperaturaC, NON si accende (serve ">" strettamente).
// - Se temperaturaC == (sogliaTemperaturaC, NON si spegne (serve "<" strettamente).
// Stampa della temperatura e dell'umidità sulla Serial Monitor
Serial.print("T=");
Serial.print(temperaturaC, 1);
Serial.print(" C RH=");
Serial.print(umiditaRH, 1);
Serial.print(" % ALLARME=");
if (allarmeAttivo) {
Serial.println("ON");
} else {
Serial.println("OFF");
}
delay(1000);
}
Esempio 03: Lettura Temperatura e Umidità con allarme su D6 (LED) con isteresi
Premessa
In elettronica, isteresi è la presenza di due soglie diverse per il passaggio tra due stati, così l’uscita dipende non solo dal valore istantaneo dell’ingresso, ma anche dalla sua storia. Serve a evitare commutazioni rapide e instabili quando il segnale oscilla vicino a una soglia.
Come nell’esempio precedente utilizziamo il diodo LED connesso al D6 come allarme, inoltre useremo l’isteresi per evitare che il LED “sfarfalli” (ON/OFF ripetuti) quando la temperatura oscilla vicino alla soglia a causa di rumore o piccole variazioni.
Nello sketch che segue l’isteresi funziona in questo modo:
- Soglia di attivazione: sogliaTemperaturaC = 26.0 °C
L’allarme si accende appena T > 26.0 °C. - Isteresi: isteresiC = 0.5 °C
L’allarme si spegne solo quando T < 26.0 − 0.5 = 25.5 °C.
Quindi usi due soglie:
- T_on = 26.0 °C (accendo quando la supero)
- T_off = 25.5 °C (spengo solo quando scendo sotto)
Senza isteresi, se la temperatura è nell’intorno di intorno a 26 °C (es. 25.9 ↔ 26.1 per il rumore), l’allarme continuerebbe ad accendersi e spegnersi rapidamente. Con l’isteresi, una volta acceso, resta acceso finché non rientra ben al di sotto della soglia, evitando lampeggi/ronzii fastidiosi e messaggi “ALERT” ripetuti.
Quindi come regola generale per i sensori DHT che utilizziamo in laboratorio valori tra 0,3 e 1°C sono di solito sufficienti. Se è presente ancora sfarfallio, aumentare leggermente; se la risposta è troppo lenta a spegnersi, ridurre.
Come schema logico si tenga in conto:
- Se allarme OFF e T > T_on → accendere
- Se allarme ON e T < T_off → spegnere
- Altrimenti mantenere lo stato corrente
È la stessa logica usata nei termostati: due soglie (accensione/spegnimento) invece di una sola, per ottenere un comportamento stabile.
/*
Prof. Maffucci Michele
01.10.2025
Lettura Temperatura e Umidità con allarme su D6 (LED) con isteresi
- Allarme: LED su D6 si accende se T > soglia.
- Messaggi su Serial Monitor: ALERT all'attivazione, DISATTIVATO allo spegnimento.
- DHT20 (I2C): lascia attiva la define Environment_I2C.
- DHT11: commenta la define sotto; la libreria gestisce il pin del Base Shield.
*/
#include <Arduino_SensorKit.h>
#define Environment Environment_I2C
// Configurazione allarme
const int pinLedAllarme = 6; // LED collegato al pin D6
const float sogliaTemperaturaC = 25.0; // soglia in °C
const float isteresiC = 0.5; // isteresi per evitare lampeggi (spegnimento sotto soglia - isteresi)
bool allarmeAttivo = false; // stato attuale dell'allarme
void setup() {
Serial.begin(9600);
// Necessario per DHT20 e per eventuali altre periferiche I2C (OLED, ecc.)
Wire.begin();
// Inizializza il sensore ambiente (DHT11 o DHT20 a seconda della define)
Environment.begin();
// LED di allarme
pinMode(pinLedAllarme, OUTPUT);
digitalWrite(pinLedAllarme, LOW);
Serial.println("== Avvio lettura Temperatura & Umidita' con allarme su D6 ==");
Serial.print("Soglia T = ");
Serial.print(sogliaTemperaturaC, 1);
Serial.println(" C");
}
void loop() {
// Letture dal sensore
float temperaturaC = Environment.readTemperature(); // °C
float umiditaRH = Environment.readHumidity(); // %RH
// --- Gestione allarme con isteresi ---
// Usiamo DUE soglie diverse per evitare ON/OFF continui vicino al limite.
// - Soglia di ACCENSIONE (T_on): temperaturaC > sogliaTemperaturaC
// - Soglia di SPEGNIMENTO (T_off): temperaturaC < (sogliaTemperaturaC - isteresiC) // Finché T resta tra T_off e T_on, manteniamo lo stato attuale (nessun cambiamento). if (!allarmeAttivo && temperaturaC > sogliaTemperaturaC) {
// Caso 1: l'allarme è attualmente OFF e la temperatura SUPERA la soglia di ACCENSIONE.
// Accendiamo l'allarme (LED ON) e stampiamo un messaggio di ALERT.
allarmeAttivo = true;
digitalWrite(pinLedAllarme, HIGH);
Serial.print("!!! ALERT: Temperatura sopra soglia: ");
Serial.print(temperaturaC, 1);
Serial.println(" C");
} else if (allarmeAttivo && temperaturaC < (sogliaTemperaturaC - isteresiC)) { // Caso 2: l'allarme è attualmente ON e la temperatura SCENDE sotto la soglia di SPEGNIMENTO // (cioè sotto la soglia di accensione meno l'isteresi). // Spegniamo l'allarme (LED OFF) e informiamo che è rientrato. allarmeAttivo = false; digitalWrite(pinLedAllarme, LOW); Serial.print("Allarme DISATTIVATO: Temperatura rientrata: "); Serial.print(temperaturaC, 1); Serial.println(" C"); } // Nota sui casi limite: // - Se temperaturaC == sogliaTemperaturaC, NON si accende (serve ">" strettamente).
// - Se temperaturaC == (sogliaTemperaturaC - isteresiC), NON si spegne (serve "<" strettamente).
// Questo evita cambi di stato ripetuti quando il valore oscilla esattamente sulla soglia.
// Stampa della temperatura e dell'umidità sulla Serial Monitor
Serial.print("T=");
Serial.print(temperaturaC, 1);
Serial.print(" C RH=");
Serial.print(umiditaRH, 1);
Serial.print(" % ALLARME=");
if (allarmeAttivo) {
Serial.println("ON");
} else {
Serial.println("OFF");
}
delay(1000);
}
Esempio 04: Lettura Temperatura e Umidità con stampa su OLED e Serial Monitor
Abbiamo visto nella precedente lezione l’uso del display OLED dell’Arduino Sensor Kit, utilizziamolo ora per mostrare temperatura ed umidità che stamperemo anche sulla Serial Monitor.
/*
Prof. Maffucci Michele
01.10.2025
Lettura Temperatura e Umidità con stampa su OLED e Serial Monitor
- DHT20 (I2C): lascia attiva la define Environment_I2C.
- DHT11: commenta la define sotto; la libreria gestisce il pin del Base Shield.
*/
#include <Arduino_SensorKit.h>
#define Environment Environment_I2C
void setup() {
Serial.begin(9600);
Wire.begin(); // necessario con DHT20/OLED su I2C
Environment.begin(); // DHT11 o DHT20 (in base alla define)
Oled.begin(); // inizializza OLED
// Orientamento e font leggibile
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
// Pulisci UNA volta all’avvio
Oled.clearDisplay();
// Etichette fisse (non cambiano > non serve riscriverle)
Oled.setCursor(0, 2);
Oled.print("T=");
Oled.setCursor(0, 4);
Oled.print("RH=");
}
void loop() {
float tC = Environment.readTemperature(); // °C
float rH = Environment.readHumidity(); // %RH
// --Stampa su OLED
// Sovrascrivo soltanto il campo variabile, SENZA clearDisplay
Oled.setCursor(2, 2); // subito dopo "T="
Oled.print(tC);
Oled.setCursor(3, 4); // subito dopo "RH="
Oled.print(rH);
// --Stampa su seriale
Serial.print("T=");
Serial.print(tC);
Serial.print(" C RH=");
Serial.print(rH);
Serial.println(" %");
delay(500); // aggiorna 2 volte al secondo (meno sfarfallio)
}
Esempio 05: Lettura Temperatura e Umidità con stampa su OLED e Serial Monitor ed accensione LED con isteresi
Aggiungiamo alla versione precedente l’allarme dato con il LED.
/*
Prof. Maffucci Michele
01.10.2025
Lettura Temperatura e Umidità con stampa su OLED e Serial Monitor
ed accensione LED con isteresi
- DHT20 (I2C): lascia attiva la define Environment_I2C.
- DHT11: commenta la define sotto; la libreria gestisce il pin del Base Shield.
*/
#include <Arduino_SensorKit.h>
#define Environment Environment_I2C
// Configurazione allarme
const int pinLedAllarme = 6; // LED collegato al pin D6
const float sogliaTemperaturaC = 25.0; // soglia in °C
const float isteresiC = 0.5; // isteresi per evitare lampeggi (spegnimento sotto soglia - isteresi)
bool allarmeAttivo = false; // stato attuale dell'allarme
void setup() {
Serial.begin(9600);
Wire.begin(); // necessario con DHT20/OLED su I2C
Environment.begin(); // DHT11 o DHT20 (in base alla define)
Oled.begin(); // inizializza OLED
// Orientamento e font leggibile
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
// Pulisci UNA volta all’avvio
Oled.clearDisplay();
// Etichette fisse (non cambiano → non serve riscriverle)
Oled.setCursor(0, 2);
Oled.print("T=");
Oled.setCursor(0, 4);
Oled.print("RH=");
pinMode(pinLedAllarme, OUTPUT);
digitalWrite(pinLedAllarme, LOW);
Serial.println("== Avvio lettura Temperatura & Umidita' con allarme su D6 ==");
Serial.print("Soglia T = ");
Serial.print(sogliaTemperaturaC, 1);
Serial.println(" C");
}
void loop() {
float tC = Environment.readTemperature(); // °C
float rH = Environment.readHumidity(); // %RH
// --- Gestione allarme con isteresi ---
// Usiamo DUE soglie diverse per evitare ON/OFF continui vicino al limite.
// - Soglia di ACCENSIONE (T_on): temperaturaC > sogliaTemperaturaC
// - Soglia di SPEGNIMENTO (T_off): temperaturaC < (sogliaTemperaturaC - isteresiC) // Finché T resta tra T_off e T_on, manteniamo lo stato attuale (nessun cambiamento). if (!allarmeAttivo && tC > sogliaTemperaturaC) {
// Caso 1: l'allarme è attualmente OFF e la temperatura SUPERA la soglia di ACCENSIONE.
// Accendiamo l'allarme (LED ON) e stampiamo un messaggio di ALERT.
allarmeAttivo = true;
digitalWrite(pinLedAllarme, HIGH);
Serial.print("!!! ALERT: Temperatura sopra soglia: ");
Serial.print(tC, 1);
Serial.println(" C");
} else if (allarmeAttivo && tC < (sogliaTemperaturaC - isteresiC)) {
// Caso 2: l'allarme è attualmente ON e la temperatura SCENDE sotto la soglia di SPEGNIMENTO
// (cioè sotto la soglia di accensione meno l'isteresi).
// Spegniamo l'allarme (LED OFF) e informiamo che è rientrato.
allarmeAttivo = false;
digitalWrite(pinLedAllarme, LOW);
Serial.print("Allarme DISATTIVATO: Temperatura rientrata: ");
Serial.print(tC, 1);
Serial.println(" C");
}
// -- Stampa su OLED --
// Sovrascrivo soltanto il campo variabile, SENZA clearDisplay
Oled.setCursor(2, 2); // subito dopo "T="
Oled.print(tC);
Oled.setCursor(3, 4); // subito dopo "RH="
Oled.print(rH);
// -- Stampa su seriale --
Serial.print("T=");
Serial.print(tC);
Serial.print(" C RH=");
Serial.print(rH);
Serial.println(" %");
delay(500); // aggiorna 2 volte al secondo (meno sfarfallio)
}
Esempio 06: lettura Temperatura & Umidità con stampa su OLED e Serial Monitor ed accensione LED – su OLED viene mostrato allarme
Aggiungiamo allo sketch precedente la visualizzazione del messaggio di alert sul display. Per semplicità di lettura ho tolto i commenti nella sezione: “Gestione allarme con isteresi”, lasciando solo quelli che si riferiscono alla stampa dell’alert sul display.
/*
Prof. Maffucci Michele
01.10.2025
Lettura Temperatura & Umidità con stampa su OLED e Serial Monitor
ed accensione LED - su OLED viene mostrato allarme
- DHT20 (I2C): lascia attiva la define Environment_I2C.
- DHT11: commenta la define sotto; la libreria gestisce il pin del Base Shield.
*/
#include <Arduino_SensorKit.h>
#define Environment Environment_I2C
// Configurazione allarme
const int pinLedAllarme = 6; // LED collegato al pin D6
const float sogliaTemperaturaC = 25.0; // soglia in °C
const float isteresiC = 0.5; // isteresi per evitare lampeggi (spegnimento sotto soglia - isteresi)
bool allarmeAttivo = false; // stato attuale dell'allarme
void setup() {
Serial.begin(9600);
Wire.begin(); // necessario con DHT20/OLED su I2C
Environment.begin(); // DHT11 o DHT20 (in base alla define)
Oled.begin(); // inizializza OLED
// Orientamento e font leggibile
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
// Pulisci UNA volta all’avvio
Oled.clearDisplay();
// Etichette fisse (non cambiano → non serve riscriverle)
Oled.setCursor(0, 2);
Oled.print("T=");
Oled.setCursor(0, 4);
Oled.print("RH=");
pinMode(pinLedAllarme, OUTPUT);
digitalWrite(pinLedAllarme, LOW);
Serial.println("== Avvio lettura Temperatura & Umidita' con allarme su D6 ==");
Serial.print("Soglia T = ");
Serial.print(sogliaTemperaturaC, 1);
Serial.println(" C");
}
void loop() {
float tC = Environment.readTemperature(); // °C
float rH = Environment.readHumidity(); // %RH
// --- Gestione allarme con isteresi ---
if (!allarmeAttivo && tC > sogliaTemperaturaC) {
allarmeAttivo = true;
digitalWrite(pinLedAllarme, HIGH);
// cursore nell'angolo in alto a destra
Oled.setCursor(0, 0);
// stampa del messaggio di alert
Oled.print("ALERT: t>tMax");
Serial.print("!!! ALERT: Temperatura sopra soglia: ");
Serial.print(tC, 1);
Serial.println(" C");
} else if (allarmeAttivo && tC < (sogliaTemperaturaC - isteresiC)) {
allarmeAttivo = false;
digitalWrite(pinLedAllarme, LOW);
// cursore nell'angolo in alto a destra
Oled.setCursor(0, 0);
// cancellazione con spazi del messaggio di alert
Oled.print(" ");
Serial.print("Allarme DISATTIVATO: Temperatura rientrata: ");
Serial.print(tC, 1);
Serial.println(" C");
}
// -- Stampa su OLED --
// Sovrascrivo soltanto il campo variabile, SENZA clearDisplay
Oled.setCursor(2, 2); // subito dopo "T="
Oled.print(tC);
Oled.setCursor(3, 4); // subito dopo "RH="
Oled.print(rH);
// -- Stampa su seriale --
Serial.print("T=");
Serial.print(tC);
Serial.print(" C RH=");
Serial.print(rH);
Serial.println(" %");
delay(500); // aggiorna 2 volte al secondo (meno sfarfallio)
}
Buon Coding a tutti 🙂






















