⏱️ Arduino • Timer • Display 4 cifre

Timer con Arduino e display a 4 cifre

Realizziamo un timer fino a 60 minuti con display a 7 segmenti multiplexato, pulsante di impostazione e buzzer di fine countdown.

DifficoltàIntermedia / Avanzata
DisplayHS410561K-32
Tempo massimo60 minuti
In poche parole: tenendo premuto il pulsante si imposta il numero di minuti. Quando il pulsante viene rilasciato parte il countdown, visualizzato come minuti e secondi sulle quattro cifre. Alla fine il buzzer suona per alcuni secondi.

Cosa imparerai

  • come funziona un display a 4 cifre multiplexato;
  • come condividere i segmenti tra più cifre;
  • come selezionare una cifra alla volta molto rapidamente;
  • come trasformare i secondi residui in minuti e secondi;
  • come impostare un timer tramite pulsante;
  • come gestire il countdown con millis();
  • come attivare un buzzer alla fine del tempo.

Come funziona il progetto

Il progetto utilizza un display a quattro cifre modello HS410561K-32. Il timer può essere impostato fino a circa un’ora tramite un pulsante; al termine del conto alla rovescia Arduino attiva un buzzer.

Arduino timer display 4 cifre
Timer Arduino 4 cifre

Esempi del timer con display a quattro cifre.

Materiale necessario

🔌 Arduino Uno
🔢 Display 4 cifre HS410561K-32
〰️ 8 resistenze da 220 Ω
〰️ 1 resistenza da 10 kΩ
🔊 Buzzer
🔘 Pulsante
🧩 Breadboard
🔗 Cavetti jumper

🧰 Kit Arduino consigliato

Molti progetti del sito utilizzano display, pulsanti, buzzer, resistenze e breadboard. Un kit completo può essere comodo per iniziare.

👉 Guarda il 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?

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.

Schema del circuito

Il circuito è mostrato in due immagini per maggiore chiarezza, ma fisicamente va realizzato come un unico circuito.

Schema collegamento display 4 cifre Arduino

Schema di collegamento del display a quattro cifre.

Schema buzzer e pulsante timer Arduino 4 cifre

Schema collegamento buzzer e pulsante.

Pin utilizzati nello sketch

FunzionePin Arduino
BuzzerD0
Segmenti display + puntoD1–D8
Selezione delle 4 cifreD9–D12
Pulsante impostazioneD13
Attenzione a D0 e D1: lo sketch occupa entrambi i pin della seriale hardware di Arduino Uno. Per questo non puoi usare normalmente il Monitor Seriale mentre il circuito è cablato in questo modo. Se vuoi liberare RX e TX puoi spostare buzzer e segmenti su altri pin oppure usare un driver dedicato.

Che cos’è il multiplexing

Un display a quattro cifre non richiede sette pin separati per ogni cifra. I segmenti a–g vengono condivisi, mentre quattro pin aggiuntivi selezionano quale cifra deve essere accesa.

Arduino attiva una cifra, imposta i suoi segmenti, la spegne e passa immediatamente alla successiva. Ripetendo il ciclo abbastanza velocemente, l’occhio percepisce tutte e quattro le cifre come accese contemporaneamente.

Concetto chiave: i pin D9–D12 selezionano le quattro cifre, mentre D1–D8 controllano segmenti e punto decimale.

Formato del tempo

CifraContenuto
1ª da sinistraDecine di minuti
2ªUnità di minuti
3ªDecine di secondi
4ªUnità di secondi

Il punto decimale della seconda cifra viene utilizzato come separatore visivo tra minuti e secondi.

Codice Arduino commentato

Timer 4 cifre – codice commentato
// ==========================================================
// TIMER ARDUINO CON DISPLAY A 4 CIFRE
// Cablaggio basato sul progetto HS410561K-32
// ==========================================================

// Buzzer collegato al pin D0.
// NOTA: D0 è anche RX della seriale hardware.
const int buzzerPin = 0;

