In questo tutorial imparerai a controllare le animazioni Parola su un display a matrice LED MAX7219. Andremo a concatenare animazioni, usare pulsanti per cambiare animazione e potenziometri per regolare la luminosità e la velocità delle animazioni.
La libreria MD_Parola è una delle più usate per programmare animazioni su display, come ad esempio il testo scorrevole, rendendo tutto molto semplice. Mentre le singole animazioni sono facili da implementare, potresti trovare più complicato concatenare o controllare più animazioni. Inoltre, spesso vogliamo leggere dati da sensori senza interrompere l’animazione. Questo tutorial ti mostrerà come fare.
Componenti necessari
Ho usato un Arduino Uno per questo progetto, ma qualsiasi altra scheda Arduino, oppure una scheda ESP8266/ESP32, funzionerà altrettanto bene. Qui utilizziamo un display a matrice LED MAX7219 composto da 4 moduli, ma il codice e i collegamenti per display con più o meno moduli sono praticamente gli stessi.

Display a matrice LED MAX7219

Arduino Uno

Set di cavi Dupont

Breadboard

Cavo USB per Arduino UNO

Pulsante

Potenziometro 10KΩ
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Collegamento del display LED MAX7219 con Arduino
In questo tutorial useremo un display a matrice LED MAX7219 per mostrare animazioni. Il driver del display MAX7219 comunica con Arduino tramite SPI (Serial Peripheral Interface). Quindi, la prima cosa da fare è collegare il display ad Arduino usando l’interfaccia SPI.
Collegamenti
Il seguente schema mostra i collegamenti necessari tra il display MAX7219 e un Arduino Uno. Assicurati di collegarti al lato di ingresso (DIN) e non a quello di uscita (DOUT) del display.

Inizia collegando i pin dell’interfaccia SPI: il pin 11 di Arduino va collegato al pin DIN del display. Poi collega il pin 3 a CS e il pin 13 a CLK. Infine, collega 5V a VCC e GND a GND. La tabella seguente riassume i collegamenti:
| Display | Arduino |
|---|---|
| VCC | 5 V |
| GND | GND |
| DIN | 11 (MOSI) |
| CS | 3 (SS) |
| CLK | 13 (SCK) |
I pin scelti sopra sono per l’SPI hardware, che è più veloce rispetto all’SPI software ma richiede l’uso di pin specifici che cambiano a seconda della scheda. Per maggiori dettagli vedi la MAX7219 LED dot matrix display Arduino tutorial .
Ora scriviamo e carichiamo un semplice codice di test per assicurarci che i collegamenti siano corretti.
Installa le librerie MD_Parola e MD_MAX72XX
Per prima cosa, dobbiamo installare la MD_MAX72XX e la MD_Parola libreria. Puoi installare queste librerie tramite il Library Manager dell’ Arduino IDE . Vai su Tools > Manage Libraries per aprire il Library Manager. Cerca “MD_MAX72XX” e vedrai elencate le librerie rilevanti. Nello screenshot qui sotto puoi vedere che ho già installato entrambe le librerie (evidenziate in giallo):

