PROGETTI ARDUINO

  • HOME
  • 200 Progetti
  • Progetti e Tutorial
  • Reti
    • Impara le reti
    • internet fibra
    • wifi mesh
    • modem router
    • diagnostica reti
    • ethernet lan
    • sicurezza configurazione
  • Elettronica
  • Recensioni
  • Manuale
  • Contatti
  • HOME
  • 200 Progetti
  • Progetti e Tutorial
  • Reti
    • Impara le reti
    • internet fibra
    • wifi mesh
    • modem router
    • diagnostica reti
    • ethernet lan
    • sicurezza configurazione
  • Elettronica
  • Recensioni
  • Manuale
  • Contatti

Progetto 129
​Display temperatura e umidità avanzato

🚀 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.

🎯 Cosa realizzerai
​

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
​
  • 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
​

📚 Librerie necessarie
​

Per realizzare il progetto devi installare:
  • Adafruit SSD1306
  • Adafruit GFX Library
  • DHT sensor library
  • Adafruit Unified Sensor
​
Per installarle:
  1. apri Arduino IDE;
  2. vai su Sketch → Include Library → Manage Libraries;
  3. cerca Adafruit SSD1306;
  4. installa la libreria;
  5. cerca Adafruit GFX Library;
  6. installa la libreria;
  7. cerca DHT sensor library;
  8. installa la versione sviluppata da Adafruit;
  9. installa anche Adafruit Unified Sensor quando richiesto.
La libreria Wire, necessaria per il display I2C, è già compresa nell’Arduino IDE.

🔌 Schema di collegamento
​

Display OLED SSD1306
  • VCC → 5V
  • GND → GND
  • SDA → A4
  • SCL → A5
Il codice utilizza l’indirizzo I2C 0x3C, comune nella maggior parte dei display OLED da 0,96 pollici.
​
Sensore DHT22
Se utilizzi un modulo DHT22 già assemblato:
  • VCC → 5V
  • GND → GND
  • DATA → pin digitale 2
Se utilizzi il sensore DHT22 senza modulo:
  • 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
Osserva il sensore dalla parte della griglia frontale prima di identificare i pin.

Pulsante cambio schermata
  • un terminale → pin digitale 3
  • terminale opposto → GND
Con la modalità INPUT_PULLUP:
  • pulsante non premuto → HIGH
  • pulsante premuto → LOW
Foto

💻 Codice Arduino
​

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.
Le schermate cambiano automaticamente ogni cinque secondi oppure manualmente premendo il pulsante.
​/*
  ============================================================
  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:
  • 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.
Il programma utilizza millis() invece di lunghi delay(), permettendo ad Arduino di controllare contemporaneamente sensore, pulsante e display.

🌡️ 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.

☀️ 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.

📈 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.

😊 Valutazione del comfort
​

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:
  • 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:
  • 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
👉 Queste tecniche saranno utili nel prossimo progetto, dedicato al monitoraggio ambientale con storico.

🔄 Varianti possibili
​

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

Foto
Foto

© ProgettiArduino.com 2026 - Fancello Salvatore
​ Layout, immagini e testi sono di esclusiva proprietà di www.progettiarduino.com 
Privacy Policy