Archivi categoria: i miei allievi

randomSeed() su Arduino come usarla

In riferimento al precedente post: “Come ottenere più valori da una funzione in Arduino: variabili globali, riferimenti e struct – lezione 1/2” un utente mi ha scritto in privato per chiedermi chiarimenti in merito all’uso di randomSeed(), nello specifico di randomSeed(analogRead(A0)). La spiegazione che ho fornito è diventata alla fine qualcosa che posso riutilizzare con i miei studenti quindi ne ho realizzato un post sul sito in modo che possa essere letto da tutti.

Quando in uno sketch usate random(), state usando un generatore pseudo-casuale: i numeri “sembrano” casuali, ma in realtà seguono una sequenza deterministica. Se riavviate la scheda e non fate nulla, spesso la sequenza riparte uguale. Per evitare questo comportamento (molto evidente nei giochi, nelle simulazioni e nelle attività di laboratorio), Arduino mette a disposizione randomSeed(), che inizializza il punto di partenza della sequenza.

Sintetizzo cosa fa nel dettaglio randomSeed()

  • random() genera numeri pseudo-casuali.
  • randomSeed(seed) imposta il seme (seed), cioè il valore da cui parte la sequenza.

questo vuol dire che:

  • Seed uguale > sequenza uguale.
  • Seed diverso > sequenza diversa.

L’effetto di randomSeed(analogRead(A0)) utilizzato nella lezione precedente è duplice:

  1. legge un valore analogico da A0 con analogRead(A0)
  2. usa quel valore come seme per randomSeed(...)

L’idea (consigliata anche nella documentazione Arduino) è: se A0 è scollegato, la lettura è influenzata dal “rumore” elettrico ambientale e tende a variare; quindi anche il seed cambia e, a ogni reset, random() produce una sequenza diversa.

Però attenzione, un pin “floating” non garantisce casualità perfetta; spesso fornisce poca entropia, ma per scopi didattici (giochi, simulazioni, esercizi) è in genere sufficiente. Ovviamente non è una tecnica adatta a sicurezza/criptografia.

Precisazione: differenze tra UNO R3 e UNO R4

  • Arduino UNO R3: analogRead() è a 10 bit: valori 0–1023.
  • Arduino UNO R4: per compatibilità, analogRead() parte di default a 10 bit (0–1023), ma l’UNO R4 supporta risoluzioni più alte (fino a 14 bit) tramite analogReadResolution().

Questa informazioni può essere utile anche per il seed: più risoluzione vuol dire più livelli possibili nella lettura analogica, quindi (potenzialmente) seed più variabile.

Di seguito alcune proposte di attività da svolgere a scuola o per esercitarsi.
Tutti gli esempi stampano su Serial Monitor. Usate 9600 baud e, quando richiesto, lasciate A0 scollegato.

Attività 01: serie che si ripete – (senza randomSeed)

Obiettivo: vedere che, senza inizializzazione, la sequenza tende a ripetersi dopo un reset
Consegna: fate partire lo sketch, annotate i primi 10 numeri, premete reset e confrontate.

/*
  Prof. Maffucci Michele
  14.02.26
  Attività 01: serie che si ripete - (senza randomSeed)
*/

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

void loop() {
  Serial.println("Primi 10 numeri pseudo-casuali (senza seed):");
  for (int i = 0; i < 10; i++) {
    Serial.println(random(0, 100));
  }
  Serial.println("--- Premi reset della scheda e confronta ---\n");
  delay(3000);
}

Attività 02: Seed fisso = sequenza ripetibile (utile nei test)

Obiettivo: capire che un seed costante produce sempre la stessa sequenza (utile per il debug).
Consegna: verificare che a ogni reset i numeri restano identici.

/*
  Prof. Maffucci Michele
  14.02.26
  Attività 02: capire che un seed costante produce sempre la stessa sequenza (utile per il debug)
*/

void setup() {
  Serial.begin(9600);
  randomSeed(12345); // seed fisso
}

void loop() {
  Serial.println("Primi 10 numeri con seed fisso (12345):");
  for (int i = 0; i < 10; i++) {
    Serial.println(random(0, 100));
  }
  Serial.println("--- Premi reset: deve ripetersi uguale ---\n");
  delay(3000);
}

Attività 03: Seed “rumoroso” con analogRead(A0) (A0 scollegato)

