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 124
Grafico temperatura
​su display

🚀 Introduzione

Vuoi vedere come cambia la temperatura nel tempo direttamente su un display Arduino? 📈

In questo progetto realizzerai un grafico della temperatura su display OLED, aggiornato automaticamente a intervalli regolari.

Arduino leggerà i dati da un sensore DHT11 e conserverà gli ultimi valori in memoria, visualizzandoli sotto forma di linea grafica.
​
👉 Il risultato sarà un piccolo monitor ambientale capace di mostrare sia la temperatura attuale sia il suo andamento recente.

🎯 Cosa realizzerai
​

Con Arduino creerai un sistema che:
  • 🌡️ misura la temperatura ambientale
  • 📟 mostra il valore attuale su display OLED
  • 📈 disegna un grafico della temperatura
  • 🔄 aggiorna automaticamente i dati
  • 🧠 conserva gli ultimi valori in memoria
  • ⚠️ segnala eventuali errori del sensore
  • ⏱️ utilizza millis() senza bloccare il programma

🧰 Materiale necessario
​
  • 1x Arduino UNO
  • 1x display OLED 0,96 pollici I2C SSD1306
  • 1x sensore DHT11
  • 1x resistenza da 10kΩ, se utilizzi il sensore senza modulo
  • cavetti jumper
  • breadboard
  • cavo USB

🛒 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
​
Puoi installarle dal Gestore librerie dell’Arduino IDE:
  1. apri Arduino IDE;
  2. vai su Sketch → Include Library → Manage Libraries;
  3. cerca il nome della libreria;
  4. premi Install;
  5. ripeti l’operazione per tutte le librerie richieste.

🔌 Schema di collegamento
​

Display OLED SSD1306
  • VCC → 5V
  • GND → GND
  • SDA → A4
  • SCL → A5
L’indirizzo I2C utilizzato nel codice è 0x3C.
​
Sensore DHT11
  • VCC → 5V
  • GND → GND
  • DATA → pin digitale 2
Se utilizzi un sensore DHT11 senza schedina, collega una resistenza da 10kΩ tra il pin DATA e 5V.
I moduli DHT11 già assemblati normalmente includono già questa resistenza.
Foto

💻 Codice Arduino
​

Il programma legge la temperatura ogni due secondi.
​
Ogni nuovo valore viene inserito in un array che contiene lo storico delle ultime letture.
​
Quando arriva un nuovo dato:
  • i valori precedenti vengono spostati;
  • il valore più vecchio viene eliminato;
  • il nuovo valore viene aggiunto alla fine;
  • il grafico viene ridisegnato.
​/*
  ============================================================
  Progetto 124 - Grafico temperatura su display OLED
  Visualizza la temperatura attuale e il suo andamento nel tempo
  ============================================================
*/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>

// Dimensioni del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1

// Configurazione del sensore DHT11
#define PIN_DHT 2
#define TIPO_DHT DHT11

// Numero di letture visualizzate nel grafico
#define NUMERO_CAMPIONI 55

// Limiti della scala verticale del grafico
const float TEMPERATURA_MINIMA = 10.0;
const float TEMPERATURA_MASSIMA = 40.0;

// Intervallo tra due letture.
// Il DHT11 non deve essere interrogato troppo velocemente.
const unsigned long INTERVALLO_LETTURA = 2000;

// Oggetti per il display e il sensore
Adafruit_SSD1306 display(
  LARGHEZZA_DISPLAY,
  ALTEZZA_DISPLAY,
  &Wire,
  RESET_OLED
);

DHT dht(PIN_DHT, TIPO_DHT);

// Array che conserva lo storico delle temperature
float storicoTemperatura[NUMERO_CAMPIONI];

// Ultima temperatura letta correttamente
float temperaturaAttuale = 0.0;

// Momento dell'ultimo aggiornamento
unsigned long ultimoAggiornamento = 0;

// Indica se è disponibile almeno una lettura valida
bool storicoInizializzato = false;

// Indica se l'ultima lettura del sensore è valida
bool sensoreValido = false;

void setup() {
  // Avvia la comunicazione con il sensore DHT11
  dht.begin();

  // Inizializza il display OLED all'indirizzo I2C 0x3C
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    // Se il display non viene rilevato, blocca il programma
    while (true) {
    }
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);

  // Mostra una breve schermata iniziale
  display.setCursor(10, 20);
  display.println("Grafico temperatura");

  display.setCursor(28, 36);
  display.println("Progetto 124");

  display.display();

  delay(1800);

  // Esegue una prima lettura del sensore
  leggiTemperatura();

  // Mostra subito la schermata principale
  mostraSchermata();

  // Memorizza il tempo dell'ultima lettura
  ultimoAggiornamento = millis();
}

