Archivi autore: admin

Progettare bene, programmare meglio: pseudocodice e diagrammi di flusso per sistemi elettronici – lezione 3/5


Ripasso di inizio anno – appunti per la classe.

Lo pseudocodice è un modo semplice e strutturato di descrivere un algoritmo in lingua naturale (italiano+parole chiave) senza la rigidità della sintassi di un linguaggio di programmazione.
È come scrivere una ricetta: elenchi ingredienti (dati), spieghi i passaggi (istruzioni) e le condizioni (“se… allora…”). Non lo “esegue” il computer, ma lo capiscono persone (docenti, compagni, te stesso domani) e ti guida a tradurre poi tutto in codice (es. Arduino/C++).

Cosa rende utile lo pseudocodice

Chiedere agli studenti di scrivere pseudocodice non è un esercizio di progettazione, ma neanche un modo per semplificare la progettazione del nostro sistema, è un modo che permette di decidere prima che cosa deve accadere, poi si penserà a come scriverlo in un linguaggio di programmazione, nel nostro caso in C/C++ per Arduino.

Possiamo definire lo pseudocodice come ad una lingua ponte: viene compreso sia da chi programma ma anche da chi ancora non programma; detto in altro modo possiamo dire che “mette in fila le idee”, riduce gli errori di distrazione, rende veloce il debug e lascia una traccia chiara e leggibile del progetto.

E’ sicuramente uno strumento inclusivo: abbassa la soglia d’ingresso per chi fatica con la sintassi ed è più abile nel ragionamento.

Nella pratica se so raccontare bene l’algoritmo con verbi chiari (LEGGI, SE, MENTRE, RITORNA), tradurlo in codice diventa un’operazione quasi meccanica.

Avrete intuito che saper scrivere pseudocodice non è solo un’attività di progettazione del software, ma anche un modo per comprendere sistemi complessi che interessano non solo la programmazione ma la nostra vita quotidiana: organizzare lo studio, pianificare un viaggio, andare a scuola, ecc… tutto può essere reso pseudocodice, se vi allenerete a scrivere pseudocodice vi accorgerete di avere maggior percezione di un problema e lo comprenderete meglio.

Sintetizziamo quanto sopra detto con una lista puntata che vi servirà nello studio.

Vantaggi dello pseudocodice

  • Chiarezza di idee: separate il cosa fare dal come scriverlo in C/C++.
  • Comunicazione: è una lingua comune tra chi sa e chi non sa ancora programmare, oppure una lingua comune tra persone che serve per comprendere un sistema.
  • Progettazione top-down: partite dal problema, lo scomponete in sotto-problemi, definite funzioni e responsabilità.
  • Riduzione errori: se l’algoritmo è corretto in pseudocodice, gli errori in codice molto probabilmente si ridurranno a dettagli sintattici.
  • Debug più rapido: quando il programma non funziona, si verifica prima la logica (lo pseudocodice), poi la sintassi.
  • Documentazione: lasciate tracce intelligibili del progetto, quindi ottimo per la relazione di laboratorio.
  • Valutazione: mostra il processo e non solo il risultato. Un buon pseudocodice rivela le vostre competenze di analisi, decomposizione, gestione dei casi limite (pensate a quanto diventa utile anche durante la prova scritta dell’esame di maturità… ne parlo più avanti)
  • Inclusione: aiuta chi ha poca dimestichezza con la sintassi a concentrarsi sui concetti fondamentali (input, output, decisioni, cicli, dati).

Perché è importante usarlo nel laboratorio di sistemi elettronici

In laboratorio non scriviamo solo righe di codice: progettiamo sistemi con sensori, attuatori, tempi, soglie e stati.
Lo pseudocodice costringe a dichiarare pin, costanti e variabili di stato, a prevedere debounce, time-out, condizioni di errore, cioè chiarisce il flusso:

inizializzazione > letture > decisioni > azioni

e rivolgendomi agli studenti, vedrete che renderà i test al banco di lavoro più rapidi, nel senso che saprete già quali valori provare e che risposta aspettarmi su ad esempio un LED, buzzer o seriale.

Ritengo che tra i vantaggi più importanti nella realizzazione dello pseudocodice ci sia quella di facilitare il lavoro di gruppo:

ognuno implementa una funzione sapendo dove si inserisce nel flusso generale. Risultato: meno tentativi a vuoto, più tempo speso a capire cosa fa davvero il nostro sistema.

Nelle esercitazioni che svilupperete con Arduino ma in generale con qualsiasi scheda a microcontrollore, c’è sempre un “sistema” da far funzionare: sensori, attuatori, logica, tempi, soglie, stati.

Se scriverete prima lo pseudocodice:

  • sarete obbligati a dichiarare ingressi (sensori), uscite (attuatori), costanti (soglie, pin), variabili di stato;
  • sarà più chiaro il flusso: inizializzazione > ciclo principale > gestione eventi > funzioni di servizio;
  • vi aiuterà a ragionare su casi limite (esempio: debounce, errori di misura, time-out);
  • diventerete più rapidi nel passaggio alla codifica e nella verifica sperimentale al banco.

In pratica: pseudocodice = “schema funzionale” del vostro impianto in forma testuale.

Pensiamo ora ad un evento che vi coinvolgerà: l’esame di maturità

Sarebbe bello ottimizzare il tempo della prova scritta di sistemi (se questa sarà la materia della seconda prova) ma l’uso dello pseudocodice va bene anche per la progettazione di qualsiasi tipo di prova, anche per strutturare un tema di italiano.
All’orale la commissione potrebbe valutare anche come progettate, quindi non solo se il codice funziona. Saper scrivere su un foglio:

Requisiti > Pseudocodice > Schema I/O > Stralcio di codice > Piano di test

sicuramente comunica metodo, ordine e padronanza… e quindi fate una bella figura 😉

Lo pseudocodice vi aiuta a spiegare le scelte: perché una soglia? perché una macchina a stati? come gestisci i casi limite?
E vi mette al sicuro quando vi chiedono una variazione durante l’orale: se la logica è chiara, sapete subito dove intervenire. È un modo semplice per far vedere che sapete passare dall’idea all’implementazione in modo professionale.

