Archivi tag: programmazione

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 🙂

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 🙂

Guida all’uso di millis() – Lezione 1

Credo che una delle problematiche più ostiche da gestire soprattutto per i neofiti è l’utilizzo degli intervalli di tempo in cui eseguire operazioni con Arduino, mi riferisco all’uso e all’abuso improprio del delay(). Infatti gli studenti scoprono che, sebbene la funzione delay() sia facile da usare, ha degli effetti collaterali importanti; il principale è che ferma l’esecuzione dello sketch Arduino fino a quando non è trascorso il periodo di delay. Quando ciò accade, di solito chi spiega indirizza lo studente sull’esempio di defaut sulla temporizzazione non bloccante che troviamo nell’IDE di Arduino: BlinkWithoutDelay.

Molto spesso però questo confonde ancora di più le idee perché in realtà non si vuole solo far lampeggiare un LED ma si vogliono eseguire più operazioni contemporaneamente, quindi è bene comprendere a fondo il principio di funzionamento del BlinkWithoutDelay prima di poterlo applicare alla propria situazione.

Ho pensato quindi di realizzare qualche post tematico sull’uso di millis(), prendendo spunto dalle spiegazioni che realizzo per gli studenti.

Per usare millis() per la temporizzazione è necessario registrare il momento in cui un’azione si è verificata (ad esempio accensione di un LED ritardata alla pressione di un pulsante) affinché possiate iniziare a contare il tempo trascorso da tale evento, dovrete quindi controllare ad intervalli regolari se il periodo richiesto è trascorso.
Se tale intervallo di tempo non è trascorso allora il vostro programma potrà fare altro fino al prossimo controllo.

Nei programmi che seguono userò i commenti all’interno dello sketch per spiegare l’utilizzo delle varie parti del programma.

Ma cos’è millis()?

La funzione millis() restituisce il numero di millisecondi trascorsi dall’avvio del programma corrente su una scheda Arduino. Questo valore è restituito come un numero di tipo unsigned long.

Come Funziona

  • Incremento Automatico: il conteggio inizia automaticamente quando il microcontrollore sulla scheda Arduino viene alimentato o resettato. Il conteggio continua ad aumentare fino a che la scheda rimane alimentata.
  • Overflow: poiché millis() utilizza una variabile di tipo unsigned long, che ha una dimensione di 32 bit su Arduino, il valore massimo che può raggiungere è 4,294,967,295, dopo aver raggiunto questo valore, si andrà in overflow (ovvero Arduino non è in grado di memorizzare un numero più grande) e il valore restituito da millis() ripartirà da zero. Questo avviene dopo circa 49 giorni e 17 ore dall’ultimo reset della scheda.

Utilizzi di millis()

Di seguito una lista non esaustiva di alcuni utilizzi della funzione millis():

  • Temporizzazione non bloccante: a differenza di delay(), che ferma l’esecuzione del programma per un periodo specificato, millis() può essere utilizzato per realizzare pause o attese senza bloccare altre operazioni. Questo è particolarmente utile in applicazioni multitasking dove altre attività devono continuare ad essere eseguite.
  • Debounce: viene spesso usata per implementare il debounce di pulsanti o switch, riducendo gli effetti dei rimbalzi meccanici che possono causare letture multiple per una singola pressione.
  • Esecuzione di azioni a intervalli regolari: può essere utilizzata per eseguire specifiche azioni a intervalli regolari, come leggere sensori, aggiornare display, o inviare dati.

Pratica di utilizzo

Per utilizzare millis() per la temporizzazione, il vostro sketch deve conoscere il valore attuale del tempo (valore restituito da millis()) e questa rilevazione può essere fatto quando volete, in più punti dello sketch ovviamente dovrebbe essere fatta quando serve, ma vediamo cosa vuol dire.

Tipicamente il valore di millis() conviene registrarlo in una variabile ad inizio loop() o all’interno del setup() in questo modo:

millisCorrente = millis();

Regola di utilizzo:

  1. La variabile millisCorrente deve essere stata precedentemente dichiarata.
  2. Deve essere di tipo unsigned long perché millis() restituisce un intero long senza segno.

Regole generali che valgono per tutti i programmi che realizzerete, lo scrivo perchè puntualmente durante le correzioni qualcuno dimentica questa due regolette:

  1. Il nome della variabile, così come accade per tutte le variabili dovrebbe essere autoesplicativa, quindi il suo nome deve dare informazioni: “a cosa serve”
  2. Inoltre è buona regola utilizzare la notazione Camel Case per gestire nomi di variabili composte da più parole, ciò vale anche per le funzioni.