void loop() {
  // Controlla se è trascorso l'intervallo previsto
  // senza bloccare Arduino con delay()
  if (millis() - ultimoAggiornamento >= INTERVALLO_LETTURA) {
    ultimoAggiornamento = millis();

    leggiTemperatura();
    mostraSchermata();
  }
}

void leggiTemperatura() {
  // Legge la temperatura in gradi Celsius
  float nuovaTemperatura = dht.readTemperature();

  // Se il sensore restituisce un valore non valido,
  // conserva lo storico precedente senza modificarlo
  if (isnan(nuovaTemperatura)) {
    sensoreValido = false;
    return;
  }

  sensoreValido = true;
  temperaturaAttuale = nuovaTemperatura;

  // Alla prima lettura valida riempie tutto lo storico
  // con la stessa temperatura, evitando valori casuali
  if (!storicoInizializzato) {
    for (int i = 0; i < NUMERO_CAMPIONI; i++) {
      storicoTemperatura[i] = temperaturaAttuale;
    }

    storicoInizializzato = true;
    return;
  }

  // Sposta tutti i valori di una posizione verso sinistra.
  // Il campione più vecchio viene eliminato.
  for (int i = 0; i < NUMERO_CAMPIONI - 1; i++) {
    storicoTemperatura[i] = storicoTemperatura[i + 1];
  }

  // Inserisce la nuova temperatura nell'ultima posizione
  storicoTemperatura[NUMERO_CAMPIONI - 1] = temperaturaAttuale;
}

void mostraSchermata() {
  // Pulisce il display prima di ridisegnare la schermata
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

  // Titolo della schermata
  display.setCursor(0, 0);
  display.print("TEMPERATURA");

  // Mostra il valore attuale nella parte alta
  display.setCursor(73, 0);

  if (sensoreValido) {
    display.print(temperaturaAttuale, 1);
    display.print((char)247);
    display.print("C");
  } else {
    display.print("ERR");
  }

  // Linea di separazione tra titolo e grafico
  display.drawLine(
    0,
    10,
    127,
    10,
    SSD1306_WHITE
  );

  // Se esiste almeno una lettura valida,
  // visualizza lo storico anche quando una lettura fallisce
  if (storicoInizializzato) {
    disegnaGrafico();

    // Mostra un piccolo avviso se l'ultima lettura è fallita
    if (!sensoreValido) {
      display.fillRect(88, 53, 38, 9, SSD1306_BLACK);
      display.setCursor(91, 54);
      display.print("DHT ERR");
    }
  } else {
    mostraErrore();
  }

  // Invia al display tutti gli elementi disegnati
  display.display();
}

void disegnaGrafico() {
  // Coordinate e dimensioni dell'area del grafico.
  // Il margine sinistro lascia spazio ai valori della scala.
  const int graficoX = 17;
  const int graficoY = 15;
  const int graficoLarghezza = 110;
  const int graficoAltezza = 48;

  // Disegna il bordo esterno del grafico
  display.drawRect(
    graficoX,
    graficoY,
    graficoLarghezza,
    graficoAltezza,
    SSD1306_WHITE
  );

  // Mostra il valore massimo della scala
  display.setCursor(0, graficoY + 1);
  display.print((int)TEMPERATURA_MASSIMA);

  // Mostra il valore minimo della scala
  display.setCursor(0, graficoY + graficoAltezza - 8);
  display.print((int)TEMPERATURA_MINIMA);

  // Disegna una linea centrale di riferimento
  display.drawLine(
    graficoX + 1,
    graficoY + graficoAltezza / 2,
    graficoX + graficoLarghezza - 2,
    graficoY + graficoAltezza / 2,
    SSD1306_WHITE
  );

  // Calcola la distanza orizzontale tra due campioni
  float passoX = (float)(graficoLarghezza - 5) /
                 (NUMERO_CAMPIONI - 1);

  // Disegna una linea tra ogni coppia
  // di temperature consecutive
  for (int i = 0; i < NUMERO_CAMPIONI - 1; i++) {
    int x1 = graficoX + 2 + (int)(i * passoX);
    int x2 = graficoX + 2 + (int)((i + 1) * passoX);

    int y1 = convertiTemperaturaInY(
      storicoTemperatura[i],
      graficoY,
      graficoAltezza
    );

    int y2 = convertiTemperaturaInY(
      storicoTemperatura[i + 1],
      graficoY,
      graficoAltezza
    );

    display.drawLine(
      x1,
      y1,
      x2,
      y2,
      SSD1306_WHITE
    );
  }
}