La libreria MD_MAX72XX è essenzialmente il driver software per il display LED MAX7219. La libreria MD_Parola la utilizza per creare animazioni come testo scorrevole ed effetti sprite. Se vuoi saperne di più sulle animazioni disponibili dai un’occhiata alla MAX7219 LED dot matrix display Arduino tutorial .
Codice di test
Il seguente codice è un esempio minimo per testare i collegamenti e il funzionamento del display. Mostra semplicemente il testo scorrevole “Test” sul display.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
disp.displayText("Test", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
void loop() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
Il codice inizia includendo le librerie necessarie. La SPI è disponibile di default, mentre hai già installato la MD_Parola e la MD_MAX72xx libreria sopra.
#include "MD_Parola.h" #include "MD_MAX72xx.h" #include "SPI.h"
Ora dobbiamo definire alcune costanti e creare l’oggetto display ( disp ). In particolare, dobbiamo specificare il tipo di display, quanti moduli ha e quale pin di Arduino è collegato al segnale Chip Select ( CS ).
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW #define MAX_DEVICES 4 #define CS_PIN 3 MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
Se hai un display con più o meno moduli dovrai impostare MAX_DEVICES di conseguenza. Nota anche che qui stiamo usando l’SPI hardware. Per l’SPI software devi definire i pin utilizzati. Dai un’occhiata alla MAX7219 LED dot matrix display Arduino tutorial per i dettagli.
Nella funzione setup , il codice prepara il display, imposta la luminosità e cancella il display. Nell’ultimo passaggio, definiamo un’animazione che fa scorrere il testo ” Test ” da sinistra a destra con una velocità di 100, cioè un ritardo di 100ms tra ogni step dell’animazione. Quindi, valori più bassi sono più veloci.
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
disp.displayText("Test", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
Il main loop esegue continuamente l’animazione chiamando displayAnimate() . Se questa funzione restituisce true, l’animazione è completa e il display si resetta per un nuovo ciclo. In pratica, il testo ricomincia a scorrere.
void loop() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
Se carichi ed esegui questo codice dovresti vedere il testo “Test” scorrere da sinistra a destra sul tuo display MAX7219:

Se funziona, congratulazioni! Siamo pronti per altre animazioni.
Concatenare animazioni
Una domanda comune è come creare una sequenza di animazioni che vengono eseguite una dopo l’altra. Ad esempio, supponiamo di voler far scorrere il testo “Left” verso sinistra e poi “Right” verso destra, ripetendo il ciclo.

Tuttavia, non possiamo interrompere il ciclo dell’animazione o concatenare facilmente due loop uno dopo l’altro. In qualche modo, dobbiamo cambiare animazione all’interno del loop.
void loop() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
Il codice seguente mostra come si può ottenere questo risultato:
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void switchAnimation(int animationId) {
switch(animationId) {
case 0:
disp.displayText("Left", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, 100, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
switchAnimation(0);
}
void loop() {
static int animationId = 0;
if (disp.displayAnimate()) {
disp.displayReset();
switchAnimation(++animationId % 2);
}
}
Vediamo più da vicino questo codice. Le istruzioni include, la definizione delle costanti e la creazione del display MD_Parola sono le stesse di prima.
Funzione switchAnimation
La novità è la funzione switchAnimation() . Prende l’ id di un’animazione e imposta l’animazione di scorrimento a sinistra o a destra. Nota che switchAnimation() non esegue l’animazione, ma dice solo al display quale animazione eseguire. L’esecuzione vera e propria avviene tramite displayAnimate() nel main loop.
void switchAnimation(int animationId) {
switch(animationId) {
case 0:
disp.displayText("Left", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, 100, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
Funzione setup
La funzione setup rimane praticamente invariata. Come prima, prepara il display, imposta la luminosità e cancella il display. Nell’ultimo passaggio, però, chiamiamo switchAnimation(0), che imposta l’animazione con id=0. In questo caso, è lo scorrimento del testo “Left”.
Funzione loop
Nella funzione loop definiamo la variabile animationId per tenere traccia dell’animazione corrente. È static , il che significa che il suo valore viene mantenuto tra un ciclo e l’altro.
void loop() {
static int animationId = 0;
if (disp.displayAnimate()) {
disp.displayReset();
switchAnimation(++animationId % 2);
}
}
All’interno del loop, la chiamata a displayAnimate() esegue l’animazione corrente. Quando un’animazione è completa (il testo è completamente scorrevole), questa funzione restituisce true e si entra nel corpo dell’ if -if. Lì eseguiamo un reset e poi passiamo all’animazione successiva.
L’espressione ++animationId % 2 incrementa l’id dell’animazione fino a 2 e poi lo riporta a 0. Se vuoi concatenare più di 2 animazioni, devi sostituire il 2 con il numero di animazioni che hai. Inoltre, queste animazioni devono essere definite nella funzione switchAnimation() .
Ecco un codice di esempio per una sequenza di tre animazioni:
...
void switchAnimation(int animationId) {
switch(animationId) {
case 0:
disp.displayText(...);
break;
case 1:
disp.displayText(...);
break;
case2:
disp.displayText(...);
break;
}
}
void setup() {
...
}
void loop() {
static int animationId = 0;
if (disp.displayAnimate()) {
disp.displayReset();
switchAnimation(++animationId % 3);
}
}
Se carichi ed esegui questo codice dovresti vedere la seguente animazione:

Nella prossima sezione ti mostro come cambiare animazione in base a input esterni, come pulsanti.
Cambiare animazione
Spesso vuoi cambiare animazione in base a un input esterno. Questo può essere un pulsante, un telecomando, un sensore di movimento o dati da un sensore come la temperatura. Nell’esempio seguente useremo due pulsanti per attivare l’animazione “Left” o “Right”.

Iniziamo aggiungendo i due pulsanti al nostro circuito.
Collegamenti
Aggiungere i due pulsanti è semplice. Collega un pin di entrambi i pulsanti a massa (GND) e l’altro pin rispettivamente al pin 7 e al pin 8 di Arduino, come mostrato qui sotto:

Fai attenzione a collegare il pulsante usando i pin effettivamente commutati. Nota che non servono resistenze di pull-up, dato che useremo le pull-up interne di Arduino.
Codice per cambiare animazione
Il codice per cambiare animazione è una semplice estensione di quello per le animazioni concatenate.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
#define BTN1_PIN 6
#define BTN2_PIN 7
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void switchAnimation(int animationId) {
switch (animationId) {
case 0:
disp.displayText("Left", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, 100, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
void setAnimation(int btn_pin, int animationId) {
if (!digitalRead(btn_pin)) {
disp.displayReset();
disp.displayClear();
switchAnimation(animationId);
delay(200);
}
}
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
setAnimation(0);
pinMode(BTN1_PIN, INPUT_PULLUP);
pinMode(BTN2_PIN, INPUT_PULLUP);
}
void loop() {
setAnimation(BTN1_PIN, 0);
setAnimation(BTN2_PIN, 1);
animate();
}
La parte che include le librerie necessarie, definisce le costanti e crea l’oggetto display MD_Parola è praticamente invariata. L’unica differenza è che definiamo i pin a cui sono collegati i due pulsanti.
#define BTN1_PIN 6 #define BTN2_PIN 7
Anche la funzione switchAnimation() è la stessa di prima. Ma ora abbiamo una nuova funzione setAnimation() :
void setAnimation(int btn_pin, int animationId) {
if (!digitalRead(btn_pin)) {
disp.displayReset();
disp.displayClear();
switchAnimation(animationId);
delay(200);
}
}
Prende un pin di un pulsante e un id di animazione e controlla se il pulsante sul pin specificato è premuto chiamando !digitalRead(btn_pin) . Nota che la logica è invertita, perché quando il pulsante è premuto il pin GPIO viene portato a livello basso.
Se il pulsante è premuto, resettiamo e cancelliamo il display, e passiamo all’animazione assegnata a quel pulsante. Il delay di 200ms serve per il debounce del pulsante. Qui il delay va bene, perché abbiamo appena cambiato animazione e quindi non rallentiamo un’animazione in corso.
Poi spostiamo il codice che esegue un’animazione dal main loop a una nuova funzione animate() . Così la funzione loop sarà molto più pulita.
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
La funzione setup() è praticamente la stessa, ma impostiamo la modalità dei due pin a cui sono collegati i pulsanti. Nota che impostiamo INPUT_PULLUP , per usare la pull-up resistors interna.
void setup() {
...
pinMode(BTN1_PIN, INPUT_PULLUP);
pinMode(BTN2_PIN, INPUT_PULLUP);
}
La funzione loop ora è davvero semplice. Assegniamo l’id di un’animazione ai pulsanti tramite setAnimation() e poi chiamiamo animate() per eseguire l’animazione attiva. Nota che il codice ora sembra una piccola storia o ricetta. È proprio così che vogliamo che sia il nostro codice.
void loop() {
setAnimation(BTN1_PIN, 0);
setAnimation(BTN2_PIN, 1);
animate();
}
Carica il codice e provalo! I brevi video qui sotto mostrano le due animazioni che dovresti vedere premendo il pulsante sinistro (BTN1) o destro (BTN2).


Nella prossima sezione andremo a modificare la funzione dei due pulsanti.
Attivare o sospendere animazioni
Invece di usare un pulsante per ogni animazione, useremo un pulsante (BTN1) per cambiare animazione e l’altro (BTN2) per mettere in pausa l’animazione in corso. Il codice seguente mostra come fare.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
#define BTN1_PIN 6
#define BTN2_PIN 7
int animationId = 0;
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void switchAnimation() {
switch (animationId) {
case 0:
disp.displayText("Left", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, 100, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
void toggleAnimation() {
if (!digitalRead(BTN1_PIN)) {
disp.displayReset();
disp.displayClear();
animationId = (animationId + 1) % 2;
switchAnimation();
delay(200);
}
}
void pauseAnimation() {
static bool isPaused = false;
if (!digitalRead(BTN2_PIN)) {
isPaused = !isPaused;
disp.displaySuspend(isPaused);
delay(200);
}
}
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
switchAnimation();
pinMode(BTN1_PIN, INPUT_PULLUP);
pinMode(BTN2_PIN, INPUT_PULLUP);
}
void loop() {
toggleAnimation();
pauseAnimation();
animate();
}
Ci sono alcune differenze rispetto al codice precedente. Prima di tutto, la funzione switchAnimation() non prende più un animationId come argomento, ma si basa su una variabile globale per tenere traccia dell’animazione in corso.
Inoltre, abbiamo due nuove funzioni: toggleAnimation() e pauseAnimation() . Vediamo più da vicino toggleAnimation() .
void toggleAnimation() {
if (!digitalRead(BTN1_PIN)) {
disp.displayReset();
disp.displayClear();
animationId = (animationId + 1) % 2;
switchAnimation();
delay(200);
}
}
Questa funzione controlla se BTN1 è stato premuto. Se sì, resetta e cancella il display, aggiorna la animationId all’animazione successiva e chiama switchAnimation() per impostare l’animazione corrispondente. Alla fine c’è il solito delay per il debounce del pulsante.
La funzione pauseAnimation() controlla se BTN2 è stato premuto e, in tal caso, cambia lo stato del flag isPaused . In base al valore di questo flag, l’animazione viene sospesa o meno.
void pauseAnimation() {
static bool isPaused = false;
if (!digitalRead(BTN2_PIN)) {
isPaused = !isPaused;
disp.displaySuspend(isPaused);
delay(200);
}
}
La funzione setup è sostanzialmente invariata e la funzione loop, ancora una volta, è molto leggibile come una piccola storia:
void loop() {
toggleAnimation();
pauseAnimation();
animate();
}
A ogni iterazione gestiamo il cambio o la sospensione dell’animazione. Come vedi, è facile cambiare la funzione dei pulsanti e mantenere tutto ordinato.
Nelle prossime due sezioni facciamo un passo in più e aggiungiamo un potenziometro per regolare la luminosità o la velocità di un’animazione in esecuzione.
Regolare la luminosità dell’animazione
In questa parte vediamo come regolare la luminosità del testo visualizzato mentre l’animazione è in esecuzione.
Collegamenti
Iniziamo aggiungendo un potenziometro al circuito. Lo useremo per regolare la luminosità del display in modo analogico. Ho usato un potenziometro da 10kΩ, ma qualsiasi valore tra 1kΩ e 100kΩ va bene.

Collega il pin centrale del potenziometro (POT) all’ingresso analogico A0 di Arduino. Poi collega 5V e GND agli altri due pin del potenziometro. L’ordine non è importante, ma influenzerà se la luminosità aumenta girando il potenziometro a sinistra o a destra. Se preferisci una direzione specifica, ad esempio aumentare la luminosità girando a destra, basta invertire i collegamenti 5V e GND sul potenziometro.
Codice per regolare la luminosità
Ecco il codice usato prima, con la funzionalità aggiuntiva per regolare la luminosità del display in base alla posizione del potenziometro.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
#define BTN1_PIN 6
#define BTN2_PIN 7
int animationId = 0;
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void switchAnimation() {
switch (animationId) {
case 0:
disp.displayText("Left", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, 100, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
void toggleAnimation() {
if (!digitalRead(BTN1_PIN)) {
disp.displayReset();
disp.displayClear();
animationId = (animationId + 1) % 2;
switchAnimation();
delay(200);
}
}
void pauseAnimation() {
static bool isPaused = false;
if (!digitalRead(BTN2_PIN)) {
isPaused = !isPaused;
disp.displaySuspend(isPaused);
delay(200);
}
}
void adjustBrightness() {
int val = analogRead(A0);
int intensity = map(val, 0, 1023, 0, 15);
disp.setIntensity(intensity);
}
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
switchAnimation();
pinMode(BTN1_PIN, INPUT_PULLUP);
pinMode(BTN2_PIN, INPUT_PULLUP);
}
void loop() {
toggleAnimation();
pauseAnimation();
adjustBrightness();
animate();
}
Vediamo le modifiche al codice. Serve solo una nuova funzione che legge il valore del potenziometro tramite analogRead(), lo mappa su un valore di intensità tra 0 e 15 e poi imposta la luminosità del display di conseguenza.
void adjustIntensity() {
int val = analogRead(A0);
int intensity = map(val, 0, 1023, 0, 15);
disp.setIntensity(intensity);
}
Dobbiamo poi chiamare adjustBrightness() nel main loop per regolare la luminosità del display mentre l’animazione è in esecuzione. Tutto qui. Ora puoi cambiare animazione, metterla in pausa e regolare la luminosità.
Nella prossima sezione facciamo qualcosa di molto simile, ma invece di regolare la luminosità del display, regoliamo la velocità dell’animazione.
Regolare la velocità dell’animazione
Ecco il codice completo per impostare la velocità dell’animazione in base alla posizione del potenziometro.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
#define BTN1_PIN 6
#define BTN2_PIN 7
int animationId = 0;
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void switchAnimation() {
int speed = disp.getSpeed();
switch (animationId) {
case 0:
disp.displayText("Left", PA_CENTER, speed, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, speed, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
void toggleAnimation() {
if (!digitalRead(BTN1_PIN)) {
disp.displayReset();
disp.displayClear();
animationId = (animationId + 1) % 2;
switchAnimation();
delay(200);
}
}
void pauseAnimation() {
static bool isPaused = false;
if (!digitalRead(BTN2_PIN)) {
isPaused = !isPaused;
disp.displaySuspend(isPaused);
delay(200);
}
}
void adjustSpeed() {
int val = analogRead(A0);
int speed = map(val, 0, 1023, 10, 1000);
disp.setSpeed(speed);
}
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
switchAnimation();
pinMode(BTN1_PIN, INPUT_PULLUP);
pinMode(BTN2_PIN, INPUT_PULLUP);
}
void loop() {
toggleAnimation();
pauseAnimation();
adjustSpeed();
animate();
}
Questo codice è leggermente più complesso, perché dobbiamo aggiungere una nuova funzione e modificare la funzione switchAnimation() . Nella funzione switchAnimation() ora otteniamo la velocità attuale del display e la usiamo quando cambiamo animazione:
void switchAnimation() {
int speed = disp.getSpeed();
switch (animationId) {
case 0:
disp.displayText("Left", PA_CENTER, speed, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
break;
case 1:
disp.displayText("Right", PA_CENTER, speed, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
break;
}
}
E abbiamo la nuova funzione adjustSpeed() , molto simile alla precedente funzione adjustBrightness() . La funzione adjustSpeed() legge il valore del potenziometro tramite analogRead(), lo mappa su un valore di velocità tra 10 e 1000 e poi imposta la velocità dell’animazione di conseguenza.
void adjustSpeed() {
int val = analogRead(A0);
int speed = map(val, 0, 1023, 10, 1000);
disp.setSpeed(speed);
}
Cambiare il contenuto dell’animazione
Infine, ti mostro un metodo semplice per aggiornare il contenuto di un’animazione. Ti servirà, ad esempio, se vuoi mostrare dati da sensori, come la temperatura o l’ora.
Invece di usare un sensore specifico, nell’esempio qui sotto riutilizziamo il potenziometro per simulare la lettura di un sensore. Ma puoi facilmente sostituire il potenziometro con qualsiasi altro sensore.
#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
MD_Parola disp = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void updateAnimation() {
static char buffer[32] = "";
int value = analogRead(A0);
sprintf(buffer, "value=%d", value);
disp.displayText(buffer, PA_CENTER, 50, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
updateAnimation();
}
}
void setup() {
disp.begin();
disp.setIntensity(0);
disp.displayClear();
updateAnimation();
}
void loop() {
animate();
}
La funzionalità principale per l’aggiornamento dell’animazione è nella funzione updateAnimation() . Legge il valore attuale del sensore, in questo caso il potenziometro, lo formatta e lo scrive in una stringa buffer tramite sprintf , e infine aggiorna il testo visualizzato tramite displayText() . Se carichi ed esegui il codice dovresti vedere la seguente animazione:

Nota che la dimensione del buffer della stringa è impostata a 32 caratteri. Se vuoi mostrare testi più lunghi, dovrai aumentare la dimensione del buffer.
La funzione updateAnimation() può essere facilmente modificata per mostrare altri dati. Supponiamo che invece del potenziometro colleghi un sensore di temperatura DHT11. Dovresti solo cambiare la funzione come segue:
float t = dht.readTemperature();
void updateAnimation() {
static char buffer[32] = "";
float temp = dht.readTemperature();
sprintf(text, "Temp=%.2f", temp);
disp.displayText(buffer, PA_CENTER, 50, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
Questo ovviamente presuppone che tu abbia collegato il sensore DHT11 e impostato la sua funzione nel codice. Dai un’occhiata al tutorial su How to use DHT11 and DHT22 Sensors with Arduino per maggiori informazioni.
Nota che l’aggiornamento del contenuto avviene quando parte una nuova animazione, ma non durante l’esecuzione di un’animazione. Ad esempio, se usi il testo scorrevole, il testo non si aggiornerà mentre scorre, ma si aggiornerà quando inizia un nuovo ciclo. Puoi vedere questo nella funzione animate() , dove chiamiamo updateAnimation() quando l’animazione corrente è completa.
void animate() {
if (disp.displayAnimate()) {
disp.displayReset();
updateAnimation();
}
}
E questo è tutto! Diversi esempi, si spera utili, su come controllare varie funzioni di un’animazione usando input digitali o analogici, senza interrompere l’animazione. Se hai domande, lascia pure un commento.
Conclusioni
La libreria Parola è ottima per le animazioni, ma può essere un po’ complicata da capire quando si tratta di controllare, cambiare o aggiornare le animazioni senza interromperle. Spero che questo tutorial ti abbia dato tutte le informazioni per farlo nei tuoi progetti.
Abbiamo usato pulsanti e un potenziometro come input per controllare le animazioni. Ma è facile usare altri input digitali o analogici. Ad esempio, puoi controllare le animazioni con un telecomando IR, oppure usare una fotoresistenza per regolare la luminosità del display in base alla luce ambiente, e mostrare dati meteo aggiornati da internet.
Inoltre, la libreria Parola ti permette di dividere il display in più zone che possono eseguire animazioni diverse, ad esempio una zona per l’orologio e un’altra per i dati meteo. Se vuoi saperne di più, dai un’occhiata al tutorial Coordinate Parola Zone Animations on MAX7219 Display .
Infine, anche se in questo tutorial abbiamo usato un Arduino, qualsiasi altro microcontrollore comune come ESP32 o ESP8266 andrà benissimo.
E ora buon divertimento con le animazioni ; )