// Segmenti nell'ordine a, b, c, d, e, f, g.
// Mappatura dei segmenti utilizzata nel progetto.
const int segmenti[7] = {
 3, // a
 4, // b
 6, // c
 7, // d
 8, // e
 2, // f
 1 // g
};

// Punto decimale
const int puntoPin = 5;

// Pin che selezionano le quattro cifre
const int cifrePin[4] = {9, 10, 11, 12};

// Pulsante di impostazione del tempo
const int pulsantePin = 13;

// Tabella dei segmenti per i numeri 0...9.
// Ordine: a,b,c,d,e,f,g
const bool numeri[10][7] = {
 {1,1,1,1,1,1,0}, // 0
 {0,1,1,0,0,0,0}, // 1
 {1,1,0,1,1,0,1}, // 2
 {1,1,1,1,0,0,1}, // 3
 {0,1,1,0,0,1,1}, // 4
 {1,0,1,1,0,1,1}, // 5
 {1,0,1,1,1,1,1}, // 6
 {1,1,1,0,0,0,0}, // 7
 {1,1,1,1,1,1,1}, // 8
 {1,1,1,1,0,1,1} // 9
};

// Minuti scelti dall'utente
int minutiImpostati = 0;

// Secondi rimanenti durante il countdown
long secondiResidui = 0;

// Momento di riferimento del countdown
unsigned long ultimoSecondo = 0;

// Indice della cifra multiplexata
int cifraCorrente = 0;

// Momento dell'ultimo cambio cifra
unsigned long ultimoRefresh = 0;

// Stato del timer
bool timerAttivo = false;

// ----------------------------------------------------------
// Spegne tutte le cifre.
// Le cifre vengono attivate portando il relativo pin HIGH.
// ----------------------------------------------------------
void spegniCifre() {
 for (int i = 0; i < 4; i++) {
 digitalWrite(cifrePin[i], LOW);
 }
}

// ----------------------------------------------------------
// Imposta i segmenti per visualizzare una cifra.
// I segmenti sono attivi LOW in questo cablaggio.
// ----------------------------------------------------------
void impostaNumero(int numero) {

 for (int i = 0; i < 7; i++) {

 if (numeri[numero][i]) {
 digitalWrite(segmenti[i], LOW);
 } else {
 digitalWrite(segmenti[i], HIGH);
 }
 }
}

// ----------------------------------------------------------
// Aggiorna rapidamente una sola cifra del display.
// Va richiamata molto spesso dal loop().
// ----------------------------------------------------------
void aggiornaDisplay(long secondiDaMostrare) {

 // Limita il valore al formato massimo 59:59.
 if (secondiDaMostrare < 0) secondiDaMostrare = 0;
 if (secondiDaMostrare > 3599) secondiDaMostrare = 3599;

 int minuti = secondiDaMostrare / 60;
 int secondi = secondiDaMostrare % 60;

 int valori[4] = {
 minuti / 10,
 minuti % 10,
 secondi / 10,
 secondi % 10
 };

 // Aggiorna una cifra circa ogni 2 ms.
 if (millis() - ultimoRefresh >= 2) {

 ultimoRefresh = millis();

 // Prima spegne tutte le cifre
 // per evitare immagini fantasma.
 spegniCifre();

 // Prepara i segmenti della cifra corrente
 impostaNumero(valori[cifraCorrente]);

 // Punto decimale come separatore minuti/secondi.
 // È associato alla seconda cifra.
 if (cifraCorrente == 1) {
 digitalWrite(puntoPin, LOW);
 } else {
 digitalWrite(puntoPin, HIGH);
 }

 // Accende soltanto la cifra corrente
 digitalWrite(cifrePin[cifraCorrente], HIGH);

 // Passa alla cifra successiva
 cifraCorrente++;

 if (cifraCorrente > 3) {
 cifraCorrente = 0;
 }
 }
}