int convertiTemperaturaInY(
  float temperatura,
  int graficoY,
  int graficoAltezza
) {
  // Limita il valore alla scala visibile
  temperatura = constrain(
    temperatura,
    TEMPERATURA_MINIMA,
    TEMPERATURA_MASSIMA
  );

  // Moltiplica per 10 per conservare una cifra decimale
  int temperaturaDecimi = (int)(temperatura * 10.0);

  int temperaturaMinimaDecimi =
    (int)(TEMPERATURA_MINIMA * 10.0);

  int temperaturaMassimaDecimi =
    (int)(TEMPERATURA_MASSIMA * 10.0);

  // Converte la temperatura in una coordinata verticale.
  // Nel display OLED la coordinata Y aumenta verso il basso,
  // quindi i valori della scala devono essere invertiti.
  int coordinataY = map(
    temperaturaDecimi,
    temperaturaMinimaDecimi,
    temperaturaMassimaDecimi,
    graficoY + graficoAltezza - 3,
    graficoY + 2
  );

  return coordinataY;
}

void mostraErrore() {
  // Messaggio mostrato quando non è ancora disponibile
  // alcuna lettura valida dal sensore DHT11
  display.setCursor(17, 25);
  display.println("Errore sensore");

  display.setCursor(8, 41);
  display.println("Controlla i cavi");

  display.setCursor(15, 53);
  display.println("Nuovo tentativo...");
}

⚙️ Come funziona

Arduino legge la temperatura attraverso il sensore DHT11.
Il valore attuale viene mostrato nella parte superiore del display OLED.
La parte inferiore del display viene invece utilizzata per disegnare il grafico.

Ogni punto del grafico rappresenta una lettura della temperatura.
👉 I punti vengono collegati tra loro tramite linee, creando una rappresentazione visiva dell’andamento termico.
​
Quando la temperatura aumenta, la linea sale.
Quando diminuisce, la linea scende.

🧠 Memorizzazione dello storico

Il programma utilizza un array per conservare più letture:
float storicoTemperatura[NUMERO_CAMPIONI];
​
Ogni posizione dell’array rappresenta un punto del grafico.

Quando viene acquisita una nuova temperatura, tutti i valori vengono spostati di una posizione verso sinistra.

Il valore più vecchio viene eliminato, mentre il nuovo viene inserito alla fine.
👉 Questo effetto crea un grafico che scorre nel tempo da sinistra verso destra.

📊 Conversione della temperatura in coordinate
​

Il display OLED utilizza coordinate grafiche.
La temperatura deve quindi essere convertita in una posizione verticale.

Il programma utilizza la funzione map() per trasformare la temperatura in una coordinata compresa nell’area del grafico.

Per esempio:
int y = map(temperatura, 10, 40, 62, 22);
Una temperatura di 10 °C viene disegnata nella parte bassa del grafico.
Una temperatura di 40 °C viene invece disegnata nella parte alta.

La coordinata verticale viene invertita perché nel display il punto 0 si trova nella parte superiore.

⚠️ Gestione degli errori
​

Se il DHT11 non restituisce un valore valido, il programma non aggiorna il grafico.

Sul display appare il messaggio:
Errore sensore

Questo evita di inserire valori errati nello storico della temperatura.
​
Controlla sempre:
  • alimentazione del sensore;
  • collegamento del pin DATA;
  • presenza della resistenza di pull-up;
  • corretta installazione della libreria DHT.

🧠 Perché è un progetto importante
​

Con questo progetto impari a:
  • leggere la temperatura con un DHT11
  • utilizzare un display OLED grafico
  • memorizzare dati in un array
  • creare uno storico delle letture
  • disegnare linee e punti
  • convertire valori in coordinate
  • aggiornare un grafico nel tempo
  • utilizzare millis() senza bloccare Arduino
  • gestire gli errori di lettura
​
👉 È una base utile per termometri evoluti, stazioni ambientali, datalogger e sistemi di monitoraggio.

🔄 Varianti possibili
​

Vuoi migliorare il progetto?
  • 🌡️ sostituisci il DHT11 con un DHT22
  • 💧 aggiungi un secondo grafico per l’umidità
  • ⏰ aggiungi data e ora con RTC DS3231
  • 💾 salva le letture su scheda microSD
  • 🔔 attiva un allarme oltre una certa temperatura
  • 📊 mostra una griglia con valori minimi e massimi
  • 🎛️ aggiungi pulsanti per cambiare scala
  • 📶 invia i dati tramite Wi-Fi
  • 🔋 alimenta il sistema con una batteria
  • 📉 visualizza anche temperatura minima, massima e media

Foto
Foto

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