Obiettivo: ottenere sequenze diverse a ogni reset usando randomSeed(analogRead(A0)).
Consegna:

  1. eseguite con A0 scollegato > osservate seed e sequenza
  2. collega A0 a GND o 5V > osservate come seed e sequenza diventano più “stabili” (meno variabili)
/*
  Prof. Maffucci Michele
  14.02.26
  Attività 03: ottenere sequenze diverse a ogni reset usando randomSeed(analogRead(A0))
*/

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

  // A0 deve essere scollegato per sfruttare la variabilità del rumore
  int seme = analogRead(A0);
  randomSeed(seme);

  Serial.print("Seed letto da A0: ");
  Serial.println(seme);
  Serial.println();
}

void loop() {
  Serial.println("Primi 10 numeri con seed da A0:");
  for (int i = 0; i < 10; i++) {
    Serial.println(random(0, 100));
  }
  Serial.println("--- Premi reset: dovrebbero cambiare ---\n");
  delay(3000);
}

Attività 04: utilizzo di UNO R4 per avere seed più “ricco” aumentando la risoluzione (12/14 bit)

Obiettivo: su UNO R4 aumentare la risoluzione ADC e “mescolare” più letture per un seed più variabile.
Consegna:

  • fate 5 reset su UNO R3 e 5 reset su UNO R4, annotate i seed e valutate quanto cambiano
  • su UNO R4 provate anche analogReadResolution(12) e confronta con 14

Lo sketch che segue viene compilato anche su UNO R3: la parte analogReadResolution() viene attivata solo su UNO R4.

/*
  Prof. Maffucci Michele
  14.02.26
  Attività 04: utilizzo di UNO R4 per avere seed più "ricco" aumentando la risoluzione (12/14 bit)
*/

unsigned long creaSeedDaRumoreA0() {
  unsigned long seed = 0;

  // Su UNO R4 puoi aumentare la risoluzione (10 bit default, fino a 14 bit)
#if defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
  analogReadResolution(14);
#endif

  // Mescolo 32 letture per raccogliere più variabilità
  for (int i = 0; i < 32; i++) {
    seed = (seed << 1) ^ (unsigned long)analogRead(A0);
    delay(2);
  }
  return seed;
}

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

  Serial.println("Seed avanzato da A0 (A0 scollegato):");
  unsigned long seed = creaSeedDaRumoreA0();
  Serial.print("Seed calcolato: ");
  Serial.println(seed);

  randomSeed(seed);
  Serial.println();
}

void loop() {
  Serial.println("Primi 10 numeri con seed avanzato:");
  for (int i = 0; i < 10; i++) {
    Serial.println(random(0, 100));
  }
  Serial.println("--- Reset e confronta ---\n");
  delay(3000);
}

Ora vi propongo un piccolo progetto, il classico dado, che sicuramente riuscirete a svolgere velocemente.

Esercizio: “dado elettronico”

Obiettivo: usare random() in un contesto concreto e verificare che con randomSeed i lanci non siano sempre uguali dopo reset.

Vi lascio qualche giorno per provare a sviluppare una soluzione e poi ve ne propongo una io. 🙂

Terminiamo questa lezione riassumendo quanto visto:

  • random() = pseudo-casuale (sequenza deterministica);
  • randomSeed() sposta il punto di partenza della sequenza;
  • randomSeed(analogRead(A0)) funziona solo se A0 varia davvero (meglio scollegato o con una sorgente “rumorosa”);
  • UNO R4 può aumentare la risoluzione ADC con analogReadResolution() (default 10 bit per compatibilità).

Buon Coding a tutti 🙂

Come ottenere più valori da una funzione in Arduino: variabili globali, riferimenti e struct – lezione 1/2

Durante la correzione delle esercitazioni di laboratorio mi accorgo spesso che il passaggio dei valori alle funzioni è un punto che genera parecchia confusione. Per questo ho deciso di preparare una breve lezione di ripasso, per chiarire i concetti fondamentali e aiutare a scegliere l’approccio più corretto nello sviluppo degli sketch.

Uno dei problemi molto comuni quando si programma in C/C++ su Arduino è: come ottenere più di un valore da una funzione?

In molti casi vorremmo che una funzione ci restituisse, ad esempio, due risultati (come nello scambio di due numeri), ma il linguaggio prevede che una funzione possa avere un solo valore di ritorno con l’istruzione return. Questo non significa che siamo bloccati: esistono più strategie corrette per gestire più risultati in modo chiaro e sicuro.