// ----------------------------------------------------------
// Impostazione del tempo.
// Tenendo premuto il pulsante, aumenta di un minuto
// circa ogni secondo, fino a 60 e poi riparte da zero.
// ----------------------------------------------------------
void impostaTempo() {

 unsigned long inizioPressione = millis();
 int ultimoMinutoMostrato = -1;

 while (digitalRead(pulsantePin) == HIGH) {

 unsigned long trascorso = millis() - inizioPressione;

 // 1 secondo di pressione = 1 minuto impostato
 int nuovoValore = trascorso / 1000;

 // Dopo 60 minuti riparte da 0
 nuovoValore = nuovoValore % 61;

 if (nuovoValore != ultimoMinutoMostrato) {
 minutiImpostati = nuovoValore;
 ultimoMinutoMostrato = nuovoValore;
 }

 // Durante l'impostazione mostra MM:00
 aggiornaDisplay((long)minutiImpostati * 60);
 }

 // Se è stato scelto almeno un minuto,
 // prepara e avvia il countdown.
 if (minutiImpostati > 0) {
 secondiResidui = (long)minutiImpostati * 60;
 ultimoSecondo = millis();
 timerAttivo = true;
 }
}

// ----------------------------------------------------------
// Segnalazione acustica finale.
// Mantiene il buzzer attivo per circa 5 secondi.
// ----------------------------------------------------------
void allarmeFine() {

 unsigned long inizio = millis();

 digitalWrite(buzzerPin, HIGH);

 while (millis() - inizio < 5000) {

 // Continua a mostrare 00:00
 // mentre il buzzer è attivo.
 aggiornaDisplay(0);
 }

 digitalWrite(buzzerPin, LOW);
}

void setup() {

 // Configura i segmenti
 for (int i = 0; i < 7; i++) {
 pinMode(segmenti[i], OUTPUT);
 digitalWrite(segmenti[i], HIGH);
 }

 // Punto decimale
 pinMode(puntoPin, OUTPUT);
 digitalWrite(puntoPin, HIGH);

 // Selezione delle quattro cifre
 for (int i = 0; i < 4; i++) {
 pinMode(cifrePin[i], OUTPUT);
 digitalWrite(cifrePin[i], LOW);
 }

 // Pulsante con resistenza esterna da 10 kΩ
 pinMode(pulsantePin, INPUT);

 // Buzzer
 pinMode(buzzerPin, OUTPUT);
 digitalWrite(buzzerPin, LOW);
}

void loop() {

 // Se il timer non è attivo,
 // mostra il tempo impostato oppure 00:00.
 if (!timerAttivo) {

 aggiornaDisplay((long)minutiImpostati * 60);

 // Pressione del pulsante = modalità impostazione
 if (digitalRead(pulsantePin) == HIGH) {
 impostaTempo();
 }

 return;
 }

 // Durante il countdown il display va aggiornato
 // continuamente per mantenere il multiplexing.
 aggiornaDisplay(secondiResidui);

 // Ogni secondo riduce il tempo residuo.
 if (millis() - ultimoSecondo >= 1000) {

 ultimoSecondo += 1000;

 if (secondiResidui > 0) {
 secondiResidui--;
 }

 // Quando arriva a zero, termina il timer.
 if (secondiResidui <= 0) {

 timerAttivo = false;

 allarmeFine();

 // Torna pronto per una nuova impostazione.
 minutiImpostati = 0;
 secondiResidui = 0;
 }
 }
}

Come funziona il multiplexing nel codice

La funzione aggiornaDisplay() non accende tutte le cifre contemporaneamente. Ne attiva una alla volta, cambia cifra ogni pochi millisecondi e ripete il ciclo continuamente.

FaseOperazione
1Spegne tutte le cifre
2Imposta i segmenti del numero
3Accende la cifra corrente
4Passa alla cifra successiva

Come viene calcolato il tempo