Immaginate poi ad un insegnante che dovrà correggere il vostro compito, avere un buon pseudocodice vi assicuro che lo aiuta 😉

Quindi sintetizzando è molto importante ricordare:

  • esporre prima lo pseudocodice mette in luce le vostre capacità progettuali;
  • mostra che sapete astrarre dal codice e motivare le scelte;
  • facilita domande e risposte: il docente può chiedervi di modificare una parte, ad esempio aggiungere un sensore e voi sapete intervenire nel flusso.

e non ultimo farà pensare: “questa persona è professionale”.

Ora andiamo al nocciolo della questione, vediamo come si fa lo pseudocodice, in realtà vi darò una linea guida, qualche esempio ed esercizi semplici che coinvolgono la vostra vita quotidiana, imparerete in brevissimo tempo.

Quello che scrivo da questo momento in poi dovrebbe essere inserito nelle prime pagine del vostro quaderno, dove andrete ad inserire i riferimenti delle schede che utilizziamo, della sintassi di programmazione ecc…

Nota i miei studenti (da recuperare)

Ricordo che ogni attività di progettazione che farete e consegnerete dovrà includere:

    • diagramma di flusso
    • pseudocodice
    • sketch Arduino commentato in ogni parte
    • breve relazione di funzionamento
    • eventuale:
      • schema elettrico
      • schema topografico di collegamenti
      • tabella misure
      • grafici
    • Sitografia
    • Bibliografia

A tal proposito vi mostrerò un format di foglio di lavoro che potrete poi modificare secondo necessità.

Ogni progetto deve essere esposto anche oralmente.

In alcune occasioni vi sarà azione di debate, ovvero un confronto tra gruppi su specifici problemi tecnici da risolvere.

Regole di base

  • Una istruzione per riga; rientra (indenta) i blocchi.
  • Parole chiave in MAIUSCOLO: SE, ALTRIMENTI, MENTRE, PER, FUNZIONE, RITORNA, ATTENDI.
  • Date nomi chiari a variabili e costanti: sogliaLuce, tempoGiallo, pinLedRosso, cioè usiamo la convenzione camelcase che combina più parole in un’unica stringa, scrivendo la prima parola in minuscolo e le parole successive con la loro iniziale maiuscola ad esempio: nomeUtente.
  • In testa: Pin, Costanti, Variabili. Poi: Inizializzazione, Loop, Funzioni.
  • Commentate perché fate qualcosa, non scrivete l’ovvio: “sommo 1 al contatore perché ogni impulso accende il led…”

Di seguito un template da copiare ed incollare:

/* Requisito sintetico: cosa deve fare il sistema */

COSTANTI:
    pinLed = ...
    pinBtn = ...
    soglia = ...

VARIABILI:
    stato = ...
    conteggio = ...

INIZIALIZZA:
    configura pin
    azzera conteggi

LOOP PRINCIPALE:
    leggi sensori
    SE (condizione) ALLORA:
        azione
    ALTRIMENTI SE (...) ALLORA:
        altra azione
    ALTRIMENTI:
        default
    aggiorna attuatori
    ATTENDI t ms

FUNZIONI:
    FUNZIONE nome(parametri):
        passi...
        RITORNA valore

La checklist da seguire ASSOLUTAMENTE è questa:

  1. Input/Output identificati? (pin, range, unità)
  2. Costanti definite? (soglie, tempi, limiti)
  3. Stati chiari? (idle, misura, allarme, reset…)
  4. Casi limite previsti? (debounce, isteresi, time-out, valori anomali)
  5. Test plan minimo? (quali valori proverai e cosa ti aspetti di vedere)

Ora facciamo qualche esempio che coinvolge la nostra vita

01 – Sveglia e alzarsi

Diagramma di flusso Mermaid

graph TD
    A[Inizio] --> B[Suona sveglia]
    B --> C{Ancora sonno?}
    C -- Si --> D[Attendi 5 minuti]
    D --> B
    C -- No --> E[Alzati dal letto]
    E --> Z[Fine]

Diagramma di flusso

Pseudocodice

RIPETI
  SUONA_SVEGLIA()
  LEGGI risposta // "si" se hai ancora sonno, "no" altrimenti
  SE risposta == "si" ALLORA
     ATTENDI 5 minuti
  ALTRIMENTI
     ESCI DAL CICLO
  FINE SE
FINCHÉ VERO
ALZATI_DAL_LETTO()
SCRIVI "Pronto per iniziare la giornata"

02 – Colazione semplice

Si pone che la scelta sia tra due tipologie di colazione, latte o te, in alternativa bisogna bere acqua.

Diagramma di flusso Mermaid

graph TD
    A[Inizio] --> B[Apri cucina]
    B --> C{Hai fame?}
    C -- Si --> D[Scegli bevanda]
    D --> E{Bevanda scelta latte?}
    E -- Si --> F[Prepara latte]
    E -- No --> G[Prepara te]
    F --> H[Mangia colazione]
    G --> H
    C -- No --> I[Bevi acqua]
    H --> Z[Fine]
    I --> Z

Diagramma di flusso

Pseudocodice

APRI_CUCINA()
LEGGI fame // "si" oppure "no"

SE fame == "si" ALLORA
   SCRIVI "Scegli una bevanda"
   LEGGI bevanda // "latte" oppure "te"
   SE bevanda == "latte" ALLORA
      PREPARA_LATTE()
   ALTRIMENTI
      PREPARA_TE()
   FINE SE
   MANGIA_COLAZIONE()
ALTRIMENTI
   BEVI_ACQUA()
FINE SE

SCRIVI "Colazione terminata"

03 – Prepara lo zaino

Diagramma di flusso Mermaid

APRI_DIARIO()
LEGGI listaLibriRichiesti
IMPOSTA zaino = lista_vuota
PER ciascun libro IN listaLibriRichiesti:
   AGGIUNGI libro A zaino