Partiremo da una soluzione semplice e intuitiva, basata su variabili globali, utile per capire il concetto ma generalmente sconsigliata nei programmi reali perché può creare effetti collaterali difficili da controllare. Passeremo poi a un approccio molto più robusto: il passaggio per riferimento, che permette a una funzione di modificare direttamente le variabili del chiamante senza ricorrere a globali. Infine vedremo l’uso dell’istruzione struct, cioè “contenitori” di più campi, che consentono di raggruppare dati correlati e di restituirli come un unico oggetto.

L’obiettivo non è solo far funzionare gli esempi, ma capire cosa succede davvero in memoria quando una funzione riceve parametri “per valore” (copie) oppure “per riferimento” (accesso diretto all’originale) e perché la scelta del metodo influisce su leggibilità, manutenzione e affidabilità del codice. Al termine della lezione saprete riconoscere quale tecnica usare a seconda del problema e scrivere funzioni più pulite, modulari e facili da riutilizzare.

Vedremo poi nella prossima lezione una quarta variante molto diffusa nel mondo embedded.

01. Versione “semplice” (ma sconsigliata): usare variabili globali

Esempio 01: scambio di valori

La funzione non “restituisce” due valori: modifica direttamente due variabili definite fuori da loop().

/*
  Prof. Maffucci Michele
  13.02.26
  Scambio di due valori usando variabili globali.
*/

int valoreA;
int valoreB;

void scambiaGlobali() {
  int temporaneo = valoreA;
  valoreA = valoreB;
  valoreB = temporaneo;
}

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

void loop() {
  valoreA = random(10);
  valoreB = random(10);

  Serial.print("Valori prima dello scambio (A, B): ");
  Serial.print(valoreA);
  Serial.print(", ");
  Serial.println(valoreB);

  scambiaGlobali();

  Serial.print("Valori dopo lo scambio (A, B):  ");
  Serial.print(valoreA);
  Serial.print(", ");
  Serial.println(valoreB);

  Serial.println();
  delay(1000);
}

Esempio 02: la funzione restituisce minimo e massimo aggiornando variabili globali.

Sulla serial monitor vengono mostrati ogni 5 secondi: la serie di 20 numeri generati, il minimo della serie, il massimo della serie.

/*
  Prof. Maffucci Michele
  13.02.26
  Calcola minimo e massimo su una serie di campioni usando variabili globali.
*/

int minimoCampione;
int massimoCampione;

void calcolaMinMaxGlobali(int numeroCampioni) {
  minimoCampione = 9999;
  massimoCampione = -9999;

  Serial.print("Campioni: ");

  for (int i = 0; i < numeroCampioni; i++) {
    int campione = random(0, 101); // 0..100

    // Stampa i campioni separati da virgola
    Serial.print(campione);
    if (i < numeroCampioni - 1) {
      Serial.print(", ");
    } else {
      Serial.println(); // a capo dopo l'ultimo campione
    }

    // Aggiorna minimo e massimo
    if (campione < minimoCampione) {
      minimoCampione = campione;
    }
    if (campione > massimoCampione) {
      massimoCampione = campione;
    }
  }
}

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}

void loop() {
  const int numeroCampioni = 20;

  Serial.print("Genero ");
  Serial.print(numeroCampioni);
  Serial.println(" campioni casuali (0..100) e calcolo min/max...");

  calcolaMinMaxGlobali(numeroCampioni);

  Serial.print("Minimo trovato: ");
  Serial.println(minimoCampione);

  Serial.print("Massimo trovato: ");
  Serial.println(massimoCampione);

  Serial.println();
  delay(5000);
}

02. Passaggio per riferimento

Esempio 01: Scambia due valori passati per riferimento.

/*
  Prof. Maffucci Michele
  13.02.25
  Scambia due valori passati per riferimento.
*/

void scambiaPerRiferimento(int &a, int &b) {
  int temporaneo = a;
  a = b;
  b = temporaneo;
}

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

void loop() {
  int numero1 = random(10);
  int numero2 = random(10);

  Serial.print("Valori prima dello scambio (n1, n2): ");
  Serial.print(numero1);
  Serial.print(", ");
  Serial.println(numero2);

  scambiaPerRiferimento(numero1, numero2);

  Serial.print("Valori dopo lo scambio (n1, n2):  ");
  Serial.print(numero1);
  Serial.print(", ");
  Serial.println(numero2);

  Serial.println();
  delay(1000);
}

Esempio 02: divisione con resto (quoziente + resto)

Nello sketch che segue una funzione calcola due risultati (quoziente e resto) tramite riferimenti, e in più restituisce true/false per gestire il caso del divisore zero.

