Categoria: Arduino UNO rev 4

  • 03 Incontro del 11-1-2025

    Useremo 3 metodi per creare o rappresentare una Matrice LED :

    1. mediante un array bidimensionale di byte

    2. con 3 vettori di numeri binari

    3. con 3 vettori di numeri esadecimali

     

    1. Creare un bitmap LED per LED

     

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    0 

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    2

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    3

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    4

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    5

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    6

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    7

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

     

    Un cuore nel bitmap

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    0 

    0

    0

    1

    1

    0

    0

    0

    1

    1

    0

    0

    0

    1  

    0

    1

    1

    1

    1

    0

    1

    1

    1

    1

    0

    0

    2

    0

    1

    1

    1

    1

    1

    1

    1

    1

    1

    0

    0

    3

    0

    0

    1

    1

    1

    1

    1

    1

    1

    0

    0

    0

    4

    0

    0

    0

    1

    1

    1

    1

    1

    0

    0

    0

    0

    5

    0

    0

    0

    0

    1

    1

    1

    0

    0

    0

    0

    0

    6

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    0

    7

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

    0

     

    Il codice 1

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED; //creiamo una istanza
    byte cuoreBit[8][12] = { // 96 byte
    { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
    { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    };
    void setup() {
      matriceLED.begin();
      matriceLED.renderBitmap(cuoreBit, 8, 12);
    }
    void loop() {
    }
    È necessario applicare all'oggetto matriceLED il metodo renderBitmap(cuoreBit, 8, 12) per vedere l'immagine statica (fotogramma) del cuore su di esso. Il metodo renderBitmap accetta un array di elementi booleani in cui ciascun elemento corrisponde ad un singolo pixel.2

    Lampeggio nei vertici della matrice

    L’indirizzo di un elemento della matrice è costituito dal nome della matrice seguito dalla riga e colonna di appartenenza ciascuna racchiusa in una parentesi quadra; ad esempio

      nomeMatrice [2][4]

    è l’indizzo del LED che si trova all’incrocio della terza riga con la quinta colonna.

    Per cui la scrittura nel codice di:

      nomeMatrice [2][4] = 0

    determina lo spegnimento del LED in questione, mentre:

       nomeMatrice [2][4] = 1

    la sua accenzione.

    Ciò premesso,

    • Scrivere il codice che faccia lampeggiare i vertici del rettangolo matriceLED.

    Una possibile soluzione:

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED;
    uint8_t frame[8][12];
    void setup() {
      matriceLED.begin();
    }
    void loop() {
      frame[0][0] = 1;
      frame[0][11] = 1;
      frame[7][0] = 1;
      frame[7][11] = 1;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
      frame[0][0]=0;
      frame[0][11]=0;
      frame[7][0]=0;
      frame[7][11]=0;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
    }
    • Se nel loop dovessimo inserire una renderizzazione con una pausa dopo ogni singola variazione della matrice, cosa otterremmo? Perchè?

    Un partecipante all’incontro ha voluto incrociare i due precedenti programmi:

    #include "Arduino_LED_Matrix.h"
    ArduinoLEDMatrix matriceLED; 
    byte frame[8][12] = { // 96 byte
    { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
    { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    };
    void setup() {
      matriceLED.begin();
      matriceLED.renderBitmap(frame, 8, 12);
    }
      void loop() {
      frame[0][0] = 1;
      frame[0][11] = 1;
      frame[7][0] = 1;
      frame[7][11] = 1;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
      frame[0][0]=0;
      frame[0][11]=0;
      frame[7][0]=0;
      frame[7][11]=0;
      matriceLED.renderBitmap(frame, 8, 12);
      delay(1000);
    }

    ________________________________________________________

    Note

    1https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix/

    2 ll rendering (letteralmente restituzione grafica), italianizzato come renderizzazione, identifica la generazione di una immagine

  • 02 Incontro del 7-12-24

    �Esercizio

    Creare nel LED EDITOR MATRIX una animazione con i seguenti fotogrammi:

    pilaInCarica.png

    con un tempo di transizione di 600 ms.
    Per creare un ciclo continuo a video nell’editor: Maiusc. + Barra spaziatrice

    Pillola informatica: le variabili di tipo intere

    int8_t

    un valore con segno a 8 bit
    da -128 a +127
    char

    1 byte di RAM

    uint8_t

    un valore senza segno a 8 bit
    da 0 a 255
    byte

    1 byte di RAM

    int16_t

    un valore con segno a 16 bit
    da -32.768 a +32.767
    int

    2 byte di RAM

    uint16_t è di

    valore senza segno a16 bit
    da 0 a 65.535
    unsigned int

    2 byte di RAM

    int32_t

    valore con segno a 32 bit
    da -2.147.483.648 a +2.147.483.647
    long

    4 byte di RAM

    uint32_t

    valore senza segno a 32 bit
    da 0 a 4.294.967.295
    unsigned long

    4 byte di RAM

     

    Per comprendere i danni provocati da un overflow basti pensare al display di un contagiri costituito da soli due digit; allorchè si passa da 99 a 100, compaiono solo i due zeri poichè l’uno va fuori campo.

    Libreria Serial

    Con Arduino è possibile attivare una comunicazione seriale per inviare e ricevere dati tramite un cavo USB (Universal Serial Bus) con la libreria Serial già integrata nell’IDE. Tale libreria crea un oggetto denominato, di default, Serial.

    All’interno di questa libreria vi sono funzioni (dette anche metodi) come:

    Serial.begin(velocità);
    da usare nel setup,
    predispone Arduino a ricevere ed inviare informazioni tramite la porta seriale.

    velocità: in bit al secondo (baud1): normalmente 9600 bit/s.

    Serial.print(valore);
    invia al monitor seriale il contenuto della variabile valore o una stringa posta tra doppie virgolette o un carattere posto fra virgolette semlici2, senza mandare a capo il cursore.

    Serial.println(valore);
    come prima, ma il cursore va a capo.

    Serial.available();
    restituisce il numero intero dei caratteri che attendono di essere letti sulla porta seriale; restituisce 0 se il buffer è vuoto.

    Serial.read();
    restituisce, sotto forma di carattere, il primo byte in input dal buffer di ricezione seriale 3.

    Serial.readString();
    legge tutta la stringa presente nel buffer di ricezione seriale.

    Serial.print(“\t”);
    introduce una tabulazione.

    Serial.parseInt();4
    legge i caratteri che rappresentano cifre e li restituisce nella rappresentazione numerica.

    Serial.parseFloat();
    legge i caratteri che rappresentano numeri decimali e li restituisce nella rappresentazione numerica.

    La comunicazione seriale

    È un processo di invio di bit uno alla volta; quando i dati arrivano ad Arduino, vanno nel buffer di ricezione seriale. Arduino è dotato di un componente hardware chiamato ricevitore/trasmettitore asincrono universale (UART): tale componente quando arrivano i bit di dati dal computer, li assembla a otto ad otto e li memorizza nel buffer di ricezione seriale.

    Quando si inviano dati, può accadere che al termine della trasmissione venga aggiunto un carattere di terminazione: un CR (Carriage Return, ritorno carrello) o un LF (Line Feed, fine riga) o entrambi; ciascuno di essi aggiungerebbe un byte al buffer di ricezione seriale e questo potrebbe generare qualche effetto indesiderato. Per evitare che ciò possa accadere, è opportuno selezionare Entrambi CR & NL nel menu a discesa che compare nella finestra del Monitor Seriale

    ll monitor seriale è anche utile per verificare se il codice Arduino sta dando i risultati desiderati e risolvere eventuali problemi (tecnica conosciuta come debug seriale).

    Inoltre va puntualizzato che tutto ciò che viene immesso o visualizzato nel Monitor seriale è una stringa5 o un carattere!

    Approfondimenti
    Per comprendere la comunicazione seriale:
    https://dumblebots.com/2019/05/06/arduino-tutorial-its-getting-serial-part-a/
    https://www.programmingelectronics.com/serial-read/

    Variabile globale e variabile locale

    Approfondiamo, attraverso il Serial Monitor, la differenza tra variabile globale e variabile locale.

    • Globale
      È una variabile dichiarata al di fuori delle funzione, compreso setup() e loop(), visibile e modificabile in ogni parte del programma.
    • Locale
      Esse sono visibili solo all’interno delle funzioni e cicli dove vengono definite; viene così ridotta la possibilità di commettere errori di scrittura nelle variabili.
      Due variabili locali, definite in differenti parti del programma, possono avere lo stesso nome e contenere valori differenti, poiché una variabile locale ha vita e visibilità solo nella funzione o ciclo dove viene dichiarata.
      Una variabile che viene definita all’interno di parentesi graffe è una variabile locale.
    • Statica
      È una variabile locale che si comporta come una globale. Infatti è visibile solo dalla funzione in cui viene creata, solo che non viene distrutta quando si esce dalla funzione e ricreata ogni volta che viene chiamata la funzione: sarà definita ed inizializzata solo la prima volta e persisterà e conserverà il proprio valore all’interno della funzione. Al momento non è di nostro interesse!
      La parola chiave è static

    Esempio di variabile globale

    int contatore=1;
    int attesa=1000;

    void setup() {
       Serial.begin(9600);
    }

    void loop() {
       Serial.print(“Ora la variabile contatore contiene il numero: “);
       Serial.println(contatore);
       /*Serial.println(“Ora la variabile contatore contiene il numero: ” + String(contatore)); */
       contatore=contatore+1;
       delay(attesa);
    }

    Esempio di variabile locale

    Lo stesso programma di prima, solo che contatore viene definito in setup, invece che prima. Poiché la variabile è locale, si ottiene un errore:

    Compilation error: ‘contatore’ was not declared in this scope

    Pillola Informatica: gli array

    Supponiamo di voler memorizzare una cinquina di estrazione al lotto, due metodi:

    Con 5 variabili (cinque scatole)
    uint8_t numeroEstratto1=9;
    uint8_t numeroEstratto2= 21;
    uint8_t numeroEstratto3= 45;
    uint8_t numeroEstratto4= 90;
    uint8_t numeroEstratto5= 46;

    Con un array di dimensione 5 (una scatola con 5 scomparti)

    uint8_t numeriEstratti [5];
    numeriEstratti [0]=9;
    numeriEstratti [1]=21;
    numeriEstratti [2]=45;
    numeriEstratti [3]=90;
    numeriEstratti [4]=46;

    oppure, più sbrigativamente

    uint8_t numeriEstratti [5]={9,21,45,90,46}

    9

    21

    45

    90

    46

     

    Array unidimensionale o vettore

    Un vettore è un insieme omogeneo di dati, i cui valori vengono contrassegnati, e quindi vi si accede ad ognuno di essi, con un indice.
    Il primo elemento di un vettore costituito da N elementi (di dimensione N) è contrassegnato con lo 0, l’ultimo con N-1.

    Valore

    a

    b

    c

    d

    e

    f

    Indice

    0

    1

    2

    3

    4

    5

     

    Sintassi

    int unArray[6]; // dichiarazione di un array di dimensione 6, senza inizializzarlo

    byte unArray[6] = {‘a’,’b’,’c’,’d’,’e’,’f’}; // dichiarazione di un array di dimensione 6 inizializzato

    Se si dichiara una dimensione maggiore del numero di elementi utilizzati nella inizializzazione, vengono aggiunti spazi vuoti alla fine dell’array: in un secondo momento si potranno aggiungere gli altri elementi.

    byte unArray[]={‘a’,’b’,’c’,’d’,’e’,’f’}; // dichiarazione di un array inizializzato di  dimensione pari al numero degli elementi inseriti;

    Per recuperare il valore di un elemento dell’array è necessario avere una variabile di lettura o di accesso alla quale assegnare il valore richiesto.

    Un valore nell’array può essere richiamato con il nome dell’array e l’indice numerico della posizione occupata nell’array, posto fra parentesi quadre.

    int variabile = unArray[3] // nell’esempio precedente equivale a variabile = d

    Semplice è anche assegnare un valore ad un elemento di un array, ad esempio

    unArray[3] = ‘d’;

    assegna il valore d al quarto elemento.

    ATTENZIONE: se si accede agli elementi di un array di dimensione N con un indice superiore a N-1, si va in una zona di memoria diversa da quella occupata dall’array e si commettono errori in fase di lettura e danni in quella di scrittura!

    Array bidimensionale o matrice

    Essi sono delle strutture dati bidimensionali, in pratica delle tabelle, in cui organizzare elementi omogenei, ciascuno individuato da due indici, il primo indice è detto indice di riga, il secondo indice di colonna.

    La sintassi per creare una matrice è la seguente:
    tipoDiDati nomeMatrice [R][C];
    dove R è il numero delle righe, mentre C quello delle colonne

    La sintassi per operare con le matrici è analoga a quella vista per i vettori, con la differenza che per individuare un elemento della matrice ora sono necessari due indici.

    NOTE

    1 Unità di velocità di trasmissione in Telecomunicazioni.
    2 “stringa”, ‘carattere’
    3 Restituisce il primo (il più vecchio) carattere nel buffer, dopo di che lo rimuove; quando tutti i byte dei dati saranno stati letti, e quindi rimossi, il buffer sarà vuoto e Serial.available() restituirà il valore 0 (che in un test corrisponde a FALSO)
    4 Ignora eventuali caratteri iniziali che non siano cifre e la ricerca viene interrotta quando viene letto un un carattere che non rappresenti una cifra (o “.” nel caso di Serial.parseFloat()).
    5 Una stringa è una sequenza di caratteri come lettere, numeri e simboli.

  • 01 Incontro del 9-11-24

    Appunti dell’incontro di approfondimento di Arduino UNO Rev 4

    Premessa

    1. Arduino viene programmato nell’ambiente di sviluppo open source Arduino IDE
    2. Salvo alcune eccezioni (le direttive, riconoscibili per la presenza di un #), le istruzioni per Arduino sono comandi
    3. Tutti i comandi terminano con un punto e virgola
    4. Il linguaggio di programmazione è il C
    5. Le formulazioni di alcune istruzioni sono state create proprio per esemplificare la programmazione di Arduino; se ne fa carico l’IDE di trasformarle in istruzioni del C
    6. Il linguaggio usato per Arduino può essere arricchito, mediante un insieme di file detto libreria, con nuove proprietà e funzioni specifiche per un determinato dispositivo
    7. L’arricchimento viene effettuato mediante la direttiva
      #include nomeLibreria.h
      la cosiddette inclusione della libreria
      Che sia una direttiva lo si capisce, come già detto, dalla presenza del simbolo # ; ricordiamo ancora una volta che per le direttive non è previsto il punto e virgola
    8. Se si usa una libreria, occorre specificare (nella modalità indicata dalla libreria stessa) il nome del dispositivo cui si potranno applicare le proprietà e le funzioni integrate
    9. Un programma, detto sketch, viene trasformato in un linguaggio comprensibile per Arduino prima di caricarlo su di esso. E ciò avviene in due fasi:
      1. La precompilazione in cui vengono eseguite le direttive; ad esempio sono inglobate nel programma tutte le proprietà e funzioni (dette metodi) messe a disposizione dalle librerie. In questa fase vengono anche inglobati quei comandi esemplificativi, creati apposta per la programmazione di Arduino e di cui si è detto in precedenza.
      2. La compilazione vera e propria, cioè la trasformazione del codice nei 0 e 1 che sono familiari per Arduino.
    10. Per utilizzare la scheda WiFi UNO R4 è necessario  installare il pacchetto di schede appropriato, a tal proposito può essere utile seguire passo passo le indicazioni su
      https://docs.arduino.cc/tutorials/uno-r4-wifi/r4-wifi-getting-started/

    Se nel selettore della schede dell’IDE di Arduino non compare la WiFi UNO R4, è necessario procedere alla installazione del pacchetto della scheda. Per far ciò, poiché fa parte del Core, apri “Gestione schede”

    • dal menu Strumenti, se usi la versione 1.8.19 dell’IDE
    • in alto a sinistra, se usi la versione 2.x dell’IDE

    cerca UNO R4 WiFi Boards ed installa la versione che desideri utilizzare, preferibilmente la più aggiornata.

    shermata1.png

    In File > Esempi sono presenti moltissimi esempi per questa scheda; casomai non fossero ancora presenti dopo l’installazione del pacchetto, chiudi e riavvia l’IDE. Ed è precariata con uno di questi, (MatrixIntro.ico) che la scheda viene venduta.

    Letture consigliate:

    Pillola informatica: le librerie

    Puoi potenziare il tuo Arduino aggiungendo alcune librerie, infatti esse sono insiemi di codici già scritti e testati che rendono più facile ed intuitivo l’utilizzo di sensori ed attuatori, l’uso del monitor seriale ed altro, rendendo disponibili nuove funzionalità. Alcune librerie sono già integrate nell’IDE, altre vanno aggiunte, altre installate: innumerevoli sono le librerie disponibili e scaricabili in internet.

    Nel programma in cui includiamo una libreria a volte è necessario effettuare la “richiesta”di convergere su di una variabile, detta oggetto, le nuove funzioni e capacità messe a disposizione della libreria stessa; la scelta del nome dell’oggetto, possibilmente esplicativo, spetta al progettista purché sia univoco.

    La direttiva:

    #include <Libreria.h> 1

    impartisce ad Arduino di utilizzare una libreria non integrata; essa va posta all’inizio del programma. Durante la compilazione l’IDE includerà nel firmware sia il nostro codice che quello delle librerie.

    Per prima cosa controlliamo se la nostra libreria è fra quelle già disponibili nell’IDE: andiamo alla voce di menu Sketch/#include libreria e verrà mostrato un elenco delle librerie già disponibili; se compare la libreria di cui abbiamo bisogno, basta cliccare su di essa perché il codice di inclusione venga aggiunto automaticamente al nostro programma.

    Se invece la libreria di cui abbiamo bisogno non dovesse comparire fra quelle già disponibili, controlliamo se è fra quelle che è possibile aggiungere dalla voce di menu Sketch / #include libreria / Gestione librerie: si aprirà una finestra con un elenco di librerie pronte per l’installazione; se vi compare la libreria cercata e viene mostrato un menu a discesa, scegliamo la versione della libreria e clicchiamo su Installa. Una volta che l’istallazione sarà terminata, comparirà la dicitura INSTALLED accanto al nome della libreria.

    Utilizzo della matrice LED integrata

    Per poter gestire la matrice di LED è necessario:

    1. includere la libreria Arduino_LED_Matrix
      #include <Arduino_LED_Matrix.h>
      Non è necessario installarla; è già incorporata!
    2. definire un oggetto con un nome di nostra scelta, ad es. matriceLED
      ArduinoLEDMatrix matriceLED;
      dove ArduinoLEDMatrix è il costruttore indicato dalla libreria
    3. inizializzare l’oggetto nel setup
      matriceLED.begin();

    Per cui, in definitiva, il codice di avvio sarà del tipo:

    #include <Arduino_LED_Matrix.h>

    ArduinoLEDMatrix matriceLED;

    void setup() {

    matriceLED.begin();

    }

    LivePreview

    Per prendere dimestichezza con la matrice è utile vedere in diretta cosa si può disegnare sulla matriceLED. Per far ciò è necessario far interagire Arduino e LED Matrix Editor2 esclusivamente attraverso il browser Google Chrome; si tratta di un software sperimentale in fase di pre-rilascio al m omento della stesura del presente tutorial, per cui non è escluso qualche problemino!

    2.png

    • Collega Arduino al computer tramite porta USB
    • Apri l’IDE di Arduino
    • Nel menu File / Esempi soffermati sulla sezione Esempi per Arduino WiFi R4 ed in particolare su LED_MATRIX, carica il programma LivePreview
    • Apri Google Croome all’idirizzo https://ledmatrix-editor.arduino.cc/
    • Nella schermata dell’Editor, clicca sull’icona del dischetto posta al centro in alto e segui le istruzioni, cioè:
      • conferma di aver caricato lo sketch
      • connetti il tuo dispositivo collegandoti alla porta USB accoppiata (accertati che non ci siano altre comunicazioni seriali attive)
      • Inizia a disegnare cliccando sugli elementi della matrice e vedrai accendere o spegnere i LED sulla MatriceLED

    Dobbiamo dar merito al piccolo Angelo D. che ha dato luogo ad una animazione in questo modo:

    • ha creato prima più fotogrammi di un pupazzetto in successione di varie posizioni;
    • ha cliccato sull’icola posta in alto al centro dell’editor per creare la successione dei fotogrammi;
    • poichè la permanenza di ogni fotogramma risultava ridottissima, ha duplicato più volte ogni singolo fotogramma per rallentarne il movimento.

     Sicuramente avrebbe agito diversamente se prima fosse stato informato che nella parte sottostante il singolo fotogramma compare il ritardo temporale prima di passare al fotogramma successivo; forse sarebbe stato meno creativo! 

    Durante le esercitazioni sono state riscontrate alcune difficoltà da parte di alcuni partecipanti; allorchè si scollegava l’Arduino UNO R4 e lo si ricollegava, veniva generata una diversa porta USB virtuale, ma nell’Editor l’Arduino risultava collegato alla porta precedente: in alcuni casi è bastato chiudere e riavviare l’Editor. Come detto l’Editor è in fase sperimentale!

    1<libreria> o “libreria” a seconda che la libreria si trovi nella cartella delle librerie di Arduino o nella cartella in cui è posizionato il codice del progetto.

    2https://labs.arduino.cc/en/labs/led-matrix in particolare la liberatoria in fondo alla pagina.