FINE PER

CONTROLLA_ASTUCCIO()

LEGGI mancaQualcosa // "si" oppure "no"
MENTRE mancaQualcosa == "si" FAI
   LEGGI cosaManca
   AGGIUNGI cosaManca A zaino
   LEGGI mancaQualcosa // ricontrolla
FINE MENTRE

SCRIVI "Zaino pronto"

Diagramma di flusso

Pseudocodice

APRI_DIARIO()
LEGGI listaLibriRichiesti
IMPOSTA zaino = lista_vuota
PER ciascun libro IN listaLibriRichiesti:
   AGGIUNGI libro A zaino
FINE PER

CONTROLLA_ASTUCCIO()

LEGGI mancaQualcosa // "si" oppure "no"
MENTRE mancaQualcosa == "si" FAI
   LEGGI cosaManca
   AGGIUNGI cosaManca A zaino
   LEGGI mancaQualcosa // ricontrolla
FINE MENTRE

SCRIVI "Zaino pronto"

04 – Uscire di casa in base al meteo

Si pone che, in funzione del tempo, la scelta sia tra due oggetti alternativi: ombrello o cappellino.

Diagramma di flusso Mermaid

graph TD
    A[Inizio] --> B[Leggi meteo]
    B --> C{Pioggia?}
    C -- Si --> D[Prendi ombrello]
    C -- No --> E[Prendi cappellino]
    D --> F[Esci di casa]
    E --> F
    F --> Z[Fine]

Diagramma di flusso

Pseudocodice

LEGGI meteo // "pioggia" oppure "sereno"

SE meteo == "pioggia" ALLORA
   PRENDI_OMBRELLO()
ALTRIMENTI
   PRENDI_CAPPELLINO()
FINE SE

ESCI_DI_CASA()
SCRIVI "Buona giornata"

05 – Zaino intelligente (liste + loop)

Diagramma di flusso Mermaid

graph TD
    A[Inizio] --> B[Leggi orarioDelGiorno come elenco di materie]
    B --> C[Inizializza libriNecessari come lista vuota]
    C --> D[Imposta i = 0]
    D --> E[Calcola n uguale a numero di materie]
    E --> F{i minore di n?}

    F -- Si --> G[Prendi materia in posizione i]
    G --> H[Aggiungi materia a libriNecessari]
    H --> I[Incrementa i di 1]
    I --> F

    F -- No --> L[Stampa Metti nello zaino elenco libriNecessari]
    L --> Z[Fine]

Diagramma di flusso

Pseudocodice

LEGGI orarioDelGiorno   // lista, es: ["Mate","Storia","Inglese","Sistemi"]
IMPOSTA libriNecessari a lista vuota

PER ogni materia in orarioDelGiorno:
    AGGIUNGI materia a libriNecessari

SCRIVI "Metti nello zaino: " + libriNecessari

… e magari fate anche la versione per il quaderno e i materiali da portare con voi.

06 – Pomodoro di studio (ciclo + timer)

Visto che adotto questo metodo nella mia vita lavorativa, non potevo non propinare lo pseudocodice della tecnica del pomodoro.

Studiare a blocchi da 25’ con pause da 5’, per 4 cicli.

Diagramma di flusso Mermaid

graph TD
    A[Inizio] --> B[Imposta pomodoro = 1]
    B --> C{pomodoro <= 4} C -->|Si| D[Stampa Studia 25 minuti Pomodoro pomodoro]
    D --> E[Attendi 25 minuti]
    E --> F{pomodoro < 4} F -->|Si| G[Stampa Pausa 5 minuti]
    G --> H[Attendi 5 minuti]
    H --> J[Incrementa pomodoro di 1]
    F -->|No| I[Salta pausa]
    I --> J
    J --> C
    C -->|No| K[Stampa Sessione completata]
    K --> Z[Fine]

Diagramma di flusso

Pseudocodice

PER pomodoro da 1 a 4:
    SCRIVI "Studia 25 minuti (Pomodoro " + pomodoro + ")"
    ATTENDI 25 minuti
    SE (pomodoro < 4) ALLORA:
        SCRIVI "Pausa 5 minuti"
        ATTENDI 5 minuti
SCRIVI "Sessione completata!"

Per i miei studenti

Lista degli esercizi che dovrete fare come compito (vi dirò quando):

    1. Lavarsi i denti (tempo minimo per lavaggio 2 min).
    2. Merenda e soldi (se soldi maggiore di 2€ compro panino, altrimenti porto merenda da casa).
    3. Smartphone e batteria (se livello della batteria è inferiore al 20% ricaricare).
    4. Spegnere la luce uscendo di casa (tenere conto anche della chiusura con chiavi della porta di casa).
    5. Priorità compiti (ordinamento concettuale, ordinare le attività per scadenza e importanza).
    6. Vestiti in base al meteo (vestirsi in base al meteo (IF multiplo)).
    7. Abitudine acqua (promemoria ciclico, bere 1 bicchiere ogni ora tra le 9 e le 13).
    8. Media dei voti e situazione (input + aritmetica. Calcolare media e capire se sei sopra la soglia 6).

Seguiranno altri esercizi.

Nella prossima lezione vedremo come passare dallo pseudocodice ad uno sketch Arduino.

Buon pseudocodice a tutti 😉

Lezione 8 – Corso di Elettronica Creativa con Arduino Sensor Kit

Lo schermo OLED

Questo modulo è un display OLED monocromatico 128×64 con interfaccia Grove a 4 pin I²C, adatto a mostrare testi e semplici indicatori grafici direttamente dall’Arduino Sensor Kit. Rispetto agli LCD, gli OLED offrono autoluminescenza, alto contrasto, ampio angolo di visione e basso consumo, perché non richiedono retroilluminazione.

L’OLED (Organic Light-Emitting Diode) usa materiali organici che emettono luce quando attraversati da corrente; non avendo una retroilluminazione, ogni pixel deve essere acceso/aggiornato dal controller. Nel Sensor Kit l’OLED 0,96″ (famiglia SSD1306/SSD1315) si controlla in modo semplificato tramite la libreria Arduino_SensorKit, che fornisce la classe Oled con metodi pronti per inizializzazione, posizionamento del cursore e stampa del testo.