/*
  Prof. Maffucci Michele
  13.02.26
  Calcola due risultati (quoziente e resto) tramite riferimenti, 
  restituisce true/false per gestire il caso del divisore zero.
*/

bool dividiConResto(int numeratore, int denominatore, int &quoziente, int &resto) {
  if (denominatore == 0) {
    return false; // errore: divisione per zero
  }

  quoziente = numeratore / denominatore;
  resto = numeratore % denominatore;
  return true;
}

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}

void loop() {
  int a = random(0, 101);   // 0..100
  int b = random(0, 11);    // 0..10 (include lo zero apposta)

  int q = 0;
  int r = 0;

  Serial.print("Operazione: ");
  Serial.print(a);
  Serial.print(" / ");
  Serial.println(b);

  if (dividiConResto(a, b, q, r)) {
    Serial.print("Quoziente: ");
    Serial.println(q);

    Serial.print("Resto: ");
    Serial.println(r);
  } else {
    Serial.println("Errore: divisione per zero (b = 0).");
  }

  Serial.println();
  delay(1500);
}

03. Scambio di valori versione migliorata. Trattare più valori insieme: usare una struct

Con la struct impacchettiamo più campi in un solo tipo (una “coppia”), la passiamo alla funzione e la funzione restituisce una nuova struct con i campi scambiati.

Esercizio 01: scambio di valori

/*
  Prof. Maffucci Michele
  13.02.26
  Scambio di valori usando una struct.
*/

struct Coppia {
  int primo;
  int secondo;
};

Coppia scambiaCoppia(Coppia c) {
  int temporaneo = c.primo;
  c.primo = c.secondo;
  c.secondo = temporaneo;
  return c;
}

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

void loop() {
  Coppia dati = { random(10), random(10) };

  Serial.print("Valori prima dello scambio (p, s): ");
  Serial.print(dati.primo);
  Serial.print(", ");
  Serial.println(dati.secondo);

  dati = scambiaCoppia(dati);

  Serial.print("Valori dopo lo scambio (p, s):  ");
  Serial.print(dati.primo);
  Serial.print(", ");
  Serial.println(dati.secondo);

  Serial.println();
  delay(1000);
}

Esempio 02: Lettura analogica completa (raw + volt + percentuale)

La funzione ritorna un oggetto con tre valori: lettura grezza, tensione stimata e percentuale.

/*
  Prof. MAffucci Michele
  13.02.26
  Restituisce più valori raggruppandoli in una struct.
*/

struct LetturaAnalogica {
  int raw;          // 0..1023
  float volt;       // tensione stimata
  int percentuale;  // 0..100
};

const int PIN_INGRESSO = A0;
const float VREF = 5.0; // se usi una scheda a 3.3V, imposta 3.3

LetturaAnalogica leggiAnalogicoCompleto(int pin) {
  LetturaAnalogica risultato;

  risultato.raw = analogRead(pin);
  risultato.volt = risultato.raw * (VREF / 1023.0);
  risultato.percentuale = map(risultato.raw, 0, 1023, 0, 100);

  return risultato;
}

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

void loop() {
  LetturaAnalogica misura = leggiAnalogicoCompleto(PIN_INGRESSO);

  Serial.print("Ingresso A0 -> raw: ");
  Serial.print(misura.raw);

  Serial.print(" | V: ");
  Serial.print(misura.volt, 2);

  Serial.print(" | %: ");
  Serial.println(misura.percentuale);

  delay(500);
}

Abbiamo visto tre strategie diverse per gestire più risultati in una funzione. E’ fondamentale scegliere quale usare nei vostri sketch, è importante capire bene cosa cambia tra passaggio per valore, passaggio per riferimento e uso di una struct.

Riassumo di seguito.

Passaggio dei valori a una funzione

Quando viene chiamata una funzione, potete consegnare i dati in due modi principali:

  1. Per valore (default)
  • la funzione riceve una copia dei parametri;
  • se dentro la funzione modificate quei parametri, state modificando la copia, non le variabili originali;
  • risultato: fuori dalla funzione i valori non cambiano.
  1. Per riferimento (&) — tipico in Arduino perché è C++

  • la funzione riceve un alias delle variabili originali;
  • dentro la funzione, quando assegnate a = …, state scrivendo proprio nella variabile chiamante.
  • risultato: fuori dalla funzione i valori cambiano davvero.

