🔠 Arduino • Matrice LED 8×8 • Testo

Matrice LED 8×8 con Arduino: lettere, simboli e scorrimento

Dopo il test dei collegamenti, impariamo a trasformare una griglia di 0 e 1 in lettere e disegni e a farli scorrere sulla matrice LED 8×8.

DifficoltàIntermedia / Avanzata
Risoluzione8 × 8 pixel
ConcettiBitmap + multiplexing
In poche parole: ogni LED della matrice può essere rappresentato da un valore 0 oppure 1. Organizzando 64 valori in una griglia 8×8 possiamo disegnare lettere e simboli; spostando progressivamente le colonne otteniamo anche lo scorrimento del testo.

Dal test alla visualizzazione dei caratteri

Questo progetto è la continuazione diretta del test della matrice 8×8. Nel tutorial precedente verificavamo righe e colonne; qui utilizziamo la stessa struttura per visualizzare caratteri, disegni e sequenze scorrevoli.

← Rivedi il test della matrice 8×8

Come si crea una lettera

Nel progetto ogni disegno è descritto da una tabella di 65 valori: il primo elemento è un riempitivo e i successivi 64 rappresentano gli 8×8 LED della matrice. Un valore 1 indica un LED acceso, mentre 0 indica un LED spento.

Esempio carattere su matrice LED 8x8

Esempio di costruzione di un carattere tramite una matrice di 0 e 1. Nel sito la larghezza era automatica.

È una bitmap: puoi immaginare la matrice LED come un minuscolo display da 8×8 pixel. Ogni 1 è un pixel acceso, ogni 0 un pixel spento.

Materiale necessario

🔌 Arduino Uno
🔲 Matrice LED 8×8
〰️ 8 resistenze da 220 Ω
🧩 2 breadboard
🔗 Cavetti jumper

🧰 Kit Arduino consigliato

Molti progetti del sito utilizzano LED, resistenze, breadboard e cavetti. 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

Schema Arduino matrice LED 8x8 lettere e simboli

Schema . Anche questa immagine nel sito era impostata su larghezza automatica.

Mappatura di righe e colonne

Il cablaggio è lo stesso del progetto 32. Lo sketch usa 16 linee, comprese A0–A3 come uscite digitali.

ColonnaPinRigaPin
1D91A3
2D122A2
3D73D3
4D134D8
5D25D4
6D66D10
7A17D11
8D58A0

Esempio: una lettera come matrice di bit

Invece del vecchio array da 65 interi possiamo rappresentare in modo più leggibile ogni carattere con otto byte: ogni byte descrive una riga e ciascun bit corrisponde a un LED.

Esempio bitmap 8×8 della lettera M
// Ogni byte rappresenta una riga della matrice.
// 1 = LED acceso
// 0 = LED spento

const byte letteraM[8] = {
 B10000001,
 B11000011,
 B10100101,
 B10011001,
 B10000001,
 B10000001,
 B10000001,
 B00000000
};
Nota: l’orientamento effettivo può risultare ruotato o specchiato se la tua matrice ha una piedinatura diversa. In tal caso non è il carattere a essere “sbagliato”: va adattata la mappatura righe/colonne.

Codice Arduino commentato

Lo sketch è piuttosto lungo perché implementa manualmente caratteri, scorrimento e refresh. Qui sotto trovi una versione didattica più compatta che mantiene gli stessi concetti: cablaggio diretto, multiplexing e bitmap.

Matrice 8×8 – lettere e simboli con scorrimento
// ==========================================================
// MATRICE LED 8x8 CON ARDUINO
// Lettere, simboli e scorrimento
// ==========================================================

// Colonne: stessa mappatura del progetto
const int colonne[8] = {
 9, 12, 7, 13, 2, 6, A1, 5
};

// Righe: stessa mappatura del progetto
const int righe[8] = {
 A3, A2, 3, 8, 4, 10, 11, A0
};

// ----------------------------------------------------------
// Alcuni caratteri 8x8.
// Ogni elemento descrive una riga.
// ----------------------------------------------------------

const byte carR[8] = {
 B11100000,
 B10010000,
 B10010000,
 B11100000,
 B11000000,
 B10101000,
 B10010000,
 B00000000
};

const byte carI[8] = {
 B00100000,
 B00000000,
 B00100000,
 B00100000,
 B00100000,
 B00100000,
 B00010000,
 B00000000
};

const byte carM[8] = {
 B00000000,
 B00000000,
 B00000000,
 B01101100,
 B10010010,
 B10010010,
 B10010001,
 B00000000
};