Collegamento

  • Inserire il modulo/display sul connettore I2C del Grove Base Shield, monta lo shield su Arduino UNO e collega via USB.
  • Impostare l’interruttore del Base Shield su 5V (necessario per alimentare correttamente il display).
  • Su Arduino UNO i pin I²C sono SDA=A4 e SCL=A5; l’indirizzo I²C tipico dei moduli SSD1306 è 0x3C (alcuni esemplari possono usare 0x3D). Se non risponde, esegui uno scanner I²C per verificarlo.
  • Sull’Arduino Sensor Kit collegare il display al connettore I2C come mostrato nell’immagine che segue.

Librerie da utilizzare

  • Oled.begin() inizializza il controller con l’indirizzo corretto e imposta modalità/parametri base di comunicazione I²C.
  • Oled.setCursor(x,y) posiziona il cursore: con l’API U8x8 esposta dal kit lavori in celle di carattere 8×8 (circa 16 colonne × 8 righe su 128×64).
  • Oled.print(...) scrive testo/valori;
  • Oled.refreshDisplay() aggiorna lo schermo.

L’API U8x8 è “testo-only” e non richiede buffer RAM; per disegni pixel-level bisogna usare l’API grafica U8g2 (con font e funzioni grafiche più ricche).

Le differenze tra le due API:

  • U8x8 = velocità e semplicità e solo per testo;
  • U8g2 = grafica avanzata con e richiede più memoria.

Per i più curiosi

Il controller SSD1306 gestisce la RAM del display per pagine e supporta vari modi di indirizzamento (orizzontale/verticale/pagina). Le librerie si occupano dei dettagli, ma sapere che l’aggiornamento avviene “a blocchi” aiuta a capire perché alcune operazioni grafiche richiedono più tempo/buffer.

Specifiche del display

  • Alimentazione: 3,3–5 V (compatibile con UNO).
  • Interfaccia: I²C (Grove 4 pin).
  • Indirizzo: 0x3C (varianti 0x3D).
  • Caratteristiche d’uso: alto contrasto, basso consumo, ampia temperatura operativa (fino a –40…+85 °C su molte versioni).

Qualche consiglio da tenere a mente durante le sperimentazioni

  • Non lasciare per ore la stessa immagine ad alto contrasto; meglio aggiornare periodicamente o usare una schermata di riposo.
  • Stabilità del contenuto: se il testo “sfarfalla”, stampare prima su Serial Monitor per verificare i valori e ridurre la frequenza di refresh (es. ogni 100–200 ms).
  • Differenza tra griglia di caratteri (U8x8) e coordinate in pixel (U8g2): una “barra” fatta di caratteri ha 16 step, mentre a pixel può averne 128.

Esempi pratici

Versione con commenti per gli studenti in cui viene dettagliato il funzionamento di ogni parte del codice.

Esempio 1 (semplice)

/*
Prof. Maffucci Michele
25/09/2025
OLED – Scrivere nome e cognome - versione 1
Inizializzare il display OLED del Sensor Kit e mostrare
"Allievo:" su una riga, poi Nome e Cognome sulla riga sotto.
*/

#include <Arduino_SensorKit.h>  // Include la libreria del Sensor Kit.
// Questa libreria mette a disposizione l’oggetto 'Oled' (già pronto)
// per usare facilmente il display senza dover scrivere codice di basso livello (I2C).

void setup() {
Oled.begin();
// Inizializza il display OLED.
// Fa partire la comunicazione I2C e manda al display la sequenza di avvio.
// Senza questa riga lo schermo non mostra nulla.

Oled.setFlipMode(true);
// Ruota il contenuto di 180° (utile se lo vedi capovolto).
// Se nel tuo caso appare già dritto, puoi mettere false: Oled.setFlipMode(false);

Oled.setFont(u8x8_font_chroma48medium8_r);
// Sceglie il font (carattere) 8x8.
// Con un font 8x8 il display 128x64 si comporta come una griglia 16 colonne × 8 righe.
// Significa che setCursor(colonna, riga) userà numeri tra 0..15 (colonne) e 0..7 (righe).

Oled.clear();
// Pulisce lo schermo (cancella tutto quello che c’era prima).

Oled.setCursor(0, 2);
// Posiziona il cursore alla colonna 0, riga 2 (terza riga dall’alto).
// Le coordinate sono "a caratteri" (non in pixel).

Oled.print("Allievo:");
// Stampa il testo "Allievo:" nella posizione corrente.

Oled.setCursor(0, 4);
// Sposta il cursore alla riga 4 (quinta riga), colonna 0.
// Qui stamperemo nome e cognome.

Oled.print("Michele");
// Stampa il nome.

Oled.print(" ");
// Stampa uno spazio tra nome e cognome.

Oled.print("Maffucci");
// Stampa il cognome.

Oled.refreshDisplay();
// Aggiorna fisicamente lo schermo.
// Finché non richiami refreshDisplay(), il display potrebbe non mostrare i nuovi testi.
}

void loop() {
// Vuoto: non dobbiamo aggiornare nulla in continuazione.
// Il display mantiene il testo finché non lo cambiamo nel codice.
}

Esempio 1 – senza commenti

Nel caso servisse copiare ed incollare solamente il codice per poi inserire i propri commenti vi lascio anche la versione senza commenti:

#include <Arduino_SensorKit.h> 

void setup() {
Oled.begin();
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.clear();
Oled.setCursor(0, 2);
Oled.print("Allievo:");
Oled.setCursor(0, 4);
Oled.print("Michele");
Oled.print(" ");
Oled.print("Maffucci");
Oled.refreshDisplay();
}

void loop() {
}

Esempio 1 – avanzato

Versione con commenti per gli studenti in cui viene dettagliato il funzionamento di ogni parte del codice.