Nota: in C “puro” non esistono i riferimenti, quindi si userebbero puntatori (int *a, int *b). Arduino, però, compila in C++: i riferimenti sono disponibili.

Quando usare una struct (o un tipo “aggregato”)

La struct è utile quando:

  • volete trattare più valori come un unico oggetto logico (es. coordinate, min/max, stato di sensori, ecc.);
  • volete restituire più informazioni in un colpo solo (una sola return, ma con più campi dentro);
  • volete migliorare leggibilità: c.primo, c.secondo comunica il significato meglio di due variabili scollegate.

Costo/beneficio nell’uso della struct

  • Pro: codice più espressivo, dati “impacchettati”, interfaccia pulita.
  • Contro: c’è una copia della struct quando la passi/ritorni (di solito trascurabile se la struct è piccola). Su microcontrollori molto limitati, per struct grandi conviene passare per riferimento anche la struct.

Come detto ad inizio di questo post, nella prossima lezione vedremo una quarta variante molto diffusa nel mondo embedded: gli output parameters con puntatori (stile C) e una versione più moderna che usa const per rendere immediatamente chiaro quali dati sono solo in ingresso e quali vengono modificati dalla funzione.

Buon Coding a tutti 🙂

Arduino nello zaino: 4 “laboratori” trasportabili stampabili in 3D per avere sempre una base di prototipazione pronta

Chi fa didattica laboratoriale (o semplicemente ama sperimentare) lo sa: il problema non è avere gli strumenti, ma riuscire a portare con sé una dotazione minima che permetta di accendere il cervello “maker” ovunque ci si trovi.

Io ho già i miei laboratori completi, a casa e a scuola, dove posso fare tutto ciò che mi serve, però nello zaino porto sempre una piccola base di sperimentazione: una scheda Arduino, una breadboard, qualche cavetto e pochi componenti selezionati. Non è un “mini laboratorio” nel senso classico del termine, ma è qualcosa di altrettanto prezioso: un sistema ordinato e trasportabile che riduce l’attrito e rende immediata qualsiasi micro-attività.

In questo post vi segnalo 4 tipologie di contenitori/workstation stampabili in 3D pensate proprio per questo: tenere insieme scheda, breadboard, jumper e componenti, proteggere il setup e arrivare in aula (o ovunque) già pronto a partire.

Perché ritengo che questi organizer siano utili anche se avete un laboratorio completo

  • setup più veloce: appoggi, apri, colleghi l’USB e inizi;
  • ordine e componenti “a prova di zaino”: meno dispersione, meno “dov’è finito quel cavetto?”;
  • micro-attività replicabili: perfetti per dimostrazioni, tutoraggi, ASL, attività itineranti, laboratori in aule non attrezzate;
  • continuità nelle sperimentazioni personali: potete riprendere un prototipo esattamente dov’era rimasto, senza ricostruire tutto da zero.

All’organizer associo anche un piccolo contenitore rigido in cui dispongo ulteriori componenti elettronici.

The Folding Arduino Lab (il “classico” da zaino)

È quello che uso da sempre: The Folding Arduino Lab di Jason Welsh già segnalato qualche tempo fa su questo sito.
L’idea è semplice: un contenitore compatto che integra Arduino + breadboard (400 punti) + cassetti per cavetti e componenti. In uno spazio ridotto (indicativamente 10×9×8 cm) vi portate dietro l’essenziale.

I motivi per cui uso questa soluzione sono:

  • struttura “a libro”: protegge il setup e lo rende trasportabile, ovviamente non bisogna pretendere molti componenti sulla breadboard;
  • due vani/cassetti: ottimi per jumper, LED, resistenze, pulsanti, piccoli sensori;
  • è un progetto con molte varianti e remix: facile trovare adattamenti e accessori;
  • nota personale: l’autore ha sviluppato diverse versioni; io attualmente utilizzo la versione 2, su cui ho montato un Arduino UNO R4 WiFi.

Vi segnalo che con questo kit potete evitare, per le cerniere, l’uso di elementi metallici che possono essere sostituiti con filamento per la stampa 3D che risultano relativamente robusti e rimovibili.

Supporto/Stazione di lavoro modulare per Arduino UNO e breadboard (modulare e “scalabile”)

Questa soluzione è pensata come una workstation regolabile e modulare, ideale se vuoi una base ordinata non solo per trasporto, ma anche per lavorare “pulito” su banco (e poi richiudere e portare via).
La Modular Arduino UNO Breadboard Holder/Workstation (V2) è dichiarata come progetto modulare, con inserti, tray e mount selezionabili, e con impostazioni/accortezze legate alla stampa “print-in-place” in alcune parti.

