Sistema di debug Arduino con LED e display OLED
Crea una diagnostica autonoma con tre livelli di stato, codici di errore, DHT22, fotoresistenza e due schermate OLED.
🚀 Introduzione
Quando un progetto Arduino diventa più complesso, capire cosa non funziona collegandolo ogni volta al computer può diventare scomodo. In questo progetto realizzerai un vero sistema di diagnostica locale: tre LED comunicano immediatamente lo stato generale, mentre un display OLED mostra valori, stato del sensore e codice dell’eventuale problema.
Sistema nei limiti.
Un parametro si avvicina a una soglia critica.
Sensore non valido o soglia critica superata.
- creare livelli di stato con enum;
- assegnare priorità agli errori;
- usare LED come indicatori diagnostici;
- mostrare codici di debug su OLED;
- controllare DHT22 e LDR;
- gestire due schermate con un pulsante;
- realizzare un test automatico all’avvio;
- aggiornare il sistema tramite millis().
🧰 Materiale necessario
* Una da 10 kΩ è usata nel partitore della LDR; l’altra serve come pull-up se il DHT22 non è montato su un modulo che la integra.
🛒 Non hai ancora i componenti?
Un kit Arduino per principianti contiene molti dei componenti utilizzati in questo e negli altri progetti.
Kit Arduino consigliato →Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.📘 Vuoi imparare Arduino passo dopo passo?
Nei miei libri trovi spiegazioni, schemi e progetti pratici pensati anche per chi parte da zero.
Scopri i miei libri →Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.📚 Librerie necessarie
Gestione del display OLED.
Funzioni grafiche e testo.
Lettura del DHT22.
Dipendenza della libreria DHT.
La libreria Wire, usata per il bus I2C, è già inclusa nell’Arduino IDE.
🔌 Schema di collegamento
| Componente | Collegamento |
|---|---|
| OLED SSD1306 | VCC → 5V, GND → GND, SDA → A4, SCL → A5 |
| DHT22 | VCC → 5V, DATA → D2, GND → GND |
| LDR | 5V → LDR → A0; resistenza 10 kΩ tra A0 e GND |
| LED verde | Anodo → D8 tramite 220 Ω; catodo → GND |
| LED giallo | Anodo → D9 tramite 220 Ω; catodo → GND |
| LED rosso | Anodo → D10 tramite 220 Ω; catodo → GND |
| Pulsante | D3 ↔ pulsante ↔ GND |