/*
Prof. Maffucci Michele
25/09/2025
Scrive nome e cognome dell’allievo sul display OLED del Sensor Kit.
- Usa la libreria Arduino_SensorKit (oggetto Oled).
- Dimostrazione uso di: const char*, Oled.begin(), setFlipMode, setFont, setCursor, print, clear, refreshDisplay.
*/
#include <Arduino_SensorKit.h>  // Include la libreria che espone l’oggetto 'Oled'.

// -----------------------------------------------------------------------------
// DICHIARAZIONE DELLE STRINGHE
// 'const char*' = puntatore a caratteri costanti (stringa C in sola lettura).
// Puntano a letterali con terminatore '\0' (durata statica, non vanno modificati).
// -----------------------------------------------------------------------------
const char* nomeAllievo = "Michele"; // sostituisci con il nome reale (es. "Luca")
const char* cognomeAllievo = "Maffucci"; // sostituisci con il cognome (es. "Rossi")

void setup() {
// ---------------------------------------------------------------------------
// INIZIALIZZAZIONE DEL DISPLAY
// Oled.begin() avvia l'I2C e programma il controller del display (SSD1306/1315).
// Senza questa chiamata, il display non mostrerà nulla.
// ---------------------------------------------------------------------------
Oled.begin();

// setFlipMode(true) ruota il contenuto di 180°.
// Usarlo se il testo appare "capovolto" a causa dell’orientamento fisico.
// Mettere false se già si vede diritto.
Oled.setFlipMode(true);

// Seleziona il font 8x8 "chroma48medium8_r".
// Con font 8x8, lo schermo 128x64 si comporta come una griglia 16 colonne × 8 righe.
Oled.setFont(u8x8_font_chroma48medium8_r);

// ---------------------------------------------------------------------------
// PULIZIA E STAMPA DEL CONTENUTO
// ---------------------------------------------------------------------------

// Cancella tutto il contenuto precedente del display.
Oled.clear();

// Posiziona il cursore (colonna=0, riga=2) in coordinate "a caratteri" (non pixel).
// (0,2) significa: prima colonna, terza riga della griglia 16x8.
Oled.setCursor(0, 2);

// Stampa un’etichetta. Con la macro F("...") il testo resta in flash (serve per risparmiare RAM).
Oled.print(F("Allievo:"));

// Vai a riga 4, colonna 0, e stampa nome + cognome separati da spazio.
Oled.setCursor(0, 4);
Oled.print(nomeAllievo); // stampa la stringa puntata da 'nomeAllievo'
Oled.print(" "); // spazio tra nome e cognome
Oled.print(cognomeAllievo);

// Aggiorna fisicamente lo schermo: senza refresh, la nuova scritta potrebbe non apparire.
Oled.refreshDisplay();
}

void loop() {
// Nessuna azione periodica: il display mantiene il contenuto finché non lo cambiate.
// (Se volete far lampeggiare o scorrere il testo, lo fareste nel loop)
}

Esempio 1 – avanzato – senza commenti

#include <Arduino_SensorKit.h> 

const char* nomeAllievo = "Michele";
const char* cognomeAllievo = "Maffucci";

void setup() {
Oled.begin();
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.clear();
Oled.setCursor(0, 2);
Oled.print(F("Allievo:"));
Oled.setCursor(0, 4);
Oled.print(nomeAllievo);
Oled.print(" ");
Oled.print(cognomeAllievo);
Oled.refreshDisplay();
}

void loop() {
}

Che cosa significa char*? Perché const char* qui?

  • char è il tipo carattere in C/C++ (1 byte).
  • char* è un puntatore a char: invece di contenere direttamente un carattere, contiene l’indirizzo di memoria dove si trova una sequenza di caratteri (una stringa in stile C).
  • Le stringhe letterali scritte tra virgolette, es. "Nome", sono array di char terminati da \0 (null terminator). Hanno durata statica: esistono per tutta l’esecuzione del programma e sono solitamente in sola lettura.

Per questo si usa:

const char* nomeAllievo = "Nome";
  • const indica che non vogliamo (e non dobbiamo) modificare quei caratteri (sono un letterale costante).
  • Il tipo completo si legge: “puntatore a char costanti“. Potete cambiare il puntatore (farlo puntare ad un’altra stringa), ma non i caratteri a cui punta.

Alternative possibili

  • const char nomeAllievo[] = "Nome";
    (array di char costanti: il compilatore conosce la lunghezza e non potete riassegnare il nome dell’array).
  • String nomeAllievo = "Nome";
    (classe Arduino String: comoda ma usa più RAM dinamica; in progetti grandi può frammentare l’heap).

Nota su Arduino/AVR: i letterali come "testo" possono occupare SRAM a runtime se non si usa la macro F("testo") o PROGMEM. Nel nostro sketch la dimensione è minuscola, ma per testi lunghi conviene Oled.print(F("Allievo:")) per risparmiare RAM.

A cosa serve Oled.begin()

Oled.begin() inizializza il display OLED del Sensor Kit. In pratica:

  • Avvia la comunicazione I²C verso il controller del display (SSD1306/SSD1315) all’indirizzo corretto.
  • Manda la sequenza di setup al controller (accensione, modalità, contrasto di base, orientamento di default, ecc.).
  • Prepara l’oggetto Oled a ricevere comandi come setCursor, print, clear, refreshDisplay.

Senza Oled.begin() il display non risponde ai comandi, quindi va chiamato una volta nel setup().

Esempio 2

Lettura del valore analogico del potenziometro, visualizza il valore numerico grezzo dell’ADC e del valore percentuale sul display con barra (a carattere) di avanzamento.

Collegare il potenziometro all’ingresso A0.

/*
Prof. Maffucci Michele
25/09/2025
OLED
- Leggere il valore analogico dal potenziometro (0..1023 su Arduino UNO).
- Converte il valore in percentuale (0..100%).
- Visualizza il valore grezzo (ADC), la percentuale e una barra orizzontale su OLED.

Note:
- Usiamo la libreria Arduino_SensorKit che fornisce l'oggetto 'Oled' (display SSD1306/1315 via I2C).
- La barra è disegnata come sequenza di caratteri ASCII ('#').
*/

