Archivi tag: coding

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 🙂

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 🙂

Comprensione del testo tecnico – Escape game didattico con BBC micro:bit V2 – icebreaker per l’inizio dell’anno scolastico

Grazie ai molti colleghi che hanno apprezzato l’idea del gioco presentata nel post “Comprensione del testo tecnico – Escape game didattico con Arduino UNO R4 – icebreaker per l’inizio dell’anno scolastico“. In diversi mi avete chiesto una proposta analoga per BBC micro:bit V2: ho quindi riadattato un paio di esercizi di base.

Le motivazioni della creazione di un escape game di questo tipo sono le medesime di quelle indicate nel post indicato sopra.

Questa attività è il primo tassello di un percorso più ampio che presenterò nel mio prossimo corso per Tecnica della Scuola, “Carta, Cartone e Coding“, il corso a fine ottobre, con contenuti aggiornati rispetto alle edizioni precedenti. Se vi interessa restare informati, iscrivetevi alle novità tramite il box:  “Iscriviti al blog tramite email” che trovate nella colonna destra del sito.

Condivido anche il Google Site che ospita il gioco: ho mantenuto un’ambientazione fantascientifica perché è lo stile che preferisco, ma ovviamente potete personalizzarla a piacere. Il nome Aurora-β richiama un mio precedente escape, Aurora-α.

Blackout sull’astronave Aurora-β

Spero che questa versione vi sia utile in classe.

Buon coding a tutti! 🙂

Progettare bene, programmare meglio: diagrammi di flusso – Lezione 1/5

Ripasso di inizio anno – appunti per la classe.

Perché bisogna imparare a realizzare i diagrammi di flusso (anche se “programmiamo poco”)?

Quando progetti un programma per Arduino, il problema più grande non è scrivere le parentesi giuste: è decidere l’ordine delle azioni e quando prendere decisioni. Un diagramma di flusso è un disegno semplice che mostra i passi da compiere, le scelte “sì/no” e l’ordine in cui tutto accade. È usato in informatica da decenni proprio per rappresentare, passo-passo, il comportamento di un algoritmo o di un processo.

Un flowchart ti aiuta a vedere il programma prima di scriverlo: rettangoli per le azioni (es. “accendi LED”), rombi per le domande (es. “pulsante premuto?”), ovali per inizio/fine, parallelogrammi per ingresso/uscita di dati, frecce per la direzione. L’idea è sempre quella: dall’alto verso il basso, una freccia alla volta, fino all’uscita. Questa notazione è diventata uno standard di fatto e, nelle versioni “complete”, include molte altre forme utili (ne esistono decine); noi useremo solo quelle essenziali.

Dove si usano e perché ci interessano in laboratorio di sistemi

I diagrammi di flusso non servono solo a chi programma: si usano per documentare, spiegare e migliorare processi in tanti contesti (scuola, aziende, sanità, logistica). Nel nostro laboratorio li usiamo per tradurre un problema reale (una luce che si accende, un sensore che decide) in una sequenza chiara. Questo approccio è lo stesso che trovi nel project management: rappresentare un processo rende più facile pianificare, allineare il team e trovare i colli di bottiglia.

Esistono poi varianti “cugine” dei flowchart che potresti incontrare:

  • Workflow (flusso di lavoro), molto usato per capire chi fa cosa e quando;
  • Swimlane (corsie), utile quando più persone o sottosistemi collaborano;
  • Data Flow Diagram / DFD (flusso di dati), focalizzato su come circolano i dati tra parti di un sistema.

Noi partiamo dal flowchart di base (azioni/decisioni) perché è il ponte più diretto verso il codice Arduino

Buone pratiche “da prima riga di codice”

  • Definisci il problema in una frase (“Cosa voglio ottenere?”).
  • Elenca i passi e le decisioni (domande “sì/no”).
  • Disegna il flusso con poche forme standard (Inizio > Azioni > Decisioni > Fine).
  • Cerca le inefficienze: passaggi inutili, decisioni doppie, attese esagerate.
  • Condividi e rivedi: il diagramma è un documento vivo; aggiornatelo quando cambi idea.

Questa routine è identica a quella usata nei team professionali quando costruiscono o migliorano un processo.

Dalla carta al digitale (e al testo)

Puoi disegnare su carta, usare strumenti visuali come Lucidchart o Miro (trascini le forme e colleghi con frecce), oppure scrivere i diagrammi come testo con Mermaid (“diagram as code”), che si integra bene nei siti e nelle note tecniche. In questa lezione useremo Mermaid proprio per abituarci a ragionare prima in blocchi, poi in pseudocodice, poi in C/C++ per Arduino.

Mappa veloce “flowchart > Arduino”

Inizio / Setup > setup(): qui imposti i pin come INPUT/OUTPUT.
Azione → istruzioni come digitalWrite(), analogWrite(), tone().
Decisione (rombo) > if (...) { ... } else { ... }, spesso con letture da sensori: digitalRead(), analogRead().
Ciclo > loop() che ripete le azioni in sequenza.
Questa corrispondenza 1:1 rende naturale “tradurre” il disegno in codice, riducendo gli errori e il tempo di debug. (Rivedremo questa mappa in ogni esempio pratico.)