Come spesso accade durante le attività di laboratorio, lascio come semplicissimo esercizio per lo studente il desumere i componenti utilizzati e connessioni dagli sketch di esempio, quindi fate riferimento a quanto indicato in ogni singolo programma, si tratterà semplicemente di connettere dei LED con in serie un resistore da 220 Ohm. Per quanto riguarda l’ultimo esempio fate riferimento al link indicato che rimanda ad un altro post su questo sito.

Siete ora pronti per seguire le spiegazioni successive.

Continua a leggere

BBC micro:bit – MakeCode Multi-Editor

Durante i miei corsi online mi trovo spesso nella condizione di dover simulare la  trasmissione dati tra due microbit, ad esempio il primo dedicato alla rilevazione della temperatura ed il secondo dedicato alla visualizzazione della temperatura su display, o ancora programmare e gestire istantaneamente due micro:bit reali collegati al medesimo PC.

Per eseguire questa operazione ci viene in aiuto la funzione Multi Editor del MakeCode editor che offre un modo utilissimo per gestire simultaneamente la programmazione di dispositivi diversi. Questa caratteristica permette di avere due finestre di editor separate, una per il trasmettitore e una per il ricevitore, consentendo agli utenti di creare, modificare e testare due programmi contemporaneamente​.

Questa funzionalità si rivela particolarmente utile per simulare l’esperienza reale di gestione di programmi radio sul micro:bit, facilitando lo sviluppo e il testing di comunicazioni wireless tra dispositivi, pertanto questa funzionalità risulta utilissima in  ambito didattico.

Le due aree di programmazione possono esser ridimensionate muovendo orizzontalmente la linea di separazione, oppure possiamo mantenere modalità diverse di vista, ad esempio di codice su un micro:bit e  full screen del micro:bit sull’altra metà.

Nell’esempio mostrato di seguito un semplicissimo programma, realizzato durante uno dei miei corsi, sulla sinistra è presente un micro:bit (1) che trasmette in modo continuo la temperatura rilevata, sulla destra un secondo micro:bit (2) su cui premendo il pulsante A mostra la temperatura rilevata dal micro:bit (1). Questa operazione potrà essere fatta sia in modalità virtuale che reale.

Modalità virtuale:

Modalità reale: entrambi i microbit sono connessi allo stesso computer, vengono programmati ed usati insieme:

Quando farete il pairing tra Browser e micro:bit, vedrete che nel pannello di scelta del dispositivo potrete selezionare più micro:bit, accoppiatene uno alla volta per capire in quale area di programmazione agirete.

Se non riuscite ad effettuare il pairing, scollegate i dispositivi, ricaricate la pagina, riconnettete i micro:bit e riprovate ad effettuare il pairing.

Per provare la versione Multi-edit dell’editor seguite il link.

In alternativa se volete utilizzare la versione Multi-edit utilizzando tutti i file che avete nel vostro account online o nella cache di navigazione seguite il link.

Buon Coding a tutti 🙂

MicroCode – Language – Lezione 4

Editor delle risorse

Sono disponibili due editor, uno che permette la creazione di loghi 5×5 ed uno per la creazione di semplici melodie.

Editor icone LED

L’editor di icone LED permette di selezionare quali LED sono accesi o spenti per ogni  fotogramma di un’animazione. E’ possibile continuare ad aggiungere icone LED in una sequenza (l’editor farà una copia dell’ultima immagine realizzata):

Editor di melodie

L’editor di melodie ti permette di comporre una sequenza di quattro note, dove ogni nota può essere C, D, E, F o G:

Gestire valori numerici

Per i comandi che prevedono un valore numerico come: radio send, imposta variabile), sono disponibili vari blocchi:

  •  constant values 1, 2, 3, 4 e 5 punti
  •  values of variables X, Y e Z
  •  value of the radio receive event , disponibile solo se la sezione WHEN (QUANDO) ha un evento ricezione radio
  • value of the temperature sensor , sempre disponibile
  • random number generator un dado che fornisce in modo predefinito un numero intero casuale tra 1 e 5 (estremi inclusi).

loops

repeat

Il blocco repeat può essere aggiunta ad una serie di comandi per ripetere l’intera sezione DO. Il blocco valore, dopo repeat, determinano il numero di iterazioni. Se non viene fornito un valore, la ripetizione viene eseguita all’infinito.

WHEN: premi il logo micro:bit, DO: viene visualizzato il logo happy e il logo serio sul display e la visualizzazione dei due loghi viene mostrata per tre volte (la sequenza loghi è seguita dal repeat e dal blocco tre puntini).

Buon Coding a tutti 🙂