#include <Arduino_SensorKit.h>  // Include l'API semplificata per i sensori e l'OLED del Sensor Kit

// --------------------- CONFIGURAZIONE INGRESSO ANALOGICO ---------------------
// PIN del potenziometro: collega il cursore del pot al pin A0 (e gli altri due capi a +5V e GND).
const int PIN_POT = A0;

// Variabili per memorizzare il valore letto (grezzo) e la percentuale calcolata.
int valoreADC = 0; // Gamma tipica su UNO: 0..1023 (10 bit)
int percento = 0; // 0..100 (%)

// L'OLED in modalità font 8x8 ha circa 16 colonne: la barra avrà da 0 a 16 "blocchi" pieni.
const uint8_t LARGHEZZA_BAR = 16;

// -----------------------------------------------------------------------------
// Funzione di utilità: disegna una barra percentuale su una riga 'y' del display.
// Parametri:
// - y: indice riga (0..7 se font 8x8; 0 è la prima riga in alto).
// - percent: valore 0..100 che determina la lunghezza della barra.
// -----------------------------------------------------------------------------
void disegnaBarraPercento(uint8_t y, uint8_t percent) {
// Converte la percentuale 0..100 nel numero di "blocchi" (0..16)
// (uint32_t) evita overflow nella moltiplicazione su microcontrollori a 16 bit.
uint8_t pieni = (uint32_t)percent * LARGHEZZA_BAR / 100;

// 1) Pulisce la riga della barra: stampa 16 spazi per "cancellare" ciò che c'era prima.
Oled.setCursor(0, y); // posiziona il cursore all'inizio riga
for (uint8_t i = 0; i < LARGHEZZA_BAR; i++) {
Oled.print(' '); // spazio = cella vuota
}

// 2) Ridisegna i "blocchi" pieni (da sinistra verso destra) usando un carattere visibile e portabile ('#').
Oled.setCursor(0, y); // torna all'inizio riga
for (uint8_t i = 0; i < pieni; i++) {
Oled.print('#'); // carattere della barra
}
}

void setup() {
// ------------------------ INIZIALIZZAZIONE OLED ----------------------------
Oled.begin(); // inizializza I2C e il controller del display
Oled.setFlipMode(true); // ruota 180° se il testo appare capovolto (mettere false se OK)
Oled.setFont(u8x8_font_chroma48medium8_r); // font 8x8: griglia circa 16 colonne × 8 righe

// Pulizia e titolo
Oled.clear(); // cancella lo schermo
Oled.setCursor(0, 0); // colonna 0, riga 0 (prima riga)
Oled.print("Potenziometro"); // titolo
Oled.refreshDisplay(); // aggiorna la visualizzazione
}