Caratteristiche interessanti

  • modularità reale: potete scegliere vassoi/inserti in base a cosa usate (jumper, sensori, viteria, ecc.);
  • approccio “workstation” più che “scatola”: molto comoda per lavorare in modo ordinato;
  • ottima se volete aggiungere nel tempo moduli e supporti (display, sensori, ecc.).

Portable Arduino Lab (PAL) – molto compatto

Il Portable Arduino Lab (PAL) è una versione più piccola della workstation, pensata esplicitamente per “piccoli progetti on the go”, è dichiarato compatibile con Arduino UNO R3 e UNO R4.

Cosa mi piace

  • È progettato come “compagno di laboratorio”: base + chiusura + possibilità di storage;
  • ha indicazioni di stampa molto chiare: per esempio layer height 0,2 mm e attenzione alle tolleranze della cerniera/parti in movimento;
  • pPrevede anche opzioni e aggiornamenti: ad esempio supporti per breakout (ESP32 / Arduino Nano) sono citati tra gli update del progetto.

Nota pratica

In alcune configurazioni richiede viteria (M3x25) e una piccola fase di assemblaggio; non è un difetto, ma una scelta per robustezza e funzionalità.

Arduino R4 Laboratorio Portatile – “print in place” dedicato a UNO R4

Questa soluzione è centrata su Arduino UNO R4 e punta alla massima portabilità con la logica “print-in-place”. È indicato l’uso con breadboard da 400 punti e il fissaggio della scheda con viti M2.5 (fino a una certa lunghezza). (Seguire il link per prelevare i file per la stampa)

Scegliere questa soluzione se:

  • lavorate principalmente con UNO R4 e volete un contenitore dedicato.
  • se vi interessa un progetto già impostato con un layout essenziale: scheda + breadboard + vano.

Cosa mettere nello zaino

Se volete rendere davvero efficace uno di questi organizer, la differenza la fa la scelta dei componenti. Io ragiono per “massima resa didattica con minimo volume”:

  • Arduino (nel mio caso UNO R4 WiFi) + cavo USB;
  • breadboard 400 punti + cavetti jumper (M-M, M-F, F-F in piccola quantità);
  • set micro: LED + resistenze, 1–2 pulsanti, 1 potenziometro;
  • 1 sensore “jolly” (LDR o temperatura/umidità) + 1 attuatore (buzzer o micro-servo);
  • mini cacciavite / pinzetta, un paio di cavetti Dupont extra;
  • (opzionale) Power bank se volete lavorare senza PC per attività specifiche.

Sto realizzando in questi mesi una versione di un mini laboratorio trasportabile contenuto in una rugged bag, le classiche valigette a tenuta stagna molto robuste, le uso spesso per la realizzazione di giochi escape o per contenere apparati delicati, se riuscirò vi mostrerò più avanti il risultato.

Buon Making a tutti 🙂

Configurare Arduino UNO R4 WiFi per Arduino Cloud

Nelle prossime settimane svolgeremo una serie di attività di laboratorio dedicate alla realizzazione di semplici applicazioni IoT con Arduino Cloud, utilizzando come scheda di riferimento Arduino UNO R4 WiFi. Per lavorare in modo ordinato ed efficace, questa guida introduttiva nasce con un obiettivo preciso: accompagnare gli studenti passo dopo passo nella configurazione della scheda e nel collegamento al Cloud, così da essere operativo fin da subito.

Queste attività sono importanti perché ci permetteranno di passare dal classico circuito “che funziona sul banco” a un sistema realmente utile e osservabile: potremo monitorare da computer o da dispositivi mobili lo stato dei sensori (temperatura, luce, presenza, umidità, ecc.), visualizzare i dati su dashboard, registrare misure nel tempo e, quando necessario, intervenire da remoto attivando uscite e comandi (ad esempio LED, relè o attuatori). In altre parole, costruiremo piccoli prototipi che riproducono lo stesso schema operativo di molte soluzioni industriali e domotiche: sensore > rete > dashboard > controllo, con attenzione a affidabilità, leggibilità dei dati e sicurezza di base.

Questa guida è tratta dalla guida ufficiale su cui ho apportato alcune mie modifiche e le ho rese “più didattiche”.

Di seguito dettaglio la procedura essenziale per portare Arduino UNO R4 WiFi “online” collegandola all’Arduino Cloud.