Cosa evitare all’inizio

  • Frecce che si incrociano: rendono il percorso confuso.
  • Domande ambigue: un rombo = una domanda con risposta sì/no chiara.
  • Simboli inventati: resta su 4–5 forme standard; andrai veloce e capirai tutto al volo.
  • Salti di logica: se ti perdi, torna ai passi del processo (definisci > elenca > disegna > verifica).

Un buon diagramma di flusso è come una ricetta: indica ingredienti (sensori/attuatori), passaggi (azioni), domande al cuoco (“la pasta è al dente?” > sì/no). Se la ricetta è chiara, il codice funziona e tutti in team capiscono cosa fare.

Nota per i lettori (studenti e non): nei paragrafi successivi troverai la pipeline completa che useremo sempre: Problema > Diagramma (Mermaid) > Pseudocodice > Sketch Arduino, con esempi concreti (LED, pulsante, LDR, buzzer). Questa struttura è pensata per classi che iniziano: potete seguirla anche se non hai mai scritto una riga di codice.

Simboli nei diagrammi di flusso: poche forme bastano

L’elenco delle forme può sembrare infinito, ma non serve conoscerle tutte. Ogni simbolo indica un tipo di passaggio preciso e ha un contesto d’uso ben definito. Quando disegni, se ti senti perso, torna all’essenziale: per la grande maggioranza dei diagrammi bastano davvero alcune forme base; le altre servono in casi specifici. Qui sotto trovi quelle più ricorrenti.

Forme comuni del flowchart

Simbolo del diagramma di flusso Nome Descrizione
Inizio/Fine Segna il punto di avvio o la conclusione del flusso; delimita i confini del processo.
Processo / Azione Indica un passo operativo: un’attività, una funzione o un’elaborazione che “fa qualcosa”.
Decisione Rappresenta una domanda binaria (sì/no, vero/falso) che dirama il percorso su esiti diversi.
Input/Output (Dati) Mostra un ingresso (dato in arrivo, misura, comando) o un’uscita(risultato, messaggio, documento).
Linea di flusso Definisce la direzione della sequenza tra le forme; chiarisce l’ordine dei passi.
Sottoprocesso / Processo predefinito Collega a una procedura già definita altrove o a un gruppo di azioni consolidate.
Connettore in pagina Unisce parti lontane dello stesso schema senza incrociare frecce; migliora la leggibilità.
Connettore fuori pagina Collega a un continua su un’altra pagina; spesso include un riferimento o un codice.
Documento Indica la produzione o l’uso di un documento (ordine, report, lettera, promemoria).
Documenti multipli Come sopra, ma per più documenti generati/gestiti nello stesso passaggio.
Input manuale L’utente digita o inserisce dati a mano (es. login, compilazione di un campo).
Operazione manuale Passo che richiede intervento umano (non automatizzato) per proseguire.
Database / Archivio dati Dati archiviati in modo strutturato e interrogabili (lettura/scrittura/filtri).
Memoria interna Dati conservati all’interno del sistema/dispositivo durante l’elaborazione.
Attesa / Ritardo Indica una pausa temporale o un ritardo prima del passo successivo.
Commento / Nota Aggiunge chiarimenti al lettore; si collega con linea tratteggiata alla parte pertinente.

Alcune varianti di forma e naming possono cambiare leggermente a seconda dello strumento o dello standard adottato; l’insieme di base rimane comunque coerente tra le principali piattaforme.

Nella prossima lezione vedremo quali tool utilizzare per disegnare diagrammi di flusso.

Buon Coding a tutti 🙂

Corso di Processing – lezione 10

Variabili in Processing: dichiarazione, tipi e utilizzo

Una variabile è uno spazio di memoria con un nome, in cui possiamo memorizzare dati da usare e modificare nel corso del nostro programma. In Processing, le variabili sono fondamentali per personalizzare il comportamento degli oggetti grafici, mantenere lo stato del programma, contare, animare, verificare condizioni e molto altro.

1. Cos’è una variabile?

Potete immaginare una variabile come una scatola etichettata in cui potete inserire (e cambiare) un valore. Ogni scatola ha:

  • un nome
  • un tipo di dato
  • un valore (che può cambiare)

Sintassi base:

tipo nome = valore;

Esempio:

int lato = 50; // dichiara una variabile intera chiamata "lato" e le assegna il valore 50

2. Tipi principali di variabili in Processing

Numeri interi – int

Valori numerici senza decimali.

int x = 100;

Numeri con virgola – float

Numeri decimali.

float trasparenza = 127.5;

Valori logici – boolean

Può essere solo true (vero) o false (falso).

boolean attivo = true;

Testi – String

Sequenze di caratteri tra virgolette.

String saluto = "Ciao mondo!";

3. Usare variabili per disegnare

Possiamo usare le variabili per controllare dimensioni, posizione, colore, e altri aspetti grafici.

Esempio: dimensione variabile per un cerchio

int diametro = 100;

void setup() {
  size(400, 400);
  background(255);
  fill(0, 150, 255);
  ellipse(width/2, height/2, diametro, diametro);
}

Modifica il valore di diametro per vedere come cambia il disegno.

4. Variabili e animazioni

Le variabili possono essere aggiornate nel tempo per creare un movimento.

Esempio: far muovere un cerchio

float x = 0;

void setup() {
  size(400, 400);
}

void draw() {
  background(255);
  fill(255, 0, 0);
  ellipse(x, 200, 50, 50);
  x = x + 2; // ogni frame aumenta la posizione
}


Continua a leggere