const byte carN[8] = {
 B00000000,
 B00000000,
 B00000000,
 B11100000,
 B10010000,
 B10010000,
 B10010000,
 B00000000
};

// Buffer visualizzato sul display.
// Ogni byte rappresenta una colonna dello schermo.
byte schermo[8] = {0,0,0,0,0,0,0,0};

// ----------------------------------------------------------
// Spegne completamente la matrice.
// ----------------------------------------------------------
void spegniMatrice() {

 for (int i = 0; i < 8; i++) {
 digitalWrite(righe[i], LOW);
 digitalWrite(colonne[i], HIGH);
 }
}

// ----------------------------------------------------------
// Visualizza per alcuni millisecondi il contenuto
// del buffer "schermo" tramite multiplexing.
// ----------------------------------------------------------
void refreshMatrice(unsigned long durataMs) {

 unsigned long inizio = millis();

 while (millis() - inizio < durataMs) {

 for (int col = 0; col < 8; col++) {

 // Evita accensioni fantasma mentre
 // prepariamo la colonna successiva.
 spegniMatrice();

 // Per ogni riga controlla il bit
 // corrispondente nel buffer.
 for (int riga = 0; riga < 8; riga++) {

 bool acceso = bitRead(schermo[col], 7 - riga);

 digitalWrite(righe[riga], acceso ? HIGH : LOW);
 }

 // Nel cablaggio la colonna selezionata
 // viene portata LOW.
 digitalWrite(colonne[col], LOW);

 // Tempo molto breve per la persistenza visiva
 delayMicroseconds(800);
 }
 }

 spegniMatrice();
}

// ----------------------------------------------------------
// Converte una bitmap descritta per righe
// in otto colonne da inserire nel buffer.
// ----------------------------------------------------------
void caricaCarattere(const byte carattere[8]) {

 // Pulisce lo schermo
 for (int c = 0; c < 8; c++) {
 schermo[c] = 0;
 }

 // Legge riga e colonna del carattere
 for (int r = 0; r < 8; r++) {

 for (int c = 0; c < 8; c++) {

 // Controlla il bit della bitmap
 if (bitRead(carattere[r], 7 - c)) {

 // Inserisce il pixel nella colonna
 bitSet(schermo[c], 7 - r);
 }
 }
 }
}

// ----------------------------------------------------------
// Mostra un carattere fermo.
// ----------------------------------------------------------
void mostraCarattere(const byte carattere[8], int durata) {

 caricaCarattere(carattere);
 refreshMatrice(durata);
}

// ----------------------------------------------------------
// Fa entrare un carattere da destra.
// La nuova colonna viene aggiunta e tutto il buffer
// viene spostato verso sinistra.
// ----------------------------------------------------------
void scorriCarattere(const byte carattere[8]) {

 byte colonneCarattere[8] = {0,0,0,0,0,0,0,0};

 // Converte la bitmap in colonne
 for (int r = 0; r < 8; r++) {

 for (int c = 0; c < 8; c++) {

 if (bitRead(carattere[r], 7 - c)) {
 bitSet(colonneCarattere[c], 7 - r);
 }
 }
 }

 // Inserisce una colonna alla volta da destra
 for (int nuova = 0; nuova < 8; nuova++) {

 // Sposta tutte le colonne verso sinistra
 for (int c = 0; c < 7; c++) {
 schermo[c] = schermo[c + 1];
 }

 // Inserisce a destra la nuova colonna
 schermo[7] = colonneCarattere[nuova];

 // Mantiene visibile questa posizione
 // per creare l'effetto di movimento.
 refreshMatrice(90);
 }

 // Aggiunge una colonna vuota come spazio
 for (int c = 0; c < 7; c++) {
 schermo[c] = schermo[c + 1];
 }

 schermo[7] = 0;
 refreshMatrice(90);
}

void setup() {

 // Configura righe e colonne come uscite
 for (int i = 0; i < 8; i++) {
 pinMode(righe[i], OUTPUT);
 pinMode(colonne[i], OUTPUT);
 }

 spegniMatrice();
}

void loop() {

 // Lo sketch scorre la parola "Rimini".
 scorriCarattere(carR);
 scorriCarattere(carI);
 scorriCarattere(carM);
 scorriCarattere(carI);
 scorriCarattere(carN);
 scorriCarattere(carI);

 // Fa uscire completamente il testo
 // aggiungendo otto colonne vuote.
 for (int i = 0; i < 8; i++) {

 for (int c = 0; c < 7; c++) {
 schermo[c] = schermo[c + 1];
 }

 schermo[7] = 0;
 refreshMatrice(90);
 }

 delay(500);
}