Arduino UNO R4 WiFi, come già dettagliato in precedenti tutorial, integra un modulo radio dedicato (ESP32-S3) che mette a disposizione la connettività WiFi: grazie a questo componente la scheda può collegarsi a Internet e dialogare con i servizi Cloud senza hardware aggiuntivo. Da qui nasce il passaggio chiave dei nostri laboratori: non ci limiteremo a far “funzionare un circuito”, ma impareremo a pubblicare dati, visualizzarli su una dashboard e, quando serve, inviare comandi da remoto.

Al termine della configurazione potrete:

  • caricare sketch anche via rete (OTA, over-the-air) quando previsto dal flusso Cloud,
  • costruire dashboard consultabili da PC o smartphone,
  • monitorare variabili e sensori in tempo reale e, in prospettiva, realizzare prototipi utili per domotica, automazione e telemetria.

Cosa serve

  • Arduino UNO R4 WiFi
  • Arduino Cloud (account gratuito e accesso alla piattaforma)

Configurazione e procedura

Prima di iniziare, se non avete mai utilizzato Arduino Cloud, vi consiglio di dare un’occhiata alla guida “Getting Started With the Arduino Cloud” che vi aiuterà a capire i concetti base e vi farà risparmiare tempo durante la configurazione, però durante le lezioni che seguiranno vi fornirò tutte le indicazioni.

Continua a leggere

Flashcard per lo studio – utilizzare Anki

Visto che siamo in vacanza riprendo i miei appunti sull’organizzazione dello studio, iniziata con le schede Quick Reference, tutto con l’idea di realizzare in un futuro un manuale con esempi da fornire agli studenti. Ho ripreso lo studio delle lingue e quindi ho pensato di realizzare qualcosa in merito all’uso delle flashcard strumento che ritengo utile.

Parto da una domanda che mi è stata fatta da uno studente di seconda superiore poco prima delle vacanze natalizie:

“Prof, ma lei come studiava quando aveva la nostra età?”

È una domanda che torna spesso, e ogni volta mi ricorda una cosa importante: molti studenti immaginano che esista un “metodo segreto”, una tecnica risolutiva che rende lo studio facile e veloce. La mia risposta, invece, è sempre piuttosto disarmante: non studiavo in modo così diverso da voi. Riassunti, schemi, appunti ordinati… e soprattutto flashcard.

Le flashcard, però, non erano una soluzione “magica”. Erano uno strumento semplice, che funzionava solo a una condizione: usarle con costanza, a piccole dosi, nel tempo. Ho sempre pensato che nello studio valga una regola che sembra banale ma è decisiva: meglio poco, ma ripetuto nel tempo. È questo che trasforma un ripasso occasionale in un apprendimento stabile. E naturalmente, con gli anni, ognuno costruisce il proprio equilibrio: c’è chi rende più efficaci gli schemi, chi preferisce i riassunti, chi trova nelle flashcard la leva migliore per fissare concetti, definizioni, formule o passaggi procedurali.

Oggi, quando mi capita di usare le flashcard per imparare (ad esempio per le lingue o per memorizzare lessico tecnico), mi affido spesso ad Anki. Non perché sia “l’ennesima app per fare flashcard”, ma perché introduce un’idea molto concreta: invece di ripassare tutto allo stesso modo e negli stessi momenti, ti aiuta a ripassare solo ciò che serve, quando serve. Ti porta a fare una cosa che tende a essere faticosa ma estremamente efficace: provare a ricordare attivamente prima di guardare la risposta. E quel tentativo di richiamo, ripetuto con regolarità, è spesso la differenza tra “l’ho letto” e “lo so”.

Per gli studenti questo significa ridurre l’effetto delle maratone dell’ultimo minuto e costruire memoria a lungo termine con un metodo più sostenibile. Per i docenti significa avere uno strumento che rende più gestibile il ripasso distribuito e la personalizzazione, senza limitarsi al classico “ripasso pre-verifica”.
C’è poi un aspetto che, a scuola, conta più di quanto sembri: Anki è un progetto libero e open source (in particolare nella versione desktop), sostenuto da una comunità ampia e da un ecosistema di estensioni. In pratica, non sei legato a una piattaforma chiusa: puoi costruire nel tempo un archivio di materiali che resta tuo, riutilizzabile e migliorabile anno dopo anno.

Nei paragrafi che seguono vediamo cosa rende Anki diverso da altri strumenti di studio, quali vantaggi offre in modo concreto e come iniziare con un tutorial essenziale e due esempi pratici, subito adattabili alle vostre discipline.

