🚀 Introduzione
Vuoi fare in modo che Arduino riconosca automaticamente un problema e mostri un messaggio chiaro sul display? ⚠️📟
In questo progetto realizzerai un sistema di diagnostica con display OLED, capace di controllare diversi ingressi e segnalare eventuali anomalie.
Arduino verificherà:
👉 Il progetto insegna a distinguere tra un semplice valore fuori soglia e un vero errore di sistema.
Vuoi fare in modo che Arduino riconosca automaticamente un problema e mostri un messaggio chiaro sul display? ⚠️📟
In questo progetto realizzerai un sistema di diagnostica con display OLED, capace di controllare diversi ingressi e segnalare eventuali anomalie.
Arduino verificherà:
- funzionamento del sensore DHT22;
- temperatura troppo elevata;
- luminosità troppo bassa;
- stato di un sensore porta;
- tensione di alimentazione simulata.
👉 Il progetto insegna a distinguere tra un semplice valore fuori soglia e un vero errore di sistema.
🎯 Cosa realizzerai
Con Arduino creerai un sistema che:
Con Arduino creerai un sistema che:
- 🌡️ controlla temperatura e umidità;
- 💡 misura la luminosità ambientale;
- 🚪 rileva lo stato di una porta;
- 🔋 controlla una tensione simulata;
- ⚠️ assegna un codice a ogni errore;
- 📟 mostra l’anomalia sul display OLED;
- 🔁 alterna più errori contemporaneamente;
- ✅ mostra una schermata normale quando tutto funziona;
- 🔘 permette di scorrere manualmente gli errori;
- ⏱️ utilizza millis() senza bloccare Arduino.
🧰 Materiale necessario
Il potenziometro simula la tensione di alimentazione del sistema.
- 1x Arduino UNO;
- 1x display OLED 0,96 pollici I2C SSD1306;
- 1x sensore DHT22;
- 1x resistenza da 10 kΩ, se utilizzi il sensore senza modulo;
- 1x fotoresistenza LDR;
- 1x resistenza da 10 kΩ per il partitore della fotoresistenza;
- 1x sensore magnetico reed switch;
- 1x potenziometro da 10 kΩ;
- 1x pulsante;
- cavetti jumper;
- breadboard;
- cavo USB.
Il potenziometro simula la tensione di alimentazione del sistema.
🛒 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 realizzare il progetto devi installare:
- Adafruit SSD1306;
- Adafruit GFX Library;
- DHT sensor library;
- Adafruit Unified Sensor.
🔌 Schema di collegamento
Display OLED SSD1306
Sensore DHT22
Se utilizzi un modulo già assemblato:
Fotoresistenza LDR
Realizza un partitore di tensione:
Potenziometro
Reed switch
Con il magnete vicino, il contatto viene normalmente letto come LOW.
Pulsante
Display OLED SSD1306
- VCC → 5V;
- GND → GND;
- SDA → A4;
- SCL → A5.
Sensore DHT22
Se utilizzi un modulo già assemblato:
- VCC → 5V;
- GND → GND;
- DATA → pin digitale 2.
Fotoresistenza LDR
Realizza un partitore di tensione:
- un terminale della fotoresistenza → 5V;
- terminale opposto → A0;
- resistenza da 10 kΩ tra A0 e GND.
Potenziometro
- terminale laterale → 5V;
- terminale laterale opposto → GND;
- terminale centrale → A1.
Reed switch
- un terminale → pin digitale 3;
- terminale opposto → GND.
Con il magnete vicino, il contatto viene normalmente letto come LOW.
Pulsante
- un terminale → pin digitale 4;
- terminale opposto → GND.
💻 Codice Arduino
Il programma controlla cinque possibili anomalie:
Quando non sono presenti errori, il display mostra:
SISTEMA OK
Se invece sono presenti più anomalie, Arduino le alterna automaticamente.
Il programma controlla cinque possibili anomalie:
- E01 → sensore DHT22 non disponibile;
- E02 → temperatura troppo elevata;
- E03 → luminosità troppo bassa;
- E04 → porta aperta;
- E05 → tensione simulata troppo bassa.
Quando non sono presenti errori, il display mostra:
SISTEMA OK
Se invece sono presenti più anomalie, Arduino le alterna automaticamente.
/*
============================================================
Progetto 135 - Display errori di sistema
Controlla sensori e mostra codici di errore su display OLED
============================================================
*/
#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
// Collegamenti degli altri componenti
#define PIN_PORTA 3
#define PIN_PULSANTE 4
#define PIN_LUCE A0
#define PIN_TENSIONE A1
// Soglie utilizzate per generare gli errori
const float SOGLIA_TEMPERATURA = 30.0;
const int SOGLIA_LUMINOSITA = 20;
const float SOGLIA_TENSIONE = 3.5;
// Intervalli temporali
const unsigned long INTERVALLO_LETTURA = 2000;
const unsigned long INTERVALLO_CAMBIO_ERRORE = 3000;
const unsigned long TEMPO_DEBOUNCE = 180;
// Numero massimo di errori gestiti
const byte NUMERO_ERRORI = 5;
// Oggetti utilizzati per display e sensore
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
DHT dht(PIN_DHT, TIPO_DHT);
// Tipi di errore disponibili
enum CodiceErrore {
ERRORE_DHT,
ERRORE_TEMPERATURA,
ERRORE_LUMINOSITA,
ERRORE_PORTA,
ERRORE_TENSIONE
};
// Array che contiene gli errori attualmente attivi
CodiceErrore erroriAttivi[NUMERO_ERRORI];
// Numero di errori presenti
byte numeroErroriAttivi = 0;
// Errore attualmente visualizzato
byte indiceErroreVisualizzato = 0;
// Valori letti dai sensori
float temperatura = 0.0;
int luminositaPercentuale = 0;
float tensione = 0.0;
// Stati del sistema
bool sensoreDhtValido = false;
bool portaAperta = false;
// Variabili temporali utilizzate da millis()
unsigned long ultimaLettura = 0;
unsigned long ultimoCambioErrore = 0;
unsigned long ultimaPressione = 0;
// Indica quando il display deve essere aggiornato
bool aggiornamentoDisplayRichiesto = true;
void setup() {
// Il reed switch e il pulsante sono collegati a GND
// e utilizzano le resistenze interne di Arduino
pinMode(PIN_PORTA, INPUT_PULLUP);
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
leggiSensori();
aggiornaElencoErrori();
mostraSchermata();
ultimaLettura = millis();
ultimoCambioErrore = millis();
aggiornamentoDisplayRichiesto = false;
}
void loop() {
// Controlla il pulsante per lo scorrimento manuale
gestisciPulsante();
// Controlla continuamente lo stato della porta
bool nuovoStatoPorta =
digitalRead(PIN_PORTA) == HIGH;
if (nuovoStatoPorta != portaAperta) {
portaAperta = nuovoStatoPorta;
aggiornaElencoErrori();
aggiornamentoDisplayRichiesto = true;
}
// Legge periodicamente tutti gli altri sensori
if (millis() - ultimaLettura >= INTERVALLO_LETTURA) {
ultimaLettura = millis();
leggiSensori();
aggiornaElencoErrori();
aggiornamentoDisplayRichiesto = true;
}
// Se sono presenti più errori,
// passa automaticamente al successivo
if (numeroErroriAttivi > 1 &&
millis() - ultimoCambioErrore >=
INTERVALLO_CAMBIO_ERRORE) {
ultimoCambioErrore = millis();
passaErroreSuccessivo();
aggiornamentoDisplayRichiesto = true;
}
// Ridisegna il display soltanto quando necessario
if (aggiornamentoDisplayRichiesto) {
mostraSchermata();
aggiornamentoDisplayRichiesto = false;
}
}
void leggiSensori() {
// Legge la temperatura dal DHT22
float nuovaTemperatura = dht.readTemperature();
// Se la lettura non è valida,
// segnala un errore di comunicazione
if (isnan(nuovaTemperatura)) {
sensoreDhtValido = false;
} else {
sensoreDhtValido = true;
temperatura = nuovaTemperatura;
}
// Legge il partitore formato da LDR
// e resistenza da 10 kΩ
int valoreLuce = analogRead(PIN_LUCE);
// Converte la lettura in percentuale
luminositaPercentuale = map(
valoreLuce,
0,
1023,
0,
100
);
luminositaPercentuale = constrain(
luminositaPercentuale,
0,
100
);
// Legge il potenziometro che simula
// la tensione di alimentazione
int valoreTensione = analogRead(PIN_TENSIONE);
// Converte il valore analogico in volt
tensione =
valoreTensione * (5.0 / 1023.0);
}
void aggiornaElencoErrori() {
// Ricostruisce completamente l'elenco
// degli errori presenti nel sistema
numeroErroriAttivi = 0;
// E01: il sensore DHT22 non risponde
if (!sensoreDhtValido) {
aggiungiErrore(ERRORE_DHT);
}
// E02: la temperatura supera la soglia
if (sensoreDhtValido &&
temperatura >= SOGLIA_TEMPERATURA) {
aggiungiErrore(ERRORE_TEMPERATURA);
}
// E03: la luminosità è troppo bassa
if (luminositaPercentuale <=
SOGLIA_LUMINOSITA) {
aggiungiErrore(ERRORE_LUMINOSITA);
}
// E04: il reed switch segnala porta aperta
if (portaAperta) {
aggiungiErrore(ERRORE_PORTA);
}
// E05: la tensione simulata è troppo bassa
if (tensione <= SOGLIA_TENSIONE) {
aggiungiErrore(ERRORE_TENSIONE);
}
// Mantiene l'indice nei limiti
if (numeroErroriAttivi == 0) {
indiceErroreVisualizzato = 0;
} else if (
indiceErroreVisualizzato >= numeroErroriAttivi
) {
indiceErroreVisualizzato = 0;
}
}
void aggiungiErrore(CodiceErrore errore) {
// Aggiunge il codice all'array
// soltanto se esiste ancora spazio
if (numeroErroriAttivi < NUMERO_ERRORI) {
erroriAttivi[numeroErroriAttivi] = errore;
numeroErroriAttivi++;
}
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW
if (digitalRead(PIN_PULSANTE) == LOW &&
millis() - ultimaPressione >=
TEMPO_DEBOUNCE) {
ultimaPressione = millis();
// Scorre gli errori soltanto
// quando almeno uno è presente
if (numeroErroriAttivi > 0) {
passaErroreSuccessivo();
ultimoCambioErrore = millis();
aggiornamentoDisplayRichiesto = true;
}
}
}
void passaErroreSuccessivo() {
// Se non ci sono errori, non esegue nulla
if (numeroErroriAttivi == 0) {
return;
}
indiceErroreVisualizzato++;
// Dopo l'ultimo errore torna al primo
if (indiceErroreVisualizzato >=
numeroErroriAttivi) {
indiceErroreVisualizzato = 0;
}
}
void mostraSchermata() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// Se sono presenti errori,
// mostra la schermata diagnostica
if (numeroErroriAttivi > 0) {
mostraErroreAttivo();
} else {
mostraSistemaOk();
}
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraSistemaOk() {
display.setTextSize(1);
// Titolo e stato generale
display.setCursor(0, 0);
display.print("DIAGNOSTICA");
display.setCursor(79, 0);
display.print("SISTEMA OK");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Temperatura corrente
display.setCursor(0, 16);
display.print("Temp: ");
if (sensoreDhtValido) {
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
} else {
display.print("ERR");
}
// Luminosità corrente
display.setCursor(0, 28);
display.print("Luce: ");
display.print(luminositaPercentuale);
display.print("%");
// Tensione simulata
display.setCursor(0, 40);
display.print("Tensione: ");
display.print(tensione, 2);
display.print("V");
// Stato della porta
display.setCursor(0, 52);
display.print("Porta: ");
if (portaAperta) {
display.print("APERTA");
} else {
display.print("CHIUSA");
}
}
void mostraErroreAttivo() {
// Recupera il codice da visualizzare
CodiceErrore errore =
erroriAttivi[indiceErroreVisualizzato];
// Disegna un bordo attorno al messaggio
display.drawRect(
0,
0,
128,
64,
SSD1306_WHITE
);
display.setTextSize(1);
// Mostra la posizione nell'elenco
display.setCursor(4, 4);
display.print("Errore ");
display.print(indiceErroreVisualizzato + 1);
display.print("/");
display.print(numeroErroriAttivi);
// Mostra codice, titolo e descrizione
switch (errore) {
case ERRORE_DHT:
mostraMessaggioErrore(
"E01",
"ERRORE DHT22",
"Controlla sensore"
);
break;
case ERRORE_TEMPERATURA:
mostraMessaggioErrore(
"E02",
"TEMP. ELEVATA",
"Raffredda ambiente"
);
break;
case ERRORE_LUMINOSITA:
mostraMessaggioErrore(
"E03",
"LUCE BASSA",
"Controlla ambiente"
);
break;
case ERRORE_PORTA:
mostraMessaggioErrore(
"E04",
"PORTA APERTA",
"Chiudi ingresso"
);
break;
case ERRORE_TENSIONE:
mostraMessaggioErrore(
"E05",
"TENSIONE BASSA",
"Controlla aliment."
);
break;
}
display.setCursor(13, 54);
display.print("Premi: prossimo");
}
void mostraMessaggioErrore(
const char* codice,
const char* titolo,
const char* descrizione
) {
// Mostra il codice con caratteri grandi
display.setTextSize(2);
display.setCursor(46, 15);
display.print(codice);
// Mostra titolo e descrizione
display.setTextSize(1);
centraTesto(titolo, 36);
centraTesto(descrizione, 46);
}
void centraTesto(
const char* testo,
int coordinataY
) {
int16_t x1;
int16_t y1;
uint16_t larghezza;
uint16_t altezza;
// Calcola la dimensione della scritta
display.getTextBounds(
testo,
0,
coordinataY,
&x1,
&y1,
&larghezza,
&altezza
);
// Calcola la posizione necessaria
// per centrare il testo orizzontalmente
int coordinataX =
(LARGHEZZA_DISPLAY - larghezza) / 2;
display.setCursor(
coordinataX,
coordinataY
);
display.print(testo);
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(16, 15);
display.print("Diagnostica sistema");
display.setCursor(23, 31);
display.print("Display errori");
display.setCursor(28, 47);
display.print("Progetto 135");
display.display();
delay(1800);
}
============================================================
Progetto 135 - Display errori di sistema
Controlla sensori e mostra codici di errore su display OLED
============================================================
*/
#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
// Collegamenti degli altri componenti
#define PIN_PORTA 3
#define PIN_PULSANTE 4
#define PIN_LUCE A0
#define PIN_TENSIONE A1
// Soglie utilizzate per generare gli errori
const float SOGLIA_TEMPERATURA = 30.0;
const int SOGLIA_LUMINOSITA = 20;
const float SOGLIA_TENSIONE = 3.5;
// Intervalli temporali
const unsigned long INTERVALLO_LETTURA = 2000;
const unsigned long INTERVALLO_CAMBIO_ERRORE = 3000;
const unsigned long TEMPO_DEBOUNCE = 180;
// Numero massimo di errori gestiti
const byte NUMERO_ERRORI = 5;
// Oggetti utilizzati per display e sensore
Adafruit_SSD1306 display(
LARGHEZZA_DISPLAY,
ALTEZZA_DISPLAY,
&Wire,
RESET_OLED
);
DHT dht(PIN_DHT, TIPO_DHT);
// Tipi di errore disponibili
enum CodiceErrore {
ERRORE_DHT,
ERRORE_TEMPERATURA,
ERRORE_LUMINOSITA,
ERRORE_PORTA,
ERRORE_TENSIONE
};
// Array che contiene gli errori attualmente attivi
CodiceErrore erroriAttivi[NUMERO_ERRORI];
// Numero di errori presenti
byte numeroErroriAttivi = 0;
// Errore attualmente visualizzato
byte indiceErroreVisualizzato = 0;
// Valori letti dai sensori
float temperatura = 0.0;
int luminositaPercentuale = 0;
float tensione = 0.0;
// Stati del sistema
bool sensoreDhtValido = false;
bool portaAperta = false;
// Variabili temporali utilizzate da millis()
unsigned long ultimaLettura = 0;
unsigned long ultimoCambioErrore = 0;
unsigned long ultimaPressione = 0;
// Indica quando il display deve essere aggiornato
bool aggiornamentoDisplayRichiesto = true;
void setup() {
// Il reed switch e il pulsante sono collegati a GND
// e utilizzano le resistenze interne di Arduino
pinMode(PIN_PORTA, INPUT_PULLUP);
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
leggiSensori();
aggiornaElencoErrori();
mostraSchermata();
ultimaLettura = millis();
ultimoCambioErrore = millis();
aggiornamentoDisplayRichiesto = false;
}
void loop() {
// Controlla il pulsante per lo scorrimento manuale
gestisciPulsante();
// Controlla continuamente lo stato della porta
bool nuovoStatoPorta =
digitalRead(PIN_PORTA) == HIGH;
if (nuovoStatoPorta != portaAperta) {
portaAperta = nuovoStatoPorta;
aggiornaElencoErrori();
aggiornamentoDisplayRichiesto = true;
}
// Legge periodicamente tutti gli altri sensori
if (millis() - ultimaLettura >= INTERVALLO_LETTURA) {
ultimaLettura = millis();
leggiSensori();
aggiornaElencoErrori();
aggiornamentoDisplayRichiesto = true;
}
// Se sono presenti più errori,
// passa automaticamente al successivo
if (numeroErroriAttivi > 1 &&
millis() - ultimoCambioErrore >=
INTERVALLO_CAMBIO_ERRORE) {
ultimoCambioErrore = millis();
passaErroreSuccessivo();
aggiornamentoDisplayRichiesto = true;
}
// Ridisegna il display soltanto quando necessario
if (aggiornamentoDisplayRichiesto) {
mostraSchermata();
aggiornamentoDisplayRichiesto = false;
}
}
void leggiSensori() {
// Legge la temperatura dal DHT22
float nuovaTemperatura = dht.readTemperature();
// Se la lettura non è valida,
// segnala un errore di comunicazione
if (isnan(nuovaTemperatura)) {
sensoreDhtValido = false;
} else {
sensoreDhtValido = true;
temperatura = nuovaTemperatura;
}
// Legge il partitore formato da LDR
// e resistenza da 10 kΩ
int valoreLuce = analogRead(PIN_LUCE);
// Converte la lettura in percentuale
luminositaPercentuale = map(
valoreLuce,
0,
1023,
0,
100
);
luminositaPercentuale = constrain(
luminositaPercentuale,
0,
100
);
// Legge il potenziometro che simula
// la tensione di alimentazione
int valoreTensione = analogRead(PIN_TENSIONE);
// Converte il valore analogico in volt
tensione =
valoreTensione * (5.0 / 1023.0);
}
void aggiornaElencoErrori() {
// Ricostruisce completamente l'elenco
// degli errori presenti nel sistema
numeroErroriAttivi = 0;
// E01: il sensore DHT22 non risponde
if (!sensoreDhtValido) {
aggiungiErrore(ERRORE_DHT);
}
// E02: la temperatura supera la soglia
if (sensoreDhtValido &&
temperatura >= SOGLIA_TEMPERATURA) {
aggiungiErrore(ERRORE_TEMPERATURA);
}
// E03: la luminosità è troppo bassa
if (luminositaPercentuale <=
SOGLIA_LUMINOSITA) {
aggiungiErrore(ERRORE_LUMINOSITA);
}
// E04: il reed switch segnala porta aperta
if (portaAperta) {
aggiungiErrore(ERRORE_PORTA);
}
// E05: la tensione simulata è troppo bassa
if (tensione <= SOGLIA_TENSIONE) {
aggiungiErrore(ERRORE_TENSIONE);
}
// Mantiene l'indice nei limiti
if (numeroErroriAttivi == 0) {
indiceErroreVisualizzato = 0;
} else if (
indiceErroreVisualizzato >= numeroErroriAttivi
) {
indiceErroreVisualizzato = 0;
}
}
void aggiungiErrore(CodiceErrore errore) {
// Aggiunge il codice all'array
// soltanto se esiste ancora spazio
if (numeroErroriAttivi < NUMERO_ERRORI) {
erroriAttivi[numeroErroriAttivi] = errore;
numeroErroriAttivi++;
}
}
void gestisciPulsante() {
// Con INPUT_PULLUP il pulsante premuto
// viene letto come livello LOW
if (digitalRead(PIN_PULSANTE) == LOW &&
millis() - ultimaPressione >=
TEMPO_DEBOUNCE) {
ultimaPressione = millis();
// Scorre gli errori soltanto
// quando almeno uno è presente
if (numeroErroriAttivi > 0) {
passaErroreSuccessivo();
ultimoCambioErrore = millis();
aggiornamentoDisplayRichiesto = true;
}
}
}
void passaErroreSuccessivo() {
// Se non ci sono errori, non esegue nulla
if (numeroErroriAttivi == 0) {
return;
}
indiceErroreVisualizzato++;
// Dopo l'ultimo errore torna al primo
if (indiceErroreVisualizzato >=
numeroErroriAttivi) {
indiceErroreVisualizzato = 0;
}
}
void mostraSchermata() {
// Pulisce completamente il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// Se sono presenti errori,
// mostra la schermata diagnostica
if (numeroErroriAttivi > 0) {
mostraErroreAttivo();
} else {
mostraSistemaOk();
}
// Invia al display tutti gli elementi disegnati
display.display();
}
void mostraSistemaOk() {
display.setTextSize(1);
// Titolo e stato generale
display.setCursor(0, 0);
display.print("DIAGNOSTICA");
display.setCursor(79, 0);
display.print("SISTEMA OK");
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// Temperatura corrente
display.setCursor(0, 16);
display.print("Temp: ");
if (sensoreDhtValido) {
display.print(temperatura, 1);
display.print((char)247);
display.print("C");
} else {
display.print("ERR");
}
// Luminosità corrente
display.setCursor(0, 28);
display.print("Luce: ");
display.print(luminositaPercentuale);
display.print("%");
// Tensione simulata
display.setCursor(0, 40);
display.print("Tensione: ");
display.print(tensione, 2);
display.print("V");
// Stato della porta
display.setCursor(0, 52);
display.print("Porta: ");
if (portaAperta) {
display.print("APERTA");
} else {
display.print("CHIUSA");
}
}
void mostraErroreAttivo() {
// Recupera il codice da visualizzare
CodiceErrore errore =
erroriAttivi[indiceErroreVisualizzato];
// Disegna un bordo attorno al messaggio
display.drawRect(
0,
0,
128,
64,
SSD1306_WHITE
);
display.setTextSize(1);
// Mostra la posizione nell'elenco
display.setCursor(4, 4);
display.print("Errore ");
display.print(indiceErroreVisualizzato + 1);
display.print("/");
display.print(numeroErroriAttivi);
// Mostra codice, titolo e descrizione
switch (errore) {
case ERRORE_DHT:
mostraMessaggioErrore(
"E01",
"ERRORE DHT22",
"Controlla sensore"
);
break;
case ERRORE_TEMPERATURA:
mostraMessaggioErrore(
"E02",
"TEMP. ELEVATA",
"Raffredda ambiente"
);
break;
case ERRORE_LUMINOSITA:
mostraMessaggioErrore(
"E03",
"LUCE BASSA",
"Controlla ambiente"
);
break;
case ERRORE_PORTA:
mostraMessaggioErrore(
"E04",
"PORTA APERTA",
"Chiudi ingresso"
);
break;
case ERRORE_TENSIONE:
mostraMessaggioErrore(
"E05",
"TENSIONE BASSA",
"Controlla aliment."
);
break;
}
display.setCursor(13, 54);
display.print("Premi: prossimo");
}
void mostraMessaggioErrore(
const char* codice,
const char* titolo,
const char* descrizione
) {
// Mostra il codice con caratteri grandi
display.setTextSize(2);
display.setCursor(46, 15);
display.print(codice);
// Mostra titolo e descrizione
display.setTextSize(1);
centraTesto(titolo, 36);
centraTesto(descrizione, 46);
}
void centraTesto(
const char* testo,
int coordinataY
) {
int16_t x1;
int16_t y1;
uint16_t larghezza;
uint16_t altezza;
// Calcola la dimensione della scritta
display.getTextBounds(
testo,
0,
coordinataY,
&x1,
&y1,
&larghezza,
&altezza
);
// Calcola la posizione necessaria
// per centrare il testo orizzontalmente
int coordinataX =
(LARGHEZZA_DISPLAY - larghezza) / 2;
display.setCursor(
coordinataX,
coordinataY
);
display.print(testo);
}
void mostraAvvio() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(16, 15);
display.print("Diagnostica sistema");
display.setCursor(23, 31);
display.print("Display errori");
display.setCursor(28, 47);
display.print("Progetto 135");
display.display();
delay(1800);
}
⚙️ Come funziona
Arduino legge periodicamente tutti i sensori.
Ogni valore viene confrontato con una soglia.
Le soglie iniziali sono:
Lo stato della porta viene invece letto direttamente dal reed switch.
Quando una condizione è fuori dai limiti, il relativo errore viene aggiunto all’elenco delle anomalie attive.
Arduino legge periodicamente tutti i sensori.
Ogni valore viene confrontato con una soglia.
Le soglie iniziali sono:
- temperatura massima: 30 °C;
- luminosità minima: 20%;
- tensione minima: 3,5V.
Lo stato della porta viene invece letto direttamente dal reed switch.
Quando una condizione è fuori dai limiti, il relativo errore viene aggiunto all’elenco delle anomalie attive.
⚠️ Codici di errore
Ogni errore possiede:
Per esempio:
E02
TEMPERATURA ALTA
Controlla ambiente
Questa organizzazione rende il sistema più facile da diagnosticare.
👉 In un progetto reale, i codici potrebbero essere riportati anche in un manuale tecnico.
Ogni errore possiede:
- un codice;
- un titolo;
- una breve descrizione.
Per esempio:
E02
TEMPERATURA ALTA
Controlla ambiente
Questa organizzazione rende il sistema più facile da diagnosticare.
👉 In un progetto reale, i codici potrebbero essere riportati anche in un manuale tecnico.
🔋 Controllo della tensione simulata
Il potenziometro genera un valore analogico compreso tra 0 e 1023.
Arduino lo converte in una tensione:
tensione = valoreAnalogico * (5.0 / 1023.0);
Quando il valore scende sotto 3,5V, viene attivato l’errore:
E05 - TENSIONE BASSA
👉 Per misurare una batteria reale con tensione superiore a 5V è necessario utilizzare un partitore correttamente dimensionato.
Il potenziometro genera un valore analogico compreso tra 0 e 1023.
Arduino lo converte in una tensione:
tensione = valoreAnalogico * (5.0 / 1023.0);
Quando il valore scende sotto 3,5V, viene attivato l’errore:
E05 - TENSIONE BASSA
👉 Per misurare una batteria reale con tensione superiore a 5V è necessario utilizzare un partitore correttamente dimensionato.
🌡️ Errore e soglia non sono la stessa cosa
Il progetto distingue due situazioni:
Se invece il sensore funziona ma misura una temperatura troppo alta, viene mostrato E02.
Questa distinzione è importante nei sistemi di diagnostica reali.
Il progetto distingue due situazioni:
- sensore non disponibile;
- valore valido ma fuori soglia.
Se invece il sensore funziona ma misura una temperatura troppo alta, viene mostrato E02.
Questa distinzione è importante nei sistemi di diagnostica reali.
🧠 Perché è un progetto importante
Con questo progetto impari a:
👉 Questa tecnica è utile per centraline, impianti domotici, robot, sistemi di sicurezza e automazioni industriali.
Con questo progetto impari a:
- creare un sistema di diagnostica;
- assegnare codici agli errori;
- controllare più sensori;
- distinguere guasti e valori fuori soglia;
- gestire più anomalie contemporaneamente;
- utilizzare array di errori;
- alternare messaggi sul display;
- misurare una tensione analogica;
- costruire una schermata di stato;
- organizzare il codice in funzioni.
👉 Questa tecnica è utile per centraline, impianti domotici, robot, sistemi di sicurezza e automazioni industriali.
🔄 Varianti possibili
Vuoi migliorare il progetto?
Vuoi migliorare il progetto?
- 🔊 aggiungi un buzzer di errore;
- 🚨 assegna priorità differenti agli allarmi;
- 💾 salva gli errori nella EEPROM;
- ⏰ registra data e ora con RTC DS3231;
- 📋 crea uno storico degli ultimi eventi;
- 🔘 aggiungi un pulsante per confermare gli errori;
- 💡 collega LED di stato differenti;
- 📶 invia gli errori tramite Wi-Fi;
- 🗃️ salva gli eventi su microSD;
- ⚡ controlla automaticamente un relè;
- 🔒 aggiungi un errore per accesso non autorizzato;
- 🏠 integra il sistema in una centralina domotica.