🚀 Introduzione
Vuoi creare un monitor ambientale capace di mostrare molte più informazioni rispetto a un semplice termometro digitale? 🌡️💧
In questo progetto realizzerai un display avanzato per temperatura e umidità utilizzando Arduino, un sensore DHT22 e un display OLED SSD1306.
Oltre ai valori attuali, Arduino calcolerà la temperatura percepita, registrerà i valori minimi e massimi e mostrerà una valutazione dello stato dell’ambiente.
👉 Il risultato sarà una piccola centralina ambientale compatta, ideale per casa, ufficio, serra o laboratorio.
Vuoi creare un monitor ambientale capace di mostrare molte più informazioni rispetto a un semplice termometro digitale? 🌡️💧
In questo progetto realizzerai un display avanzato per temperatura e umidità utilizzando Arduino, un sensore DHT22 e un display OLED SSD1306.
Oltre ai valori attuali, Arduino calcolerà la temperatura percepita, registrerà i valori minimi e massimi e mostrerà una valutazione dello stato dell’ambiente.
👉 Il risultato sarà una piccola centralina ambientale compatta, ideale per casa, ufficio, serra o laboratorio.
🎯 Cosa realizzerai
Con Arduino creerai un sistema che:
Con Arduino creerai un sistema che:
- 🌡️ misura la temperatura ambientale
- 💧 misura l’umidità relativa
- ☀️ calcola la temperatura percepita
- 📉 memorizza i valori minimi
- 📈 memorizza i valori massimi
- 😊 valuta il comfort ambientale
- 📟 alterna automaticamente più schermate
- 🔘 permette di cambiare schermata manualmente
- 🔄 aggiorna i dati senza bloccare il programma
- ⚠️ segnala eventuali errori del sensore
🧰 Materiale necessario
Il DHT22 offre una precisione e un intervallo di misurazione superiori rispetto al DHT11.
Il pulsante utilizza la resistenza interna INPUT_PULLUP di Arduino, quindi non necessita di una resistenza esterna.
- 1x Arduino UNO
- 1x sensore DHT22
- 1x resistenza da 10kΩ, se utilizzi il sensore senza modulo
- 1x display OLED 0,96 pollici I2C SSD1306
- 1x pulsante
- cavetti jumper
- breadboard
- cavo USB
Il DHT22 offre una precisione e un intervallo di misurazione superiori rispetto al DHT11.
Il pulsante utilizza la resistenza interna INPUT_PULLUP di Arduino, quindi non necessita di una resistenza esterna.
🛒 Non hai ancora i componenti?
Molti dei progetti presenti su progettiarduino.com utilizzano componenti elettronici di base come LED, resistenze, sensori e breadboard.
Se stai iniziando con Arduino, il modo più semplice è utilizzare un kit completo per principianti, che include quasi tutti i componenti necessari per realizzare molti dei progetti presenti sul sito.
👉 Kit Arduino consigliato:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4b3dxjW
📘 Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti più completi, puoi dare un'occhiata anche ai miei libri dedicati ad Arduino.
All'interno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.
👉 Scopri i miei libri su Arduino:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4rfzjXE
Molti dei progetti presenti su progettiarduino.com utilizzano componenti elettronici di base come LED, resistenze, sensori e breadboard.
Se stai iniziando con Arduino, il modo più semplice è utilizzare un kit completo per principianti, che include quasi tutti i componenti necessari per realizzare molti dei progetti presenti sul sito.
👉 Kit Arduino consigliato:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4b3dxjW
📘 Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti più completi, puoi dare un'occhiata anche ai miei libri dedicati ad Arduino.
All'interno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.
👉 Scopri i miei libri su Arduino:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4rfzjXE
📚 Librerie necessarie
Per realizzare il progetto devi installare:
Per installarle:
Per realizzare il progetto devi installare:
- Adafruit SSD1306
- Adafruit GFX Library
- DHT sensor library
- Adafruit Unified Sensor
Per installarle:
- apri Arduino IDE;
- vai su Sketch → Include Library → Manage Libraries;
- cerca Adafruit SSD1306;
- installa la libreria;
- cerca Adafruit GFX Library;
- installa la libreria;
- cerca DHT sensor library;
- installa la versione sviluppata da Adafruit;
- installa anche Adafruit Unified Sensor quando richiesto.
🔌 Schema di collegamento
Display OLED SSD1306
Sensore DHT22
Se utilizzi un modulo DHT22 già assemblato:
Pulsante cambio schermata
Display OLED SSD1306
- VCC → 5V
- GND → GND
- SDA → A4
- SCL → A5
Sensore DHT22
Se utilizzi un modulo DHT22 già assemblato:
- VCC → 5V
- GND → GND
- DATA → pin digitale 2
- pin 1 VCC → 5V
- pin 2 DATA → pin digitale 2
- pin 3 → non collegato
- pin 4 GND → GND
- resistenza da 10kΩ tra DATA e 5V
Pulsante cambio schermata
- un terminale → pin digitale 3
- terminale opposto → GND
- pulsante non premuto → HIGH
- pulsante premuto → LOW
💻 Codice Arduino
Il programma visualizza tre schermate differenti.
Schermata principale
Mostra:
Schermata valori minimi e massimi
Mostra:
Schermata temperatura percepita
Mostra:
Il programma visualizza tre schermate differenti.
Schermata principale
Mostra:
- temperatura attuale;
- umidità attuale;
- valutazione del comfort.
Schermata valori minimi e massimi
Mostra:
- temperatura minima;
- temperatura massima;
- umidità minima;
- umidità massima.
Schermata temperatura percepita
Mostra:
- temperatura reale;
- temperatura percepita;
- stato generale dell’ambiente.
/*
============================================================
Progetto 129 - Display temperatura e umidita avanzato
Mostra valori attuali, percepiti, minimi, massimi e comfort
============================================================
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// Dimensioni e indirizzo del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1
#define INDIRIZZO_OLED 0x3C
// Configurazione del sensore DHT22
#define PIN_DHT 2
#define TIPO_DHT DHT22
// Pulsante per cambiare manualmente schermata
#define PIN_PULSANTE 3
// Intervalli di aggiornamento
const unsigned long INTERVALLO_LETTURA = 2000;
const unsigned long INTERVALLO_SCHERMATA = 5000;
const unsigned long TEMPO_DEBOUNCE = 180;
// Soglie indicative per il comfort ambientale
const float TEMPERATURA_MIN_COMFORT = 20.0;
const float TEMPERATURA_MAX_COMFORT = 26.0;
const float UMIDITA_MIN_COMFORT = 40.0;
const float UMIDITA_MAX_COMFORT = 60.0;
// Oggetti utilizzati per display e sensore
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
DHT dht(PIN_DHT, TIPO_DHT);
// Valori ambientali correnti
float temperatura = 0.0;
float umidita = 0.0;
float temperaturaPercepita = 0.0;
// Valori minimi e massimi registrati
float temperaturaMinima = 0.0;
float temperaturaMassima = 0.0;
float umiditaMinima = 0.0;
float umiditaMassima = 0.0;
// Stato del sensore e dello storico
bool sensoreValido = false;
bool storicoInizializzato = false;
// Identifica la schermata attualmente visualizzata
byte schermataAttuale = 0;
const byte NUMERO_SCHERMATE = 3;
// Variabili temporali utilizzate da millis()
unsigned long ultimaLettura = 0;
unsigned long ultimoCambioSchermata = 0;
unsigned long ultimaPressione = 0;
void setup() {
// Il pulsante è collegato tra il pin e GND.
// La resistenza interna mantiene stabile l'ingresso.
pinMode(PIN_PULSANTE, INPUT_PULLUP);
// Avvia il sensore DHT22
dht.begin();
// Inizializza il display OLED
if (!display.begin(
SSD1306_SWITCHCAPVCC,
INDIRIZZO_OLED
)) {
// Se il display non viene rilevato,
// il programma rimane bloccato.
while (true) {
}
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
// Mostra una breve schermata iniziale
mostraAvvio();
// Esegue subito una prima lettura
leggiSensore();
mostraSchermata();
// Memorizza i tempi iniziali
ultimaLettura = millis();
ultimoCambioSchermata = millis();
}
void loop() {
// Controlla il pulsante per il cambio manuale
gestisciPulsante();
// Legge il DHT22 ogni due secondi,
// senza bloccare Arduino con delay()
if (millis() - ultimaLettura >= INTERVALLO_LETTURA) {
ultimaLettura = millis();
leggiSensore();
mostraSchermata();
}
// Cambia automaticamente schermata
// quando è trascorso l'intervallo impostato
if (millis() - ultimoCambioSchermata >=
INTERVALLO_SCHERMATA) {
ultimoCambioSchermata = millis();
cambiaSchermata();
}
}
void leggiSensore() {
// Legge temperatura e umidità dal DHT22
float nuovaTemperatura = dht.readTemperature();
float nuovaUmidita = dht.readHumidity();
// Se almeno uno dei valori non è valido,
// conserva le ultime letture corrette.
if (isnan(nuovaTemperatura) ||
isnan(nuovaUmidita)) {
sensoreValido = false;
return;
}
sensoreValido = true;
temperatura = nuovaTemperatura;
umidita = nuovaUmidita;
// Calcola la temperatura percepita in gradi Celsius.
// Il parametro false richiede il risultato in Celsius.
temperaturaPercepita = dht.computeHeatIndex(
temperatura,
umidita,
false
);
// Alla prima lettura valida inizializza
// tutti i valori minimi e massimi.
if (!storicoInizializzato) {
temperaturaMinima = temperatura;
temperaturaMassima = temperatura;
umiditaMinima = umidita;
umiditaMassima = umidita;
storicoInizializzato = true;
return;
}
// Aggiorna i valori estremi della temperatura
if (temperatura < temperaturaMinima) {
temperaturaMinima = temperatura;
}
if (temperatura > temperaturaMassima) {
temperaturaMassima = temperatura;
}
// Aggiorna i valori estremi dell'umidità
if (umidita < umiditaMinima) {
umiditaMinima = umidita;
}
if (umidita > umiditaMassima) {
umiditaMassima = umidita;
}
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW.
if (digitalRead(PIN_PULSANTE) == LOW &&
millis() - ultimaPressione >= TEMPO_DEBOUNCE) {
ultimaPressione = millis();
// Cambia subito schermata
cambiaSchermata();
// Fa ripartire il conteggio automatico,
// evitando un secondo cambio immediato.
ultimoCambioSchermata = millis();
}
}
void cambiaSchermata() {
schermataAttuale++;
// Dopo l'ultima schermata riparte dalla prima
if (schermataAttuale >= NUMERO_SCHERMATE) {
schermataAttuale = 0;
}
mostraSchermata();
}
void mostraSchermata() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// Se non è ancora disponibile alcuna lettura valida,
// mostra una schermata di errore completa.
if (!storicoInizializzato) {
mostraErrore();
display.display();
return;
}
// Visualizza la schermata selezionata
switch (schermataAttuale) {
case 0:
mostraValoriAttuali();
break;
case 1:
mostraMinimiMassimi();
break;
case 2:
mostraTemperaturaPercepita();
break;
}
// Se l'ultima lettura è fallita,
// mostra un piccolo avviso senza cancellare i dati precedenti.
if (!sensoreValido) {
display.fillRect(
83,
54,
44,
10,
SSD1306_BLACK
);
display.setTextSize(1);
display.setCursor(87, 55);
display.print("DHT ERR");
}
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraValoriAttuali() {
display.setTextSize(1);
// Titolo della schermata
display.setCursor(0, 0);
display.print("AMBIENTE");
display.setCursor(103, 0);
display.print("1/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra la temperatura con caratteri grandi
display.setTextSize(2);
display.setCursor(0, 17);
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
// Mostra l'umidità sul lato destro
display.setCursor(72, 17);
display.print(umidita, 0);
display.print("%");
// Mostra la valutazione del comfort
display.setTextSize(1);
display.setCursor(0, 43);
display.print("Comfort:");
display.setCursor(0, 54);
display.print(valutaComfort());
}
void mostraMinimiMassimi() {
display.setTextSize(1);
display.setCursor(0, 0);
display.print("MINIMI E MASSIMI");
display.setCursor(109, 0);
display.print("2/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra temperatura minima e massima
display.setCursor(0, 17);
display.print("Temp min: ");
display.print(temperaturaMinima, 1);
display.print((char)247);
display.print("C");
display.setCursor(0, 29);
display.print("Temp max: ");
display.print(temperaturaMassima, 1);
display.print((char)247);
display.print("C");
// Mostra umidità minima e massima
display.setCursor(0, 43);
display.print("Umid min: ");
display.print(umiditaMinima, 0);
display.print("%");
display.setCursor(0, 55);
display.print("Umid max: ");
display.print(umiditaMassima, 0);
display.print("%");
}
void mostraTemperaturaPercepita() {
display.setTextSize(1);
display.setCursor(0, 0);
display.print("TEMPERATURA PERCEPITA");
display.setCursor(109, 0);
display.print("3/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra la temperatura percepita
// con caratteri grandi al centro.
display.setTextSize(2);
display.setCursor(28, 18);
display.print(temperaturaPercepita, 1);
display.print((char)247);
display.print("C");
display.setTextSize(1);
// Confronto con la temperatura reale
display.setCursor(0, 43);
display.print("Reale: ");
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
display.setCursor(0, 55);
display.print(valutaComfort());
}
const char* valutaComfort() {
// Controlla prima l'umidità,
// perché condizioni estreme influenzano
// fortemente il comfort dell'ambiente.
if (umidita < UMIDITA_MIN_COMFORT) {
return "TROPPO SECCO";
}
if (umidita > UMIDITA_MAX_COMFORT) {
return "TROPPO UMIDO";
}
// Controlla successivamente la temperatura
if (temperatura < TEMPERATURA_MIN_COMFORT) {
return "FREDDO";
}
if (temperatura > TEMPERATURA_MAX_COMFORT) {
return "CALDO";
}
// Se tutti i valori rientrano nelle soglie,
// l'ambiente viene considerato confortevole.
return "COMFORT";
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(18, 15);
display.print("Monitor ambientale");
display.setCursor(39, 31);
display.print("DHT22");
display.setCursor(28, 47);
display.print("Progetto 129");
display.display();
delay(1800);
}
void mostraErrore() {
// Messaggio mostrato quando il DHT22
// non ha ancora restituito letture valide.
display.setTextSize(1);
display.setCursor(17, 17);
display.print("ERRORE SENSORE");
display.setCursor(23, 33);
display.print("Controlla DHT22");
display.setCursor(15, 49);
display.print("Nuovo tentativo...");
}
============================================================
Progetto 129 - Display temperatura e umidita avanzato
Mostra valori attuali, percepiti, minimi, massimi e comfort
============================================================
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// Dimensioni e indirizzo del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1
#define INDIRIZZO_OLED 0x3C
// Configurazione del sensore DHT22
#define PIN_DHT 2
#define TIPO_DHT DHT22
// Pulsante per cambiare manualmente schermata
#define PIN_PULSANTE 3
// Intervalli di aggiornamento
const unsigned long INTERVALLO_LETTURA = 2000;
const unsigned long INTERVALLO_SCHERMATA = 5000;
const unsigned long TEMPO_DEBOUNCE = 180;
// Soglie indicative per il comfort ambientale
const float TEMPERATURA_MIN_COMFORT = 20.0;
const float TEMPERATURA_MAX_COMFORT = 26.0;
const float UMIDITA_MIN_COMFORT = 40.0;
const float UMIDITA_MAX_COMFORT = 60.0;
// Oggetti utilizzati per display e sensore
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
DHT dht(PIN_DHT, TIPO_DHT);
// Valori ambientali correnti
float temperatura = 0.0;
float umidita = 0.0;
float temperaturaPercepita = 0.0;
// Valori minimi e massimi registrati
float temperaturaMinima = 0.0;
float temperaturaMassima = 0.0;
float umiditaMinima = 0.0;
float umiditaMassima = 0.0;
// Stato del sensore e dello storico
bool sensoreValido = false;
bool storicoInizializzato = false;
// Identifica la schermata attualmente visualizzata
byte schermataAttuale = 0;
const byte NUMERO_SCHERMATE = 3;
// Variabili temporali utilizzate da millis()
unsigned long ultimaLettura = 0;
unsigned long ultimoCambioSchermata = 0;
unsigned long ultimaPressione = 0;
void setup() {
// Il pulsante è collegato tra il pin e GND.
// La resistenza interna mantiene stabile l'ingresso.
pinMode(PIN_PULSANTE, INPUT_PULLUP);
// Avvia il sensore DHT22
dht.begin();
// Inizializza il display OLED
if (!display.begin(
SSD1306_SWITCHCAPVCC,
INDIRIZZO_OLED
)) {
// Se il display non viene rilevato,
// il programma rimane bloccato.
while (true) {
}
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
// Mostra una breve schermata iniziale
mostraAvvio();
// Esegue subito una prima lettura
leggiSensore();
mostraSchermata();
// Memorizza i tempi iniziali
ultimaLettura = millis();
ultimoCambioSchermata = millis();
}
void loop() {
// Controlla il pulsante per il cambio manuale
gestisciPulsante();
// Legge il DHT22 ogni due secondi,
// senza bloccare Arduino con delay()
if (millis() - ultimaLettura >= INTERVALLO_LETTURA) {
ultimaLettura = millis();
leggiSensore();
mostraSchermata();
}
// Cambia automaticamente schermata
// quando è trascorso l'intervallo impostato
if (millis() - ultimoCambioSchermata >=
INTERVALLO_SCHERMATA) {
ultimoCambioSchermata = millis();
cambiaSchermata();
}
}
void leggiSensore() {
// Legge temperatura e umidità dal DHT22
float nuovaTemperatura = dht.readTemperature();
float nuovaUmidita = dht.readHumidity();
// Se almeno uno dei valori non è valido,
// conserva le ultime letture corrette.
if (isnan(nuovaTemperatura) ||
isnan(nuovaUmidita)) {
sensoreValido = false;
return;
}
sensoreValido = true;
temperatura = nuovaTemperatura;
umidita = nuovaUmidita;
// Calcola la temperatura percepita in gradi Celsius.
// Il parametro false richiede il risultato in Celsius.
temperaturaPercepita = dht.computeHeatIndex(
temperatura,
umidita,
false
);
// Alla prima lettura valida inizializza
// tutti i valori minimi e massimi.
if (!storicoInizializzato) {
temperaturaMinima = temperatura;
temperaturaMassima = temperatura;
umiditaMinima = umidita;
umiditaMassima = umidita;
storicoInizializzato = true;
return;
}
// Aggiorna i valori estremi della temperatura
if (temperatura < temperaturaMinima) {
temperaturaMinima = temperatura;
}
if (temperatura > temperaturaMassima) {
temperaturaMassima = temperatura;
}
// Aggiorna i valori estremi dell'umidità
if (umidita < umiditaMinima) {
umiditaMinima = umidita;
}
if (umidita > umiditaMassima) {
umiditaMassima = umidita;
}
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW.
if (digitalRead(PIN_PULSANTE) == LOW &&
millis() - ultimaPressione >= TEMPO_DEBOUNCE) {
ultimaPressione = millis();
// Cambia subito schermata
cambiaSchermata();
// Fa ripartire il conteggio automatico,
// evitando un secondo cambio immediato.
ultimoCambioSchermata = millis();
}
}
void cambiaSchermata() {
schermataAttuale++;
// Dopo l'ultima schermata riparte dalla prima
if (schermataAttuale >= NUMERO_SCHERMATE) {
schermataAttuale = 0;
}
mostraSchermata();
}
void mostraSchermata() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// Se non è ancora disponibile alcuna lettura valida,
// mostra una schermata di errore completa.
if (!storicoInizializzato) {
mostraErrore();
display.display();
return;
}
// Visualizza la schermata selezionata
switch (schermataAttuale) {
case 0:
mostraValoriAttuali();
break;
case 1:
mostraMinimiMassimi();
break;
case 2:
mostraTemperaturaPercepita();
break;
}
// Se l'ultima lettura è fallita,
// mostra un piccolo avviso senza cancellare i dati precedenti.
if (!sensoreValido) {
display.fillRect(
83,
54,
44,
10,
SSD1306_BLACK
);
display.setTextSize(1);
display.setCursor(87, 55);
display.print("DHT ERR");
}
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraValoriAttuali() {
display.setTextSize(1);
// Titolo della schermata
display.setCursor(0, 0);
display.print("AMBIENTE");
display.setCursor(103, 0);
display.print("1/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra la temperatura con caratteri grandi
display.setTextSize(2);
display.setCursor(0, 17);
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
// Mostra l'umidità sul lato destro
display.setCursor(72, 17);
display.print(umidita, 0);
display.print("%");
// Mostra la valutazione del comfort
display.setTextSize(1);
display.setCursor(0, 43);
display.print("Comfort:");
display.setCursor(0, 54);
display.print(valutaComfort());
}
void mostraMinimiMassimi() {
display.setTextSize(1);
display.setCursor(0, 0);
display.print("MINIMI E MASSIMI");
display.setCursor(109, 0);
display.print("2/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra temperatura minima e massima
display.setCursor(0, 17);
display.print("Temp min: ");
display.print(temperaturaMinima, 1);
display.print((char)247);
display.print("C");
display.setCursor(0, 29);
display.print("Temp max: ");
display.print(temperaturaMassima, 1);
display.print((char)247);
display.print("C");
// Mostra umidità minima e massima
display.setCursor(0, 43);
display.print("Umid min: ");
display.print(umiditaMinima, 0);
display.print("%");
display.setCursor(0, 55);
display.print("Umid max: ");
display.print(umiditaMassima, 0);
display.print("%");
}
void mostraTemperaturaPercepita() {
display.setTextSize(1);
display.setCursor(0, 0);
display.print("TEMPERATURA PERCEPITA");
display.setCursor(109, 0);
display.print("3/3");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra la temperatura percepita
// con caratteri grandi al centro.
display.setTextSize(2);
display.setCursor(28, 18);
display.print(temperaturaPercepita, 1);
display.print((char)247);
display.print("C");
display.setTextSize(1);
// Confronto con la temperatura reale
display.setCursor(0, 43);
display.print("Reale: ");
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
display.setCursor(0, 55);
display.print(valutaComfort());
}
const char* valutaComfort() {
// Controlla prima l'umidità,
// perché condizioni estreme influenzano
// fortemente il comfort dell'ambiente.
if (umidita < UMIDITA_MIN_COMFORT) {
return "TROPPO SECCO";
}
if (umidita > UMIDITA_MAX_COMFORT) {
return "TROPPO UMIDO";
}
// Controlla successivamente la temperatura
if (temperatura < TEMPERATURA_MIN_COMFORT) {
return "FREDDO";
}
if (temperatura > TEMPERATURA_MAX_COMFORT) {
return "CALDO";
}
// Se tutti i valori rientrano nelle soglie,
// l'ambiente viene considerato confortevole.
return "COMFORT";
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(18, 15);
display.print("Monitor ambientale");
display.setCursor(39, 31);
display.print("DHT22");
display.setCursor(28, 47);
display.print("Progetto 129");
display.display();
delay(1800);
}
void mostraErrore() {
// Messaggio mostrato quando il DHT22
// non ha ancora restituito letture valide.
display.setTextSize(1);
display.setCursor(17, 17);
display.print("ERRORE SENSORE");
display.setCursor(23, 33);
display.print("Controlla DHT22");
display.setCursor(15, 49);
display.print("Nuovo tentativo...");
}
⚙️ Come funziona
Arduino legge temperatura e umidità dal sensore DHT22 ogni due secondi.
Dopo ogni lettura valida:
Arduino legge temperatura e umidità dal sensore DHT22 ogni due secondi.
Dopo ogni lettura valida:
- aggiorna i valori correnti;
- confronta i dati con i minimi e i massimi;
- calcola la temperatura percepita;
- determina lo stato di comfort;
- aggiorna il display OLED.
🌡️ Temperatura e umidità
Il sensore DHT22 restituisce due valori principali:
temperatura = dht.readTemperature();
umidita = dht.readHumidity();
La temperatura viene espressa in gradi Celsius, mentre l’umidità viene espressa in percentuale.
Il programma controlla i risultati tramite isnan().
Se uno dei valori non è valido, lo storico non viene aggiornato e sul display appare un messaggio di errore.
Il sensore DHT22 restituisce due valori principali:
temperatura = dht.readTemperature();
umidita = dht.readHumidity();
La temperatura viene espressa in gradi Celsius, mentre l’umidità viene espressa in percentuale.
Il programma controlla i risultati tramite isnan().
Se uno dei valori non è valido, lo storico non viene aggiornato e sul display appare un messaggio di errore.
☀️ Temperatura percepita
La temperatura percepita dipende sia dalla temperatura reale sia dall’umidità.
La libreria DHT permette di calcolarla attraverso:
temperaturaPercepita = dht.computeHeatIndex(
temperatura,
umidita,
false
);
Il valore false indica che il risultato deve essere restituito in gradi Celsius.
👉 La temperatura percepita diventa particolarmente utile negli ambienti caldi e umidi.
La temperatura percepita dipende sia dalla temperatura reale sia dall’umidità.
La libreria DHT permette di calcolarla attraverso:
temperaturaPercepita = dht.computeHeatIndex(
temperatura,
umidita,
false
);
Il valore false indica che il risultato deve essere restituito in gradi Celsius.
👉 La temperatura percepita diventa particolarmente utile negli ambienti caldi e umidi.
📈 Valori minimi e massimi
Alla prima lettura valida, Arduino utilizza i valori misurati per inizializzare lo storico.
Le letture successive vengono confrontate con quelle precedenti.
Se la nuova temperatura è più bassa del minimo registrato, il minimo viene aggiornato.
Se è più alta del massimo, viene aggiornato il massimo.
Lo stesso procedimento viene utilizzato per l’umidità.
I valori rimangono memorizzati finché Arduino resta alimentato.
Alla prima lettura valida, Arduino utilizza i valori misurati per inizializzare lo storico.
Le letture successive vengono confrontate con quelle precedenti.
Se la nuova temperatura è più bassa del minimo registrato, il minimo viene aggiornato.
Se è più alta del massimo, viene aggiornato il massimo.
Lo stesso procedimento viene utilizzato per l’umidità.
I valori rimangono memorizzati finché Arduino resta alimentato.
😊 Valutazione del comfort
Il progetto classifica l’ambiente utilizzando temperatura e umidità.
Gli stati visualizzati sono:
Le soglie possono essere modificate all’inizio del programma.
👉 Questa valutazione è indicativa e serve soprattutto come esempio didattico.
Il progetto classifica l’ambiente utilizzando temperatura e umidità.
Gli stati visualizzati sono:
- COMFORT: temperatura e umidità in un intervallo gradevole;
- TROPPO SECCO: umidità inferiore alla soglia minima;
- TROPPO UMIDO: umidità superiore alla soglia massima;
- FREDDO: temperatura troppo bassa;
- CALDO: temperatura troppo elevata.
Le soglie possono essere modificate all’inizio del programma.
👉 Questa valutazione è indicativa e serve soprattutto come esempio didattico.
⚠️ Gestione degli errori
Quando il DHT22 non restituisce dati validi, Arduino:
Controlla sempre:
Quando il DHT22 non restituisce dati validi, Arduino:
- mantiene gli ultimi valori corretti;
- segnala l’errore sul display;
- prova nuovamente alla lettura successiva;
- non modifica minimi e massimi.
Controlla sempre:
- alimentazione del sensore;
- pin DATA;
- resistenza di pull-up;
- tipo di sensore selezionato nel codice;
- installazione delle librerie.
🧠 Perché è un progetto importante
Con questo progetto impari a:
Con questo progetto impari a:
- utilizzare un sensore DHT22
- misurare temperatura e umidità
- calcolare la temperatura percepita
- memorizzare valori minimi e massimi
- valutare condizioni ambientali
- creare più schermate su display OLED
- cambiare schermata automaticamente
- gestire un pulsante con INPUT_PULLUP
- controllare più intervalli tramite millis()
- gestire errori di lettura senza bloccare il sistema
🔄 Varianti possibili
Vuoi migliorare il progetto?
Vuoi migliorare il progetto?
- 💾 salva minimi e massimi nella EEPROM
- 🔘 aggiungi un pulsante per azzerare lo storico
- ⏰ registra l’ora dei valori estremi con un RTC DS3231
- 📊 aggiungi un grafico della temperatura
- 💧 crea un grafico dell’umidità
- 🔔 aggiungi un buzzer per gli avvisi
- 🚨 collega LED differenti per ogni stato
- 🌬️ controlla automaticamente una ventola
- 💨 aggiungi un umidificatore
- 📶 invia i dati tramite Wi-Fi
- 🗃️ salva le letture su una scheda microSD
- 📟 utilizza un display OLED da 1,3 pollici