Mi sono da poco arrivate quattro matrici LED 8×8 già montate su una pratica schedina dotata di controller, il famoso MAX 7219, e di header già saldati e quindi belle e pronte per essere posizionate su una spaziosa breadboard. Ho già fatto qualche semplice esperimento di base ma ora è il giunto il momento per iniziare un vero e proprio progetto “psichedelico”.
Nell’ultimo Week End Project (Matrici LED 8×8 con Arduino e MAX7219) troverete alcune informazioni di base per pilotare i singoli moduli 8×8 e una elaborazione del codice di base frutto delle prime sperimentazioni con i nuovi modulini.
L’idea che sta alla base di questo nuovo progetto è dare vita a una libreria per la gestione di matrici multiple attraverso la loro astrazione e la loro combinazione in una unica matrice LED virtuale di dimensioni pari a (Nx8)x8, dove N è il numero di moduli usati. Nel caso preso in esame, con quattro moduli, costruiremo una matrice (4×8)x8 ovvero 32×8.
Materiale necessario
Per completare gli esperimenti di questo post sarà necessario avere:
- 1 Arduino
- 4 Moduli matrice LED 8×8 con controller MAX 7219
- 1 Breadboard
- 28 Ponticelli da breadboard
Pilotare le singole matrici 8×8
Figura 1: La matrice 8×8 e il max 7219 montati sul modulo
Inizializzare e iniziare ad utilizzare una singola matrice è una operazione piuttosto semplice. Dopo aver effettuato i collegamenti necessari è sufficiente trasmettere i dati corretti sulla linea DIN (data in) sincronizzandoli con il clock inviato sulla linea CLK e impostare la linea CS in modo da generare una transizione LOW->HIGH. Per una dettagliata descrizione di come inizializzare ed utilizzare una matrice singola vi rimando all’articolo: Matrici LED 8×8 con Arduino e MAX7219 linkato all’inizio del post.
Quando vogliamo gestire più matrici contemporaneamente la questione si complica e per collegarle abbiamo a disposizione in linea di massima 2 opzioni:
- Collegamento in serie
- Collegamento in parallelo
La differenza sostanziale tra le due opzioni è l’utilizzo delle linee DIN/DOUT e CS e si riflette in come andrà realizzato il software di gestione.
Collegamento in serie
Nel collegamento in serie i pin Vcc, GND, CS e CLK di tutti i moduli sono collegati tra loro e ai rispettivi pin di Arduino mentre DIN e DOUT sono collegati in cascata (anche detta daisy chain): il pin DIN del primo modulo sarà collegato al pin di Arduino dal quale usciranno i dati per le matrici, il pin DIN del secondo modulo sarà collegato al pin DOUT del primo, il pin DIN del terzo al DOUT del secondo e così via.
Figura 2: Collegamento in serie
Per utilizzare con successo più matrici collegate in questo modo è necessario inviare 16xN bits di dati in modo da riempire tutti gli shift register delle N matrici prima di applicare ai pin CS, collegati in parallelo, la transizione LOW->HIGH.
Per primi andranno inviati i 16 bits da caricare nella ultima matrice della serie, seguiti da quelli per la penultima, fino alla prima. Se una matrice non deve ‘fare niente’ sarà comunque necessario inviare i 16 bits per caricare il suo shift register con un comando NOP (address 0x00, data 0x00).
Il vantaggio risiede nel fatto che indipendentemente dal numero di matrici utilizzate il numero di pin di Arduino necessari è limitato a 3 (Din, Cs e Clk).
Di contro, l’evidente svantaggio è la necessità di inviare una quantità di dati direttamente proporzionale al numero di matrici utilizzato (16xN bits) ogni volta che si deve modificare anche solo un registro di una singola matrice.
Collegamento in parallelo
Nel collegamento in parallelo i pin Vcc, GND, CLK e DIN di tutti i moduli sono collegati tra loro e ai rispettivi pin di Arduino mentre i pin CS di ciascun modulo sono collegati in modo indipendente ad altrettanti pin di Arduino (i pin DOUT non vengono utilizzati in questa configurazione).
In questo modo tutti gli shift register dei moduli vengono caricati contemporaneamente con i 16 bit trasmessi con una operazione write, ma solo il modulo che riceverà sul suo pin CS la transizione LOW->HIGH caricherà effettivamente i dati nel registro specificato.
Il vantaggio di questa configurazione è che è possibile indirizzare con una singola operazione di scrittura ogni registro di ogni matrice indipendentemente dal numero di matrici collegate.
L’evidente svantaggio è la necessità di disporre di un pin per matrice per il controllo del segnale CS, quindi N pin CS.
Figura 3: Collegamento in parallelo
La scelta per questo progetto
Per questo progetto ho deciso di collegare i moduli secondo lo schema parallelo. Questo perché ho intenzione di sviluppare un sistema di ottimizzazione dei dati inviati che permetta di modificare anche un singolo registro senza dover ritrasmettere tutti i dati di configurazione attraverso tutte le matrici nel momento in cui le variazioni della matrice virtuale lo consentano.
Figura 4: Collegamento delle N matrici a Arduino
Installazione della libreria
Per installare la libreria è sufficiente scaricare il file compresso linkato qui sotto e scompattarne il contenuto nella cartella delle librerie di Arduino. In alternativa se si utilizza il nuovo IDE 1.6.x è possibile utilizzare la apposita funzione di caricamento semplificato delle librerie.
- Download max7219array_library.zip
ATTENZIONE:
E’ disponibile un aggiornamento della libreria che include l’allocazione dinamica dei moduli e le funzioni di scroll del testo di dimensioni superiori a quelle della matrice virtuale. Trovi tutti i dettagli dell’aggiornamento qui:
Aggiornamento libreria max7219array
Dopo aver scaricato il file zip, aprire il menu Sketch, selezionare ‘Include Library’ e poi ‘Add .ZIP Librery…’. A questo punto selezionare il file zip appena scaricato e confermare il caricamento.
Figura 5: Installazione della libreria
Dopo aver riavviato l’IDE la libreria verrà visualizzata tra le librerie disponibili insieme agli esempi di utilizzo a corredo.
Figura 6: Lireria installata nell’IDE
Per chi preferisce, la libreria è disponibile per il download o il checkout anche su github all’indirizzo:
Inizializzazione e utilizzo base
Vediamo come iniziare a utilizzare la libreria partendo da uno sketch nuovo. Per prima cosa sarà necessario includere la libreria come di consueto si fa con le librerie built-in:
#include "max7219array.h"
Nel caso in cui vogliamo utilizzare le funzioni di scrittura sarà necessario includere anche un “font”, cioè una mappa di come dovranno accendersi i LED quando chiederemo alla libreria di visualizzare delle lettere sulla matrice virtuale. La libreria, oltre a consentire un utilizzo avanzato in cui definire i propri fontfles, offre la possibilità di scegliere tra due font inclusi nel pacchetto:
- font1: max7219_font_4px.h
- font2: max7219_font_5px.h
#include "max7219_font_4px.h"
Poi sarà necessario definire una variabile globale che rappresenti la matrice virtuale:
max7219array myMatrix;
Ora la classica funzione setup() in cui effettuare l’inizializzazione vera e propria. In questo caso, come esempio di base, ci limiteremo a inizializzare la matrice virtuale con i 4 moduli collegati come in Figura 4 e scrivere al suo interno la stringa “M-7219”.
Con i metodi setClkPin e setDinPin si potranno specificare quali pin di Arduino utilizzare per il clock e per i dati. In questo caso rispettivamente pin 10 e pin 8:
void setup() { myMatrix.setClkPin(10); myMatrix.setDinPin(8);
Poi, utilizzando il metodo addModule si potranno ‘presentare’ alla libreria le matrici che compongono l’array e specificare i pin CS che arduino dedicherà a ciascuna matrice:
myMatrix.addModule(13); myMatrix.addModule(12); myMatrix.addModule(11); myMatrix.addModule(9);
A questo punto la libreria si sarà già occupata di inizializzare tutti i moduli e caricare tutti i registri di configurazione dei LED a zero per presentare una matrice virtuale completamente spenta.
Ora è possibile iniziare a ‘disegnare’. Per questo esempio utilizzeremo il metodo plotstring che disegnerà sulla matrice virtuale la stringa passata come argomento usando il font incluso all’inizio dello sketch:
myMatrix.plotstring("M-7219");
Ultimo ma non meno importante il metodo che consente di visualizzare sugli N moduli reali ciò che è stato disegnato sulla matrice vrtuale:
myMatrix.flush(); }
Chiude lo scketch la funzione loop() che non deve mai mancare:
void loop() { myMatrix.rotateleft(); myMatrix.flush(); delay(100); }
Per questo sketch di esempio, nella funzione loop si effettua ciclicamente, con un periodo di 100 millisecondi, una rotazione di tutti i pixel della matrice virtuale verso sinistra e un flush della matrice virtuale sui moduli fisici per visualizzare effettivamente la rotazione.
Prossimi passi
Questa versione è la prima sufficientemente completa e stabile per essere utilizzata, ma presenta ancora alcuni aspetti da sviluppare:
- Rimuovere il limite per cui permette di aggiungere fino a 8 moduli e alloca il buffer per tutti e 8 staticamente.
- Non implementa ancora i meccanismi di ottimizzazione del ridisegnao della matrice virtuale.
- Non implementa ancora i metodi per lo scorrimento di testo la cui dimensione ecceda le dimensioni della matrice virtuale.
In attesa di queste nuove funzionalità e di un nuovo post con i relativi esempi usate i commenti qui sotto per segnalare eventuali comportamenti imprevisti e suggerire nuove funzionalità che pensate debbano essere aggiunte a questa libreria per renderla più adatta alle vostre esigenze.
Reference
Qui di seguito riporto tutti i metodi disponibili nella libreria, il formato dei parametri per chiamarli e il loro utilizzo.
Funzioni di inizializzazione
void setClkPin(byte clkPin);
Imposta il pin da utilizzare come linea di clock. Come parametro di deve passare il numero relativo al pin diArduino che verrà collegato a tutti i din CLK delle matrici fisiche.
void setDinPin(byte dinPin);
Imposta il pin da utilizzare come linea dati. Come parametro di deve passare il numero relativo al pin diArduino che verrà collegato a tutti i din DIN delle matrici fisiche.
void addModule(byte moduleCsPin);
Aggiunge un modulo alla matrice virtuale. Come parametro si deve passare il numero relativo al pin da utilizzare per il controllo del segnale CS della matrice che si sta aggiungendo.
void writeByte(byte module, byte data);
Invia un singolo byte al modulo specificato.
void write(byte module, byte address, byte data);
Imposta un registro specifico (parametro address) del modulo indicato (parametro module) con il valore passato nel parametro ‘data’.
void initModule(byte module);
Inizializza il modulo indicato. Viene chiamata automaticamente quando i moduli vengono aggiunti alla matrice virtuale cn addModule.
Funzioni che agiscono su tutti i moduli
void test(byte seconds);
Accende tutti i LED di tutte le matrici per un tempo pari a ‘seconds’ secondi.
void setBrightness(byte brightness);
Imposta la luminosità delle matrici al valore passato nel parametro ‘brightness’. Il valore è un numero da 0 a 15.
void shutdown();
Spegne tutti i LED mantenendo la ultima configurazione di accensione.
void resume();
Riaccende tutti i led con l’ultima configurazione di accensione.
Funzioni di disegno
void plot(byte x,byte y, byte color);
Accende o spegne un singolo LED della matrice virtuale. X rappresenta la colonna, Y la riga e color deve essere 1 per accendere il LED specificato o 0 per spegnerlo.
void plotline(int x1,int y1, int x2, int y2,int color);
Disegna o cancella una linea tra i LED individuati dalle coppie di valori x1,y1 e x2,y2. x1,y1 sono la colonna e la riga del LED di inizio, x2,y2 sono la colonna e la riga del LED di fine e color deve essere 1 per disegnare e 0 per cancellare.
Funzioni testo
void setPos(int x);
Imposta la posizione corrente. La prossima operazione di “stampa” di un testo (lettera o stringa) partirà dalla colonna indicata come parametro.
void plotletter(char letter);
Disegna una lettera nella posizione corrente. char è la lettera da disegnare. Sono diseganbili tutte le lettere e i simboli presenti nel font incluso all’inizio dello scketch.
void plotletterat(int x, char letter);
Disegna una lettera nella posizione specificata. x è la colonna dalla quale inizierà il disegno della lettera, char è la lettera da disegnare. Sono diseganbili tutte le lettere e i simboli presenti nel font incluso all’inizio dello scketch.
void plotstring(char string[]);
Disegna tutti i caratteri della stringa passata come parametro a partire dalla posizione corrente.
Funzioni che agiscono su tutta la matrice virtuale
void rotateleft();
Sposta tutti i pixel (LED) della matrice di una posizione verso sinistra facendo rientrare a destra la prima colonna.
void rotateright();
Sposta tutti i pixel (LED) della matrice di una posizione verso destra facendo rientrare a sinistra l’ultima colonna.
void shiftleft();
Sposta tutti i pixel (LED) della matrice di una posizione verso sinistra inserendo a destra una colonna spenta.
void shiftright();
Sposta tutti i pixel (LED) della matrice di una posizione verso destra inserendo a sinistra una colonna spenta.
void clear();
Spegne tutti i LED della matrice virtuale.
void invert();
Esegue un “not” sullo stato di tutti i LED della matrice. Quelli accesi vengono spenti, quelli spenti vengono accesi.
void flush();
Trasferisce la configurazione della matrice virtuale ai moduli di controllo delle matrici fisiche. Di fatto visualizza sui moduli fisici ciò che è stato disegnato sulla matrice virtuale.
Commenti
23.01.2016 Fede
Molto interessante! Ho imparato qualcosa sulle matrici a LED. Ciao
26.01.2016 Fabrizio
Ciao Silvio, libreria semplice e completa. Spero di testare nuove release. Buon lavoro
01.02.2017 Nikita
Grazie, è una libreria molto utile. Volevo sapere se era possibile girare i display in qualche modo. Grazie
02.02.2017 Silvio Marzotto
Ciao Nikita, l'orientamento delle matrici fisiche dipende da come viene mappata su di loro la matrice virtuale. Attualmente la matrice virtuale è implementata usando un array a una sola dimensione in cui l'indice corrisponde alla x della matrice virtuale e gli otto bits di ogni valore corrispondono alle 8 righe della matrice. Questo perchè i moduli che ho utilizzato si aspettano i dati colonna per colonna (dipende da come è stato utilizzato il max7219 nei moduli). Cosa avevi in mente esattamente?
18.03.2017 rubio
Ciao, ho 4 matrici led 8x8 e volevo far scorrere la scritta Rubio98, magari anche con qualche animazione. Come devo modificare lo sketch???? Grazie
20.03.2017 Silvio Marzotto
Ciao, in questo momento, con questa libreria, è possibile far scorrere soltanto ciò che viene visualizzato sulle matrici (e quindi mappato nella relativa matrice "virtuale" in memoria) nel senso che la rotazione è di fatto uno "shift" delle varie colonne con "rientro" dell'ultima colonna nella prima posizione. La funzione che hai in mente rientra tra le cose da sviluppare: metodi per lo scorrimento di testo la cui dimensione ecceda le dimensioni della matrice virtuale, ma non è ancora disponibile. Potresti provare a modificare il font stringendo le lettere per far rientrare tutta la scritta sulle matrici, oppure aggiungere matrici fino a farci stare tutta la scritta.
14.11.2017 Adriano
ho provato a compilare ma mi da questo errore... C:\Users\xxxxx\Documents\Arduino\led8x8\sketch_nov14a\sketch_nov14a.ino: In function 'void setup()': sketch_nov14a:15: error: 'array' was not declared in this scope array.plotstring("M-7219"); ^ C:\Users\xxxxx\Documents\Arduino\led8x8\sketch_nov14a\sketch_nov14a.ino: In function 'void loop()': sketch_nov14a:21: error: 'array' was not declared in this scope array.rotateleft(); ^ exit status 1 'array' was not declared in this scope
15.11.2017 Silvio Marzotto
Ciao Adriano, è vero! Dove trovi scritto "array." in realtà va svritto myMatrix. Quindi nel setup:
myMatrix.plotstring("M-7219"); myMatrix.flush();
e nel loop:myMatrix.rotateleft(); myMatrix.flush();
Ora correggo anche nell'articolo. Grazie per la segnalazione!13.02.2018 Louis
Ho provato a compilare ma mi da questo problema: C:\Users\MyPc\Documents\Arduino\orologioIoT\orologioIoT.ino:1:30: warning: extra tokens at end of #include directive #include "max7219_font_4px.h"; ^ C:\Users\MyPc\Documents\Arduino\orologioIoT\orologioIoT.ino:2:26: warning: extra tokens at end of #include directive #include "max7219array.h"; ^ In file included from C:\Users\MyPc\Documents\Arduino\orologioIoT\orologioIoT.ino:1:0: C:\Users\MyPc\Documents\Arduino\libraries\arduino-max7219array/max7219_font_4px.h:31:6: error: 'max7219array' has not been declared byte max7219array::font[100][6] = { ^ exit status 1 Error compiling for board Arduino/Genuino Uno
16.02.2018 Silvio Marzotto
Ciao Louis, devono essermi "scappati" due puntoevirgola alla fine degli include. Prova a toglierli e ricompilare. Sul mio IDE (1.8.5) non si lamneta ma in effetti non ci vanno. Il codice dovrebbe essere: #include "max7219array.h" #include "max7219_font_4px.h" Ho corretto anche nell'articolo. Grazie.
26.02.2018 Fabio
Ma il programma che hai pubblicato funziona con qualsiasi tipo di Arduino (Uno, Nano,ecc...) , perchè nonostante abbia aggiunto la libreria correttamente , nella compilazione è come se non me la riconoscesse . Il messaggio di errore è :C:\Users\MyPc\Documents\Arduino\libraries\arduino-max7219array/max7219_font_4px.h:31:6: error: ‘max7219array’ has not been declared Errore di compilazione per scheda Arduino/Genuino Uno E poi vorrei sapere che versione di Arduino hai usato perché io ho la versione 1.8.5 e magari anche il sito da cui l'hai scaricato.
26.02.2018 Fabio
Ho provato a scaricare la versione 1.6.5 e adesso ho un solo errore:C:\Users\MyPc\Documents\Arduino\libraries\arduino-max7219array/max7219_font_4px.h:31:6: error: 'max7219array' has not been declared byte max7219array::font[100][6] = { ^ Error compiling.
27.02.2018 Silvio Marzotto
Ciao Fabio, anche io ho compilato l'esempio con la versione 1.8.5 scaricata direttamente da arduino.cc ma non mi ha dato errori. Verifica che nell'esempio non ci sia un ; alla fine della riga 29 (dovrebbe essere: #include "max7219array.h" ). In effetti ho provato a togliere quella riga e il compilatore mostra proprio l'errore che hai riportato. Fammi sapere se era quello. Ciao, Silvio
28.02.2018 Fabio
Era proprio quello grazie. Ma nel montaggio c'é bisogno anche dell'integrato max7219??
01.03.2018 Silvio Marzotto
Si, i moduli che ho usato io hanno a bordo sia la matrice, sia il max7219. Il max7219 serve per pilotare la matrice (che di suo ha 16 pin, cioè i terminali opportunamente collegati dei 64 leds) e fornisce la memoria necessaria a gestire lo stato dei led e la logica necessaria per essere interfacciarsi via SPI.
01.03.2018 Fabio
come bisogna cambiare i pin se si vuole usare un esp8266 (perché vorrei implemenatare il programma facendo in modo che la stringa che compare sul display sia presa da internet)
01.03.2018 Silvio Marzotto
Io ho usato solo l'esp8266-01 che non ha abbastanza pin per questo progetto, quindi non ho una risposta immediata a questa domanda (non ho sotto mano altri modelli di esp8266). Però in linea generale esiste una corrispondenza tra i pin fisici dell'esp8266 e le uscite in Arduino: dovrebbe essere sufficiente andare a modificare le righe:
myMatrix.setClkPin(10); myMatrix.setDinPin(8); myMatrix.addModule(13);
Sostituendo i pin 10, 8 e 13 di Arduino con quelli che hai usato sull'esp per il clock, i dati e il select.12.05.2018 Antonio
Ciao, c'è un modo per aggiungere altri caratteri oltre a quelli presenti già nei font che hai messo a disposizione tu? Se sì come posso aggiungerli e che codici devo prendere? Grazie.
17.05.2018 Silvio Marzotto
Ciao Antonio, puoi aggiungere caratteri aggiungendo elementi all'array definito nel file del font. Se apri il file max7219_font_4px.h all'interno troverai un array che contiene la definizione di ciascun carattere a partire dal carattere "spazio" fino alla Z (zeta maiuscola). Sono in ordine di codice ASCII, dal 32 (spazio) a 90 (Z maiuscola).
byte max7219array::font[100][6] = { {5,0,0,0,0,0}, // ' ' 32 {2,95,15}, // '!' ... {5,99,81,73,69,99}, // 'Z' };
Dopo la Z c'è [ (codice ASCII 91) quindi per stampare il carattere dovrai stampare la [. Per definire il carattere lo devi disegnare su una grigla alta 8 righe e larga quante colonne ti servono. Il numero di colonne andrà messo come primo valore. Gli altri valori dovranno essere calcolati in base ai pixel da accendere. Si parte da 0 e si sommano i valori dei singoli pixel. Nel caso debba essere acceso il pixel della prima riga va sommato 1, della riga 2 va sommato 2, della riga 3 va sommato 4, della riga 4 va sommato 8, e così via fino alla riga 8 per la quale va sommato 128. Ad esempio se al carattere [ volessimo associare un quadratino 8x8 pixel potremmo scrivere{8,255,129,129,129,129,129,129,255},
Trovi maggiori dettagli su come calcolare i bytes delle colonne qui.10.06.2018 Antonio
Quindi mi stai dicendo che se ad esempio io volessi aggiungere il carattere "°" quello relativo ai gradi, dovrei aggiungere tutti i caratteri da "Z" fino a "°", oppure mi basta inserire dopo la "Z" la seguente combinazione {3, 7, 5, 7},?
13.06.2018 Silvio Marzotto
Ciao Antonio, la definizione è corretta. Per quanto riguarda la sua aggiunta al font, il carattere ° fa parte dei cosiddetti caratteri ASCII estesi, cioè quelli che vanno dal 129 a 255 (v. Ascii_table). Questo significa che per come è fatta ora la libreria sarebbe necessario estendere l'array del font a 255 elemanti ma così facendo occuperebbe 1.5k cioè quasi tutta la RAM. Qundi il font va anche spostato dalla RAM alla Flash con PROGMEM: In max7219array.h modificare la linea 75 in
const static byte font[255][6] PROGMEM;
e nel file del font, ad esempio max7219_font_4px.h modificare la linea 31 inconst byte max7219array::font[255][6] PROGMEM = {
A questo punto vanno inseriti tutti i caratteri tra la Z e il °. Non è necessario che siano effettivamente definiti, è sufficiente che ci sia un "segnaposto" come ad esempio succedere per "?":{0,0,0,0,0,0}, // '?'
Infine, nella posizione corretta (248 se non vado errato), va inserirta la definizione del ° che hai calcolato. In alternativa ti consiglio di "mappare" il simbolo ° su un altro carattere che magari non usi. Quando a programma stamperai quel carattere, sul display apparirà quello che hai mappato.05.06.2018 Fede92
Ciao, potresti darmi qualche consiglio su come far scorrere un testo che supera le dimensioni della matrice. Grazie
08.06.2018 Silvio Marzotto
Ciao Fede, quella dello scorrimento di un testo più ambio della matrice virtuale è una funzione che sto cercando di sviluppare anche io ma ancora non è pronta. Se vuoi provare anche tu a svilupparla ti dico come sto cercando di fare: 1) Metto la stringa che voglio far girare in un array 2) Inizializzo la matrice con un numero di caratteri presi dall'array che ci stia nella matrice 3) Faccio scorrere (senza rientro) la matrice verso sinistra 4) Calcolo la posizione di inizio dell'ultimo carattere stampato 5) Se l'ultimo carattere stampato è completo stampo il carattere successivo (si vedrà solo la prima colonna) 6) Altrimenti ristampo l'ultimo carattere nella posizione adatta (1px prima rispetto alla posizione precedente, si vedrà una colonna in più) 7) Torno al punto 3) fino a quando ho stampato tutti i caratteri 8) Pulisco la matrice e torno al punto 1) Spero ti possa essere di aiuto. Ciao, Silvio
08.07.2019 Massimo
Ciao Silvio è possibile utilizzarlo per una matrice led 64x32? grazie Massimo
24.02.2023 Sara
Ciao, grazie per il tuo notevole lavoro. Sono una neofita appassionata, e vorrei realizzare il gioco "snake" (come quello del Nokia 3310) su un array di 4 display, in una matrice di 16x16. Hai suggerimenti da darmi? Grazie :)
17.03.2023 Silvio Marzotto
Ciao Sara, una possibile strada è quella di crearti una immagine virtuale della tua matrice 16x16 in una varibile e delle funzioni per accendere e spegnere i punti della tua immagine virtuale. Poi, saranno necessarie delle funzioni che, quando l'immagine virtuale cambia, inviino alle matrici 8x8 i dati per "allineare" le singole matrici alla tua matrice virtuale. Se vorrai tonare tra un po' a visitare il blog, tempo permettendo, dovrei pubblicare una nuova libreria che fa proprio questo! Grazie per avermi letto, Silvio