void loop() {
// ----------------------------- LETTURA ADC --------------------------------
// Per stabilizzare il valore (ridurre rumore), facciamo una media di 4 campioni.
long somma = 0;
for (int i = 0; i < 4; i++) { somma += analogRead(PIN_POT); // legge l'ingresso analogico A0: 0..1023 delay(2); // piccola pausa per lasciare stabilizzare } valoreADC = somma / 4; // media semplice dei 4 campioni // ----------------------- SCALATURA IN PERCENTUALE ------------------------- // 'map' converte da una scala a un'altra: qui 0..1023 > 0..100.
// Nota: 'map' restituisce un intero; per scale diverse potresti usare una formula float.
percento = map(valoreADC, 0, 1023, 0, 100);

// ----------------------------- STAMPA TESTO -------------------------------
// Riga 2: mostriamo il valore ADC grezzo.
Oled.setCursor(0, 2); // colonna 0, riga 2
Oled.print("ADC: "); // spazi finali per "coprire" cifre residue
Oled.setCursor(5, 2); // posiziona circa a metà riga
Oled.print(valoreADC); // valore numerico 0..1023

// Riga 3: mostriamo la percentuale.
Oled.setCursor(0, 3);
Oled.print("Perc: ");
Oled.setCursor(6, 3);
Oled.print(percento); // 0..100
Oled.print("%");

// ------------------------------ BARRA GRAFICA -----------------------------
// Disegna la barra percentuale alla riga 5 (sesta riga).
disegnaBarraPercento(5, percento);

// Aggiorna fisicamente il display (altrimenti potresti non vedere le modifiche).
Oled.refreshDisplay();

// Piccolo delay per fluidità; valori troppo bassi aumentano il "flicker",
// valori troppo alti rendono meno reattivo l'aggiornamento.
delay(60);
}

Buon Coding a tutti 🙂

Quick References per lo studio – Tecnica del pomodoro

Il Pomodoro è un metodo di gestione dell’attenzione, non solo un timer. Alterna lavoro concentrato e pause brevi per ridurre l’affaticamento, prevenire lo “scroll” compulsivo e creare un ritmo sostenibile. Il ciclo classico è 25’ + 5’, ma puoi modularlo (20–5 per compiti cognitivamente pesanti; 50–10 per stesure prolungate). La forza del metodo sta nel trasformare compiti vaghi in unità atomiche (una consegna chiara per ciclo) e nel misurare quanta energia richiedono le attività reali. In ottica didattica è perfetto per esercizi a progressione, lettura con sintesi e progetti lunghi. Con studenti che faticano ad avviare il lavoro, un “warm-up” da 10 minuti sblocca l’inerzia; con chi perde il focus, il log delle interruzioni diventa strumento di consapevolezza e miglioramento.

Approfondimenti

Scarica PDF A4 della guida operativaApri il sorgente Markdown su GitHub

Se non sai cos’è il Markdown segui il link

---
title: "QR - Tecnica del Pomodoro"
version: "1.0"
autore: "<Classe/Studente>"
licenza: "CC BY 4.0"
ultimo_aggiornamento: "31.08.2025"
---

## Obiettivo del ciclo
< compito specifico >

## Ciclo
- Lavoro: 25'
- Pausa: 5'
- Ripeti x4 → Pausa lunga 15–30'

## Tracker pomodori
- [ ] 1 - [ ] 2 - [ ] 3 - [ ] 4

## Interruzioni / distrazioni (log)
- <evento, durata, soluzione>

## Consuntivo
- Pomodori effettivi: 
- Note: 

Perché usare Arduino UNO R4 WiFi invece di un ESP32?

Vi condivido la mia risposta alla domanda che un utente mi ha fatto sulla mia pagina Facebook in riferimento al post: Aggiornare il firmware dell’Arduino UNO R4 WiFi

Grazie degli spunti che ci dai! Ti volevo chiedere quale fosse il vantaggio di avere un Arduino che per la connettività usa, anche se integrata, una esp32 e perché invece non usare solo quest’ultima che integra la maggior parte delle funzionalità?

Poiché si tratta di una domanda ricorrente che mi viene fatta ho pensato di pubblicare la risposta su questo sito.

Ciao Antonio C.
Scusami se non ti ho risposto subito, ma ho sfruttato la tua domanda per riflettere su alcune cose che metterò in evidenza durante le prossime lezioni con i miei studenti (e forse ne farò un post) e quindi le ho scritte in modo tale da rispondere anche a loro, sono stato un po’ prolisso, pensavo e scrivevo, comunque grazie per la domanda.

Il motivo principale per cui in laboratorio uso Arduino UNO R4 WiFi è la prototipazione plug & play in un contesto dove girano tanti shield a 5 V e progetti “da banco”. Avere un UNO “classico” con la rete integrata riduce gli intoppi: niente (o molti meno) convertitori di livello, meno sorprese sui pin, più tempo per scrivere codice e fare misure. Il vantaggio, insomma, è soprattutto pratico.
In più, le schede vengono usate da classi e anni diversi: questa scelta consente di avviare attività che interagiscono con il mondo reale in modo rapido e uniforme per tutta la classe; quando il gruppo è pronto, si passa volentieri anche ad altre piattaforme.

Interessante il fatto che con l’UNO R4 mantieni logica/alimentazione a 5 V e la compatibilità con gli shield R3 tipici dell’ecosistema Arduino, senza dover inserire level-shifter. Molte schede ESP32 lavorano invece a 3,3 V e non sono 5 V-tolleranti, quindi richiedono più accortezze sull’hardware. Immagina la situazione di sperimentazione in classe: tanti adolescenti alle prime armi, dove una delle competenza da raggiungere è l’attenzione, quanti ESP32 brucerei? 🙂

Per le prime classi dell’ITIS è un plus avere l’ecosistema Arduino pronto (IDE, Cloud, librerie, esempi).

Su R4 WiFi usi direttamente WiFiS3 e gli esempi ufficiali: accendi, compili, carichi, senza dover toccare RTOS, partizioni o toolchain ESP.

Un’altra comodità è la separazione dei compiti tra i due chip:

  • la RA4M1 esegue il tuo sketch e le parti “tempo-critiche” (ADC, PWM, servo, protocolli, ecc.);
  • l’ESP32-S3 gestisce Wi-Fi/BLE e, sulla UNO R4 WiFi, cura anche la USB-to-serial verso il RA4M1. Questo schema riduce il rischio che stack di rete/USB “sporchino” il timing del codice utente.

Sul fronte analogico, hai a bordo un DAC a 12 bit e un OP AMP integrato, con un ESP32-S3 “puro” queste funzioni non le hai integrate, quindi dovresti aggiungerle con IC esterni.

Non ultimo, la matrice LED 12×8 integrata: perfetto per debug e feedback rapidi (numeri, icone, barre, stati). Tutti gli studenti vedono subito cosa succede senza dover guardare solo il Serial Monitor, e ci sono esempi pronti nell’IDE.

Detto questo, non devo “convincere” nessuno: quando la classe risponde bene e c’è voglia di spingersi oltre, uso anche ESP32 (e altro), soprattutto per progetti tutto a 3,3 V o più “muscolosi” lato rete/calcolo, con componentistica esterna ad hoc. Dipende molto dal contesto e dagli obiettivi didattici.

In sintesi, UNO R4 WiFi è un oggetto che include già molto (5 V + shield, connettività, DAC, OP AMP, matrice) e mi permette di gestire velocemente gruppi diversi (dal punto di vista delle competenze) senza perdite di tempo.

Una cosa che vorrei sottolineare: i tempi di sviluppo sperimentazione che un appassionato Maker o professionista si discostano parecchio da quelli di uno studente che usa il “tempo scuola” per studiare anche altre discipline, però fortunatamente abbiamo molti ragazzi che si appassionano e fanno tanto in autonomia e che io ed i miei colleghi seguiamo la mattina ma anche in attività pomeridiane.

Tutto ciò per dire che Arduino UNO R4 WiFi è un buon compromesso.

Grazie.

Progettare bene, programmare meglio: diagrammi di flusso – cos’è il formato Mermaid? – Lezione 2/5

Ripasso di inizio anno – appunti per la classe.

In elettronica e automazione, un errore concettuale spesso costa più tempo di un errore di cablaggio. I diagrammi di flusso aiutano a scomporre il problema in passi elementari, chiarire condizioni e cicli, progettare la logica prima di scrivere il codice. Questo riduce la probabilità di “scrivere e sperare” e mette gli studenti nella condizione di ragionare per stati, condizioni e transizioni: esattamente ciò che serve per gestire sensori (LDR, potenziometri), attuatori (LED, buzzer) e sequenze temporizzate su Arduino.

In classe, partire dal diagramma rende trasparente il legame tra:

  • Analisi del problema > (diagramma);
  • Progettazione > (pseudocodice);
  • Implementazione > (sketch Arduino).

Questa filiera abitua a un metodo di lavoro replicabile, valutabile e condivisibile.

Che cos’è Mermaid

Mermaid è uno strumento open-source che trasforma descrizioni testuali (uno specifico linguaggio “simile al Markdown”) in diagrammi resi automaticamente nel browser. È scritto in JavaScript ed è pensato proprio per “diagrammare come si scrive”: poche righe leggibili, risultato grafico immediato.

Nato come progetto open-source nel 2014 per semplificare la creazione di diagrammi nelle documentazioni tecniche, Mermaid è sviluppato dalla comunità (MIT license) e supporta diversi tipi di diagramma: flowchart, sequence diagram, state diagram, Gantt, ER, class diagram e altri.

Dove funziona (integrazioni utili a scuola)

Mermaid è integrato o supportato nativamente in molte piattaforme usate anche in ambito didattico e progettuale (editor Markdown, wiki, ambienti di sviluppo, appunti digitali). Questo significa che studenti e docenti possono scrivere il diagramma nello stesso file in cui documentano, e vederlo renderizzato senza strumenti pesanti.

Un vantaggio pratico importante: GitHub permette di includere i diagrammi Mermaid direttamente dentro i file Markdown del repository. Per noi significa versionare codice e diagrammi nello stesso posto.

Perché Mermaid è più interessante rispetto ai tool grafici tradizionali

Molti software di disegno (Visio, draw.io, ecc.) producono file binari o complessi da confrontare e unire. Mermaid, invece, produce testo:

  • che viene integrato nella versione con Git insieme allo sketch (storia delle modifiche, differenze riga-per-riga, revisioni);
  • si integra nei flussi “docs-as-code”, cioè il trattare la versione e gli aggiornamenti della  documentazione di progetto come si fa per il codice (documentazione e progetto nello stesso repository);
  • è più veloce da modificare: cambiare una logica significa aggiornare due righe, non ridisegnare frecce e box;
  • è adatto all’automazione (generare diagrammi da script o dati).

Inoltre, per gli studenti è inclusivo: chi fatica con strumenti grafici complessi oppure non è particolarmente allenato nello scrivere codice, può concentrarsi sulla logica invece che sulla formattazione.

Tipi di diagrammi utili nel laboratorio di sistemi con Arduino

  • Flowchart (diagrammi di flusso): progettano il comportamento dello sketch (lettura sensore > confronto con soglia > azione). Perfetti per attività didattiche laboratoriali, come ad esempio con la gestione di: LDR, potenziometri, PWM su LED/buzzer.
  • State diagram (diagrammi di stati): modellano macchine a stati finiti, utili per sistemi reattivi (allarmi luminosi/acustici, sequenze a tempo e molto altro).
  • Sequence diagram: descrivono interazioni nel tempo (Utente > Arduino > Sensore >  Attuatore), utili per chiarire responsabilità e tempi (debounce, ritardi, feedback).
  • Gantt: pianificano attività di laboratorio (ricerca componenti, prototipazione, test, consegna), favorendo un’organizzazione realistica del progetto.
  • ER diagram: modellano dati (es. datalogger con tabelle misure, sensori), utile quando il progetto prevede salvataggi su SD/PC e successiva analisi.

Un flusso di lavoro consigliato (didattico e “versionabile”)

Di seguito trovate il flusso di lavoro che bisognerebbe adottare nello sviluppo di un sistema con Arduino e non solo, ovviamente è suscettibile di modifiche, ma percorrendo i 6 punti molto probabilmente il vostro progetto funzionerà, o come diceva un mio caro amico probabilmente “funzionicchierà” 🙂

  1. Definisci il comportamento atteso del sistema (requisiti minimi e soglie).
  2. Scrivi il flowchart in Mermaid (anche direttamente nel README del progetto).
  3. Aggiungi lo state diagram se il comportamento è meglio descritto per stati.
  4. Deriva lo pseudocodice riga-per-riga dal diagramma.
  5. Implementa lo sketch Arduino e committa insieme a diagrammi e note.
  6. Versiona su GitHub e usa pull request per rivedere sia codice che diagrammi (il diff testuale evidenzia le modifiche di logica).

Esempio pratico

Vediamo ora un esempio minimale pratico che conduce dal diagramma di flusso allo sketch

flowchart TD
A[Start] --> B[Leggi LDR A0]
B --> C{v < soglia?}
C -- Si --> D[LED ON]
C -- No  --> E[LED OFF]
D --> B
E --> B

Lettura della LDR, confronto a soglia, attivazione LED: lo schema diventa facilmente uno sketch con analogRead(), confronto, digitalWrite(). Questo ponte chiaro tra diagramma e codice rende la progettazione più rigorosa e la correzione più rapida.

Strumenti gratuiti per generare il diagramma di flusso

E’ possibile utilizzare diversi software gratuiti o semi-gratuiti che vi consentono di scrivere la descrizione del diagramma e lo traducono immediatamente in un grafico, vi segnalo due software

Mermaid Live Editor

Mermaid Live Editor (browser, nessuna installazione). Accedendo all’applicativo web scriverete sulla sinistra della pagina e se la descrizione del grafico è ben scritta e formatta, vedrete il diagramma a destra della pagina. Sarà possibile esporta in PNG/SVG. Ottimo per le prime esercitazioni.
Per la documentazione ufficiale di Mermaid Live Editor seguite il link.

Drawio

Un altro software credo già molto impiegato nella scuola è draw.io che può essere integrato all’intero degli applicativi Google come estensione oppure potete utilizzare direttamente collegandovi al sito di riferimento drawio.com.
Utilizzare l’applicativo è estremamente semplice e l’importazione di un grafico Mermaid potete farlo seguendo il percorso: Organizza > Inserisci > Mermaid… si aprirà un pannello in cui inserire il testo Mermaid.
L’uso di drawio facilita maggiormente l’editing, in quanto le modifiche avvengono su un editor grafico, pertanto l’orientamento delle frecce di collegamento tra i blocchi, spessori di linee, aggiunte di blocchi ed altro sono probabilmente più semplici, quindi probabilmente potrebbe essere utile insegnare a scrivere il testo Mermaid e poi rielaborarlo in drawio.

Nella prossima lezione vedremo come passare dal diagramma di flusso allo pseudocodice su problemi della vita comune.

Buona progettazione a tutti 🙂