Gli appunti che seguono sono una sintesi del manuale che trovate sul sito di riferimento e che ho riformulato e sintetizzato, troverete poi alcuni esempi di flashcard sull’uso di Arduino.

Anki nello studio

C’è un momento che studenti e docenti conoscono bene: hai studiato “davvero”, magari anche con impegno costante, eppure dopo pochi giorni ti accorgi che alcuni passaggi si sono sfilacciati. Non è (solo) una questione di volontà, è più spesso una questione di come ripassi e quando lo fai.

Anki è un programma di flashcard “intelligenti” che pianifica per voi il ripasso: vi mostra una domanda, vi chiede di rispondere, poi usa il vostro feedback per decidere quando rivedrete quella stessa informazione. In altre parole: voi pensate ai contenuti, Anki si occupa del calendario del ripasso.

Anki nasce esattamente per rispondere a questo problema quotidiano: non vi chiede di studiare di più, vi aiuta a sprecare meno. Invece di ripassare tutto allo stesso modo e nello stesso momento, vi porta a rivedere ciò che state per dimenticare, quando serve davvero. La logica di fondo è quella di allenare il cervello con due leve molto concrete: richiamo attivo (provare a ricordare prima di controllare) e ripetizione distanziata (rivedere a intervalli crescenti).

Perché Anki è interessante rispetto ad altri applicativi

  1. Trasforma lo studio passivo in apprendimento che resta
    Rileggere, sottolineare, “ripassare scorrendo” sono abitudini comprensibili: danno l’idea di essere produttivi. Ma spesso si basano sul riconoscimento, non sul recupero. Quando invece vi trovate davanti a una domanda e dovete rispondere senza aiuti, state facendo ciò che il manuale chiama test di richiamo attivo: è faticoso, sì, ma è proprio quella fatica “buona” che rende la memoria più stabile.
  2. Ripassate meno, ma meglio (ripetizione distanziata)
    Il cervello tende a scartare in fretta ciò che non viene usato. Ecco perché il ripasso “a ondate” (tutto la sera prima) funziona male sul lungo periodo. Anki applica invece la ripetizione distanziata: ciò che ricordate bene torna dopo più tempo; ciò che vi è difficile ricompare prima. Il risultato pratico è semplice: non ripassate “a caso”, ma in modo mirato, con intervalli che crescono mentre la memoria si consolida.
  3. È personalizzabile: funziona per materie diverse e livelli diversi
    Anki non è “solo per le lingue” o “solo per medicina”. Se una cosa si può chiedere in forma di domanda (e verificare con una risposta), allora si può allenare con Anki: definizioni, formule, passaggi di procedure, date, classificazioni, concetti chiave e potete farlo anche con materiali ricchi: immagini, audio, video, notazione scientifica (LaTeX/Math).
  4. Open source e free: vantaggi concreti
    Qui Anki ha un valore particolare, soprattutto a scuola:

    • Desktop open source: il codice di Anki è pubblicato con licenza GNU AGPL v3 o successiva (con alcune parti sotto licenze differenti, come indicato nel repository). Questo significa continuità, verificabilità e un progetto che non dipende da una “scatola chiusa”.
    • Ecosistema di add-on: Anki si estende con componenti aggiuntivi, spesso nati da bisogni reali di docenti e studenti (lingue, layout, gestione, workflow).
    • Controllo e portabilità dei materiali: puoi esportare e trasferire mazzi “impacchettati” con contenuti e media, utile per backup e condivisione ragionata.
    • Multi-piattaforma e sync: esiste un servizio di sincronizzazione gratuito (AnkiWeb) per tenere allineati i contenuti tra dispositivi.
    • Android open source: AnkiDroid è su GitHub e dichiara licenze libere (GPL-3.0, con componenti specifiche sotto altre licenze).

Nota utile per evitare equivoci: su iOS l’app ufficiale AnkiMobile è a pagamento; la pagina App Store spiega che le vendite finanziano lo sviluppo.

  1. Un “sistema” più che un’app
    Molti strumenti per flashcard si fermano al “fronte/retro”. Anki, invece, è un piccolo sistema di studio: statistiche, ricerca, tag, opzioni di pianificazione, modelli delle carte, sincronizzazione, backup. Per chi vuole ottimizzare ulteriormente, oggi esiste anche un pianificatore alternativo (FSRS) integrato nelle opzioni.

Mini-tutorial usare Anki

Continua a leggere