Come funziona lo scorrimento

L’idea centrale è semplice: invece di ridisegnare istantaneamente un nuovo carattere, spostiamo tutto ciò che è già sul display di una colonna verso sinistra e inseriamo una nuova colonna sul lato destro.

PassaggioCosa accade
1Si prepara il carattere come matrice 8×8
2Si estrae una colonna alla volta
3Il contenuto corrente scorre verso sinistra
4La nuova colonna entra da destra
5Il multiplexing mantiene visibile il risultato

La parola usata nello sketch

Nel programma vengono caricati in sequenza i caratteri R, i, m, i, n, i, formando la parola “Rimini”. Ogni carattere viene copiato in un’area di lavoro e poi passato alla routine di scorrimento.

Per cambiare testo: devi creare nuove bitmap 8×8 e richiamarle nell’ordine desiderato. Lo stesso principio può essere usato per nomi, abbreviazioni, simboli e piccole animazioni.

Il refresh della matrice

Una matrice collegata direttamente ad Arduino deve essere continuamente aggiornata. La routine di refresh seleziona una colonna alla volta e accende le righe necessarie. Se questo processo è abbastanza rapido, l’occhio vede l’intera immagine stabile.

Perché il codice usa aree di lavoro

Nel sketch trovi array come comodo, carcomodo e colonna. Servono come buffer temporanei: prima viene copiato il carattere da mostrare, poi vengono estratte le colonne necessarie allo scorrimento e infine viene aggiornata la matrice visibile.

Creare i tuoi simboli

Puoi disegnare un simbolo su carta quadrettata 8×8 e trasformare ogni casella in 0 oppure 1. Per esempio un cuore potrebbe essere descritto così:

Esempio bitmap cuore 8×8
const byte cuore[8] = {
 B00000000,
 B01100110,
 B11111111,
 B11111111,
 B01111110,
 B00111100,
 B00011000,
 B00000000
};

Limiti della matrice collegata direttamente

Questo approccio occupa 16 pin e richiede che Arduino si occupi continuamente del refresh. È molto utile per imparare, ma per testi e animazioni più complesse è più pratico usare un driver come MAX7219.

Con MAX7219: il microcontrollore invia i dati al driver e non deve più pilotare manualmente tutte le 16 linee della matrice. Diventa molto più facile concatenare più moduli e creare scritte lunghe.

Scarica lo sketch

⬇️ Scarica arduino_matrice_led_finito_sketch.ino

Debug rapido

  • verifica prima il circuito con il Progetto 32;
  • controlla orientamento e piedinatura della matrice;
  • se il carattere è specchiato, inverti l’ordine delle colonne;
  • se è capovolto, inverti l’ordine delle righe;
  • se il display sfarfalla, riduci il tempo di refresh per colonna;
  • se compaiono LED fantasma, spegni righe e colonne prima di selezionare quella successiva;
  • se una parte del carattere manca, verifica la bitmap e il relativo collegamento.

Varianti del progetto

  • creare un alfabeto completo 8×8;
  • visualizzare numeri e punteggiatura;
  • creare faccine e icone;
  • regolare la velocità di scorrimento con un potenziometro;
  • ricevere il testo dalla porta seriale;
  • passare a MAX7219 per concatenare più matrici;
  • memorizzare i font in PROGMEM per risparmiare RAM.

Cosa devi ricordare

  • Ogni carattere è una bitmap 8×8.
  • Un valore 1 rappresenta un LED acceso e 0 un LED spento.
  • Il display deve essere continuamente multiplexato.
  • Lo scorrimento avviene spostando il buffer di una colonna alla volta.
  • Il cablaggio è lo stesso del progetto di test precedente.
  • Per progetti più complessi conviene usare un driver dedicato.

Domande frequenti

Perché il carattere appare specchiato?

La sequenza delle colonne della tua matrice potrebbe essere invertita rispetto alla mappatura usata nel codice. Puoi invertire l’ordine dell’array delle colonne oppure quello dei bit.

Come creo una nuova lettera?

Disegnala su una griglia 8×8 e converti ogni riga in una sequenza di 0 e 1. Poi inserisci la bitmap nel programma e richiamala nella sequenza desiderata.

Posso far scorrere una frase lunga?

Sì, ma con il collegamento diretto il codice e la gestione diventano rapidamente più complessi. Per scritte lunghe è più pratico usare uno o più moduli MAX7219.

Perché lo sketch usa 65 elementi e non 64?

Il primo elemento è un valore di riempimento non utilizzato; i successivi 64 corrispondono realmente agli 8×8 LED della matrice.