💻 Codice Arduino completo
Il programma divide la diagnostica in tre livelli — OK, ATTENZIONE ed ERRORE — e assegna codici specifici alle anomalie.
/*
============================================================
Progetto 138 - Sistema debug LED e display
Mostra stato, avvisi e codici di errore del sistema
============================================================
*/
#include
#include
#include
#include
// 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
// Collegamenti degli altri componenti
#define PIN_PULSANTE 3
#define PIN_LED_VERDE 8
#define PIN_LED_GIALLO 9
#define PIN_LED_ROSSO 10
#define PIN_LUCE A0
// Soglie di attenzione
const float TEMP_ATTENZIONE = 28.0;
const float UMID_ATTENZIONE = 65.0;
const int LUCE_ATTENZIONE = 25;
// Soglie di errore
const float TEMP_ERRORE = 35.0;
const float UMID_ERRORE = 80.0;
const int LUCE_ERRORE = 10;
// Tempi di aggiornamento
const unsigned long INTERVALLO_LETTURA = 2000;
const unsigned long TEMPO_DEBOUNCE = 180;
// Oggetti utilizzati per display e sensore
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
DHT dht(PIN_DHT, TIPO_DHT);
// Livelli generali del sistema
enum LivelloSistema {
STATO_OK,
STATO_ATTENZIONE,
STATO_ERRORE
};
LivelloSistema livelloAttuale = STATO_OK;
// Codici di debug disponibili
enum CodiceDebug {
DEBUG_OK,
DEBUG_DHT,
DEBUG_TEMPERATURA,
DEBUG_UMIDITA,
DEBUG_LUMINOSITA
};
CodiceDebug codiceAttuale = DEBUG_OK;
// Valori letti dai sensori
float temperatura = 0.0;
float umidita = 0.0;
int luminositaPercentuale = 0;
// Indica se il DHT22 ha restituito dati validi
bool sensoreDhtValido = false;
// Schermata attualmente visualizzata
byte schermataAttuale = 0;
const byte NUMERO_SCHERMATE = 2;
// Variabili temporali
unsigned long ultimaLettura = 0;
unsigned long ultimaPressione = 0;
unsigned long ultimoAggiornamentoValido = 0;
// Indica quando il display deve essere ridisegnato
bool aggiornamentoDisplayRichiesto = true;
void setup() {
// Il pulsante è collegato tra il pin e GND
pinMode(PIN_PULSANTE, INPUT_PULLUP);
// Configura i tre LED come uscite
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_GIALLO, OUTPUT);
pinMode(PIN_LED_ROSSO, OUTPUT);
// Spegne tutti i LED durante l'avvio
spegniTuttiLed();
// 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);
mostraAvvio();
// Esegue un test rapido dei LED
testLed();
// Esegue subito una prima lettura
leggiSensori();
valutaSistema();
aggiornaLed();
mostraSchermata();
ultimaLettura = millis();
aggiornamentoDisplayRichiesto = false;
}
void loop() {
// Controlla il pulsante per cambiare schermata
gestisciPulsante();
// Legge periodicamente i sensori
if (millis() - ultimaLettura >= INTERVALLO_LETTURA) {
ultimaLettura = millis();
leggiSensori();
valutaSistema();
aggiornaLed();
aggiornamentoDisplayRichiesto = true;
}
// Ridisegna il display soltanto quando necessario
if (aggiornamentoDisplayRichiesto) {
mostraSchermata();
aggiornamentoDisplayRichiesto = false;
}
}
void leggiSensori() {
// Legge temperatura e umidità dal DHT22
float nuovaTemperatura = dht.readTemperature();
float nuovaUmidita = dht.readHumidity();
// Aggiorna i valori soltanto
// se entrambe le letture sono valide
if (!isnan(nuovaTemperatura) &&
!isnan(nuovaUmidita)) {
temperatura = nuovaTemperatura;
umidita = nuovaUmidita;
sensoreDhtValido = true;
// Memorizza il momento dell'ultima lettura valida
ultimoAggiornamentoValido = millis();
} else {
sensoreDhtValido = false;
}
// Legge la fotoresistenza
int valoreLuce = analogRead(PIN_LUCE);
// Converte il valore analogico in percentuale
luminositaPercentuale = map(
valoreLuce,
0,
1023,
0,
100
);
luminositaPercentuale = constrain(
luminositaPercentuale,
0,
100
);
}
void valutaSistema() {
/*
Gli errori hanno priorità sulle condizioni
di attenzione. Il primo errore trovato
determina il codice mostrato sul display.
*/
// Errore di comunicazione con il DHT22
if (!sensoreDhtValido) {
livelloAttuale = STATO_ERRORE;
codiceAttuale = DEBUG_DHT;
return;
}
// Temperatura oltre la soglia critica
if (temperatura >= TEMP_ERRORE) {
livelloAttuale = STATO_ERRORE;
codiceAttuale = DEBUG_TEMPERATURA;
return;
}
// Umidità oltre la soglia critica
if (umidita >= UMID_ERRORE) {
livelloAttuale = STATO_ERRORE;
codiceAttuale = DEBUG_UMIDITA;
return;
}
// Luminosità sotto la soglia critica
if (luminositaPercentuale = TEMP_ATTENZIONE ||
umidita >= UMID_ATTENZIONE ||
luminositaPercentuale = TEMPO_DEBOUNCE) {
ultimaPressione = millis();
// Passa alla schermata successiva
schermataAttuale++;
if (schermataAttuale >= NUMERO_SCHERMATE) {
schermataAttuale = 0;
}
aggiornamentoDisplayRichiesto = true;
}
}
void mostraSchermata() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
if (schermataAttuale == 0) {
mostraRiepilogo();
} else {
mostraDebug();
}
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraRiepilogo() {
display.setTextSize(1);
// Titolo della schermata
display.setCursor(0, 0);
display.print("STATO SISTEMA");
display.setCursor(103, 0);
display.print("1/2");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra il livello generale
display.setCursor(0, 16);
display.print("Livello: ");
if (livelloAttuale == STATO_OK) {
display.print("OK");
} else if (livelloAttuale == STATO_ATTENZIONE) {
display.print("ATTENZIONE");
} else {
display.print("ERRORE");
}
// Mostra la temperatura
display.setCursor(0, 29);
display.print("Temp: ");
if (sensoreDhtValido) {
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
} else {
display.print("ERR");
}
// Mostra l'umidità
display.setCursor(0, 42);
display.print("Umid: ");
if (sensoreDhtValido) {
display.print(umidita, 1);
display.print("%");
} else {
display.print("ERR");
}
// Mostra la luminosità
display.setCursor(0, 55);
display.print("Luce: ");
display.print(luminositaPercentuale);
display.print("%");
}
void mostraDebug() {
display.setTextSize(1);
display.setCursor(0, 0);
display.print("DEBUG SISTEMA");
display.setCursor(103, 0);
display.print("2/2");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Mostra il codice di debug
display.setCursor(0, 16);
display.print("Codice: ");
display.print(testoCodiceDebug());
// Mostra lo stato del DHT22
display.setCursor(0, 29);
display.print("DHT22: ");
if (sensoreDhtValido) {
display.print("ONLINE");
} else {
display.print("ERRORE");
}
// Mostra il tempo trascorso dall'ultima
// lettura valida del sensore
display.setCursor(0, 42);
display.print("Ultimo OK: ");
unsigned long secondiTrascorsi =
(millis() - ultimoAggiornamentoValido) / 1000UL;
display.print(secondiTrascorsi);
display.print("s");
// Mostra il LED che dovrebbe essere acceso
display.setCursor(0, 55);
display.print("LED: ");
if (livelloAttuale == STATO_OK) {
display.print("VERDE");
} else if (livelloAttuale == STATO_ATTENZIONE) {
display.print("GIALLO");
} else {
display.print("ROSSO");
}
}
const char* testoCodiceDebug() {
// Restituisce il testo corrispondente
// al codice di errore corrente
switch (codiceAttuale) {
case DEBUG_DHT:
return "D01";
case DEBUG_TEMPERATURA:
return "D02";
case DEBUG_UMIDITA:
return "D03";
case DEBUG_LUMINOSITA:
return "D04";
case DEBUG_OK:
default:
return "D00";
}
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(19, 14);
display.print("Sistema debug");
display.setCursor(19, 30);
display.print("LED + display");
display.setCursor(28, 47);
display.print("Progetto 138");
display.display();
delay(1800);
}⚙️ Come funziona
Ogni due secondi Arduino legge DHT22 e fotoresistenza, valuta i valori rispetto alle soglie configurate, sceglie il livello generale e accende soltanto il LED corrispondente. Il display viene ridisegnato quando arrivano nuovi dati oppure quando premi il pulsante per cambiare schermata.
🚦 Le soglie del sistema
| Parametro | Attenzione | Errore |
|---|---|---|
| Temperatura | ≥ 28 °C | ≥ 35 °C |
| Umidità | ≥ 65% | ≥ 80% |
| Luminosità | ≤ 25% | ≤ 10% |
| DHT22 | — | Lettura non valida |
Le soglie sono dichiarate all’inizio dello sketch, quindi puoi adattarle facilmente al tuo progetto.
⚠️ Codici di debug
| Codice | Significato |
|---|---|
| D00 | Nessun errore |
| D01 | DHT22 non disponibile / lettura non valida |
| D02 | Temperatura troppo elevata |
| D03 | Umidità troppo elevata |
| D04 | Luminosità troppo bassa |
Gli errori hanno priorità sulle condizioni di attenzione. Inoltre lo sketch controlla gli errori in un ordine preciso: DHT22, temperatura, umidità e infine luminosità. Il primo errore trovato diventa il codice mostrato sul display.
🧪 Test automatico dei LED
All’accensione viene eseguita la funzione testLed(). Arduino accende per circa 350 ms prima il LED verde, poi il giallo e infine il rosso.
📟 Le due schermate OLED
Schermata 1/2 — Stato sistema
- livello generale;
- temperatura;
- umidità;
- luminosità.
Schermata 2/2 — Debug sistema
- codice diagnostico;
- DHT22 online/errore;
- secondi dall’ultima lettura valida;
- LED che dovrebbe essere acceso.
Premendo il pulsante su D3 il programma passa ciclicamente da una schermata all’altra. Un debounce software di 180 ms evita cambi multipli causati dal rimbalzo meccanico.
⏱️ Aggiornamento senza bloccare Arduino
Le letture periodiche sono gestite con millis() e un intervallo di 2000 ms. Questo evita un delay(2000) nel loop principale e lascia il microcontrollore libero di controllare continuamente il pulsante.
🧠 Perché questo progetto è importante
Qui Arduino non si limita a leggere sensori: interpreta lo stato del sistema e comunica una diagnosi. È un modello utile per centraline, robot, sistemi domotici e dispositivi installati lontano dal computer.
La separazione in funzioni come lettura, valutazione, LED e visualizzazione rende inoltre lo sketch più facile da mantenere ed estendere.
🔄 Varianti possibili
✅ Cosa devi ricordare
- verde = sistema regolare, giallo = attenzione, rosso = errore;
- le letture vengono aggiornate ogni 2 secondi;
- gli errori hanno priorità sulle condizioni di attenzione;
- il DHT22 non valido genera D01;
- il pulsante D3 cambia tra le due schermate;
- il display usa I2C all’indirizzo 0x3C;
- il test iniziale verifica i tre LED;
- il display viene ridisegnato soltanto quando necessario;
- le soglie possono essere personalizzate all’inizio dello sketch.