Il tempo residuo viene conservato in secondi. Da questo unico valore ricaviamo le quattro cifre:

Conversione in minuti e secondi
int minuti = secondiResidui / 60;
int secondi = secondiResidui % 60;

int decineMinuti = minuti / 10;
int unitaMinuti = minuti % 10;

int decineSecondi = secondi / 10;
int unitaSecondi = secondi % 10;

L’operatore % restituisce il resto della divisione ed è molto utile per separare decine e unità.

Perché millis() è importante

Il progetto usa millis() per calcolare il tempo trascorso e il tempo residuo. È una scelta importante perché un display multiplexato deve continuare ad essere aggiornato molto rapidamente: un lungo delay() farebbe spegnere o sfarfallare le cifre.

Concetto chiave: in questo progetto millis() non serve soltanto per il countdown. Permette anche di tenere il programma reattivo mentre il display viene continuamente multiplexato.

Limiti del collegamento diretto

  • D0 viene usato dal buzzer, quindi occupa RX.
  • D1 viene usato da un segmento, quindi occupa TX.
  • quasi tutti i pin digitali di Arduino Uno risultano impegnati;
  • la seriale hardware non è praticamente disponibile;
  • il cablaggio è molto più complesso rispetto a un modulo display con driver.

Come lo realizzeremmo oggi

Per semplificare il circuito puoi usare un modulo a quattro cifre con driver integrato, per esempio basato su TM1637 o MAX7219. Servirebbero molti meno pin e il software sarebbe più semplice.

Il collegamento diretto resta comunque un ottimo esercizio per capire davvero come funziona il multiplexing.

Scarica lo sketch

⬇️ Scarica arduino_countdown_4_cifre.ino

Debug rapido

  • verifica che il display sia realmente il modello previsto o abbia una piedinatura compatibile;
  • controlla la corrispondenza tra segmenti e pin D1–D8;
  • controlla le quattro linee di selezione cifra su D9–D12;
  • se alcune cifre sono invertite, verifica l’ordine dei quattro anodi;
  • se il display sfarfalla, controlla che il multiplexing venga eseguito abbastanza rapidamente;
  • se il pulsante non imposta il tempo, controlla D13 e la resistenza da 10 kΩ;
  • se il buzzer non suona, verifica D0 e il tipo di buzzer utilizzato.

Varianti del progetto

  • aggiungere un secondo pulsante per diminuire i minuti;
  • aggiungere start/stop separato;
  • implementare pausa e reset;
  • usare INPUT_PULLUP per semplificare il pulsante;
  • spostare buzzer e display lontano dai pin D0/D1;
  • usare TM1637 o MAX7219;
  • aggiungere memoria EEPROM per ricordare l’ultimo tempo.

Cosa devi ricordare

  • Il timer arriva fino a circa 60 minuti.
  • Il display mostra minuti e secondi su quattro cifre.
  • D9–D12 selezionano le cifre una alla volta.
  • D1–D8 comandano segmenti e punto decimale.
  • Il pulsante è su D13 e il buzzer su D0.
  • Il multiplexing deve essere aggiornato continuamente.
  • millis() permette di gestire il tempo senza bloccare il display.

Domande frequenti

Perché il display sembra avere tutte le cifre accese insieme?

È l’effetto del multiplexing: Arduino accende in realtà una cifra alla volta, ma lo fa abbastanza velocemente da ingannare la persistenza visiva dell’occhio.

Perché non posso usare facilmente il Monitor Seriale?

Perché il cablaggio usa D0 e D1, che su Arduino Uno sono RX e TX della seriale hardware.

Posso usare un display 4 cifre diverso?

Sì, ma devi verificarne piedinatura, tipo di comune e ordine delle cifre. Non è garantita la compatibilità diretta con HS410561K-32.

Posso usare un modulo TM1637?

Sì. Per un nuovo progetto è molto più semplice perché richiede pochissimi collegamenti e gestisce internamente il multiplexing.