Archivi categoria: i miei allievi

Arduino – while: ripetere finché la condizione è vera (controllo in ingresso)

while esegue un blocco finché la condizione è vera, ma controlla prima di entrare. È perfetto per attese (pulsante premuto, dato disponibile), conteggi con condizione di uscita, e loop che possono saltare del tutto se la condizione è già falsa.

Sintassi

while (condizione) {
  // esegue se (e finché) condizione è vera
}
  • se la condizione è falsa all’inizio, il corpo non la esegue nemmeno una volta;
  • molto usato per polling di eventi e attese non bloccanti (con accortezza sui ritardi).

I primi tre esempi che seguono, propongono funzionalità molto simili a quelle realizzate nella lezione precedente sull’uso del do..while. Come sempre nei commenti le spiegazioni di approfondimento.

Esempio 01 – Attendere la pressione di un pulsante

Utilizziamo un pulsante connesso al pin 2 ed abilitiamo la resistenza di bull-up.

/*
  Prof. Maffucci Michele
  data: 28.10.25

  Premere il pulsante su D2 per proseguire;
  LED lampeggia durante l’attesa.
*/

const int PIN_BTN = 2;  // collegato a GND con INPUT_PULLUP

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PIN_BTN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Premi il pulsante per continuare...");
}
void loop() {
  // Attesa attiva: finché il pulsante NON è premuto
  while (digitalRead(PIN_BTN) == HIGH) {  // HIGH = non premuto (pull-up)
    digitalWrite(LED_BUILTIN, HIGH);
    delay(150);
    digitalWrite(LED_BUILTIN, LOW);
    delay(150);
  }
  Serial.println("Pulsante premuto: procedo!");
  while (true) {}
}

Esempio 02 – Countdown finché t > 0

Utilizziamo un buzzer connesso al pin 5.

/*
  Prof. Maffucci Michele
  data: 28.10.25

  Countdown da 10 a 0; beep a fine conteggio (buzzer su D5)
*/

const int PIN_BUZ = 5;
void setup() {
  Serial.begin(9600);
  pinMode(PIN_BUZ, OUTPUT);
}
void loop() {
  int t = 10;
  while (t > 0) {
    Serial.print("T-");
    Serial.println(t);
    delay(500);
    t--;
  }
  tone(PIN_BUZ, 880, 300);  // beep
  Serial.println("Decollo!");
  while (true) {}
}

Esempio 03 – Leggere finché c’è un dato sulla seriale (svuotare buffer)

Ogni volta che scriviamo un testo e premiamo invio, questo viene mostrato come output sulla Serial Monitor.

/*
  Prof. Maffucci Michele
  data: 28.10.25

  Svuota il buffer leggendo tutti i caratteri arrivati finché disponibili
*/

void setup() {
  Serial.begin(9600);
  Serial.println("Scrivi qualcosa e premi invio");
}
void loop() {
  if (Serial.available() > 0) {
    Serial.print("Ricevuto: ");
    while (Serial.available() > 0) {
      char c = Serial.read();
      Serial.write(c);  // eco del testo
    }
    Serial.println();
  }
}

Esempio 04 – Conta impulsi in 5 secondi (sensore su D2)

Contiamo quante volte un sensore digitale (fotointerruttore, reed, finecorsa) o un pulsante, cambia stato in una finestra temporale di 5 s. Abilitiamo anche in questo caso la resistenza di pull-up si D2.

/*
/*
  Prof. Maffucci Michele
  data: 28.10.25

  Conta impulsi in 5 secondi (D2)
  - Collega un sensore digitale su D2 (INPUT_PULLUP, attivo-basso).
  - Conta quante transizioni LOW->HIGH avvengono in 5 s.
*/

const int PIN_SENSORE = 2;

void setup() {
  Serial.begin(9600);
  pinMode(PIN_SENSORE, INPUT_PULLUP);
  Serial.println("Pronto. Avvio finestra di misura di 5 secondi...");
}

void loop() {
  // finestra temporale di 5 s (5000 ms) usata con millis() per la misura
  const unsigned long finestra = 5000;
  unsigned long t0 = millis();
  int impulsi = 0;

  int statoPrecedente = digitalRead(PIN_SENSORE);

  // Esegue finché non scadono i 5 secondi
  while (millis() - t0 < finestra) { int stato = digitalRead(PIN_SENSORE); // conta il fronte di salita (LOW -> HIGH con pull-up)
    if (statoPrecedente == LOW && stato == HIGH) {
      impulsi++;
    }
    statoPrecedente = stato;
  }

  Serial.print("Impulsi contati in 5 s: ");
  Serial.println(impulsi);

  // Pausa informativa e ripeti
  delay(1000);
}

Esempio 05 – Leggi una stringa fino al terminatore ‘#’

Vengono raccolti tutti i caratteri inseriti sulla serial Monitor fino al carattere # e successivamente all’invio, viene stampata la frase.

/*
  Prof. Maffucci Michele
  data: 28.10.25

  Lettura stringa con terminatore '#'
  - Scrivi nel Serial Monitor una frase e termina con '#'
  - Il programma raccoglie i caratteri fino a '#', poi stampa la frase.
  - Imposta 9600 baud. "No line ending" consigliato.
*/

void setup() {
  Serial.begin(9600);
  Serial.println("Digita una frase e termina con '#':");
}

void loop() {
  // Attende che arrivi almeno un carattere per partire
  // Nessun dato in arrivo: esci da loop() e riprova al prossimo ciclo (evita di eseguire il resto del codice)
  if (Serial.available() == 0)
    return;

  String frase = "";
  char c = '\0';

  // Leggi finché non arriva il terminatore '#'
  while (c != '#') {
    
    // Se non c'è ancora nulla, continua ad attendere, ricontrolla il buffer al prossimo ciclo di while
    // Con continue si passa subito alla prossima iterazione del while
    // (cioè al prossimo controllo della condizione c != '#'),
    // senza eseguire le istruzioni che seguono nel corpo del ciclo.
    if (Serial.available() == 0)
      continue;

    c = Serial.read();
    if (c == '\r' || c == '\n')
      continue;                // ignora a capo
                               // salta il resto e riparte il ciclo, così non aggiungi \r/\n alla stringa raccolta
    if (c != '#') frase += c;  // accumula solo se non è il terminatore
  }

  Serial.print("Hai scritto: ");
  Serial.println(frase);

  // Pulisci eventuali residui e proponi una nuova acquisizione
  while (Serial.available() > 0)
    Serial.read();
  Serial.println("Digita una nuova frase terminata da '#':");
}

Ricordare che:

  • return in loop(): termina l’intera iterazione di loop() (si ricomincia dal prossimo giro della funzione loop());
  • continue: termina solo l’iterazione corrente del ciclo in cui si trova (es. il while interno), poi il ciclo riparte al prossimo ciclo del while;
  • alternative senza continue: si può usare una struttura con else { ... }, ma continue mantiene il corpo più lineare quando si vogliono saltare casi particolari.

Esempio 06 – “Dado” mentre il pulsante è premuto (animazione live)

Tenendo premuto un pulsante, si “fa girare” un numero casuale 1–6; finché il pulsante è premuto l’animazione continua, quando si rilascia il numero si blocca (come lanciare un dado).

/*
  Prof. Maffucci Michele
  data: 28.10.25
  
  Dado con pulsante (D2) e animazione in attesa
  - INPUT_PULLUP su D2 (premuto = LOW)
  - Finché il pulsante è PREMUTO, mostra numeri 1..6 che scorrono.
  - Al rilascio, stampa il risultato finale.
*/

const int PIN_BTN = 2;  // collegare pulsante a GND (INPUT_PULLUP)

void setup() {
  Serial.begin(9600);
  pinMode(PIN_BTN, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  randomSeed(analogRead(A0));  // inizializza generatore
  Serial.println("Tieni premuto il pulsante per 'far girare' il dado, poi rilascia.");
}

void loop() {
  // Attendi pressione (attivo-basso)
  if (digitalRead(PIN_BTN) == HIGH)
    return;

  int ultimoNumero = 1;

  // Finché il pulsante rimane premuto, scorrono i numeri
  while (digitalRead(PIN_BTN) == LOW) {
    ultimoNumero = random(1, 7);  // 1..6
    Serial.print("Dado: ");
    Serial.println(ultimoNumero);

    // piccolo effetto visivo sul LED
    digitalWrite(LED_BUILTIN, HIGH);
    delay(60);
    digitalWrite(LED_BUILTIN, LOW);
    delay(60);
  }

  // Debounce semplice sul rilascio
  delay(30);
  if (digitalRead(PIN_BTN) == HIGH) {
    Serial.print("Risultato finale: ");
    Serial.println(ultimoNumero);
    Serial.println("---");
    delay(300);
  }
}

Esercizi

Esercizio 01 – Validazione di input numerico (range 1..10)

Chiedere all’utente un numero intero tra 1 e 10. Finché l’input non è valido, ripetere la richiesta (usare while). Quando è valido, stampare “Valore accettato: X”.

Esercizio 02 – Algoritmo di Euclide (MCD) con while

Leggere due interi positivi a e b dal Serial Monitor e calcolare il Massimo Comun Divisore usando il metodo di Euclide:
ripetere finché b != 0 la sostituzione a, b = b, a % b. Alla fine stampare MCD = a.

Esercizio 03 – Servo: scansione fino al finecorsa (stato controllato con while)

Collegare un servo (pin D9) e un finecorsa su D2 (con INPUT_PULLUP). Far ruotare il servo dal minimo verso il massimo (per passi di 2–3 gradi) finché il finecorsa NON viene premuto (LOW). Quando il finecorsa si attiva, fermarsi e stampare l’angolo raggiunto.

Buon lavoro 🙂

Arduino – istruzione “do…while” – soluzione esercizi proposti

In riferimento alla lezione: Arduino – istruzione “do…while”: eseguire almeno una volta, poi verificare pubblico una possibile soluzione agli esercizi proposti.

Esercizio 01 – Attendi pulsante

  • Consegna: attendere che un pulsante su D2 venga premuto; durante l’attesa far lampeggiare il LED integrato.
  • Vincoli: usare while come attesa in ingresso (while(digitalRead(…)==HIGH)).
  • Extra: al termine, stampare “OK” e fermarsi.

Soluzione

/*
  Prof. Maffucci Michele
  data: 27.10.25

  Soluzione esercizio 01 - Attendi pulsante
  Hardware:
    - Pulsante su D2 con INPUT_PULLUP (un capo a D2, l'altro a GND)
    - LED integrato (pin 13)
  Obiettivo:
    - Lampeggiare il LED mentre si attende la pressione del pulsante
    - Usare while(digitalRead(PIN_BTN) == HIGH) come attesa
    - Quando il pulsante viene premuto -> stampare "OK" e fermarsi
*/

// PIN_BTN dichiarato come byte e non come int per occupare meno spazio di memoria
// collegare il pulsante a GND (INPUT_PULLUP)

const byte PIN_BTN = 2;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PIN_BTN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Premi il pulsante per continuare...");
}

void loop() {
  // Attesa attiva: finché il pulsante NON è premuto (HIGH con pull-up)
  // il LED_BUILTIN (13) lampeggia
  while (digitalRead(PIN_BTN) == HIGH) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(150);
    digitalWrite(LED_BUILTIN, LOW);
    delay(150);
  }

  // Debounce semplice per elimina rimbalzi meccanici
  // realizzato con piccolo ritardo
  delay(30);
  
  while (digitalRead(PIN_BTN) == LOW) {  // resta qui finché è tenuto premuto
  }

  Serial.println("OK");
  digitalWrite(LED_BUILTIN, HIGH);      // lascia il LED acceso come conferma
  while (true) {}                       // ferma la demo
}

Esercizio 02 – Svuota buffer seriale

  • Consegna: quando l’utente invia testo, fare echo e svuotare tutti i caratteri residui.
  • Vincoli: usare while(Serial.available()>0).
  • Extra: contare quanti byte sono stati letti e mostrarli.

Soluzione

/*
  Prof. Maffucci Michele
  data: 27.10.25

  Soluzione esercizio 02 — Svuota buffer seriale
  Obiettivo:
    - Appena arriva del testo, fare echo di TUTTI i caratteri presenti nel buffer
    - Usare while(Serial.available() > 0) per svuotare il buffer
    - Contare i byte letti e mostrarli
  Ricordare:
    - Impostare il Serial Monitor a 9600 baud
*/

void setup() {
  Serial.begin(9600);
  Serial.println("Scrivi una riga di testo e premi invio...");
}

void loop() {
  if (Serial.available() > 0) {
    int conteggioByte = 0;

    Serial.print("Echo: ");
    // Legge TUTTO ciò che è attualmente in buffer
    while (Serial.available() > 0) {
      char c = Serial.read();     // leggi un byte
      Serial.write(c);            // echo (stampa il carattere così com'è)
      conteggioByte++;            // conta i byte letti
      // piccola attesa facoltativa per dare tempo al buffer di riempirsi
      delay(1);
    }
    Serial.println();
    Serial.print("Byte letti: ");
    Serial.println(conteggioByte);
    Serial.println("----");
  }
  // Se serve introdurre qui altro codice non bloccante
}

Attenzione!

Può capitare che vengano contati due byte in più, ciò accade perché la Serial Monitor (in basso a destra)
aggiunge automaticamente i caratteri di fine riga quando premete invio.

  • entrambi NL & CR (Both NL & CR) > aggiunge due byte: \r (CR, 13) e \n (LF, 10) → ecco il tuo +2 costante;
  • a capo NL (Newline) > aggiunge un byte: \n > +1;
  • ritorno carrello (CR) (Carriage return) > aggiunge un byte: \r > +1;
  • nessuna fine riga (No line ending) > +0 (il conteggio coincide con i caratteri digitati, salvo caratteri non ASCII).

Esercizio 03 – Timer regressivo

  • Consegna: da un valore t letto da Serial (es. 5..20), eseguire un countdown finché t>0.
  • Vincoli: usare while(t>0) con t– e stampa del tempo.
  • Extra: beep finale + messaggio “Decollo!”.

Soluzione

/*
  Prof. Maffucci Michele
  data: 27.10.25

  Soluzione esercizio 03 — Timer regressivo
  Obiettivo:
    - Leggere un intero t (5..20) dal Serial Monitor
    - Eseguire while(t > 0) con stampa del tempo e t--
    - Al termine: beep su D5 e messaggio "Decollo!"
  Note:
    - Usa Serial.parseInt() per semplicità (attende un numero)
    - Per maggior informazioni sull'uso di parseInt() consultare il link:
      https://wp.me/p4kwmk-4Ah
*/

const int PIN_BUZ = 5;  // collegare un buzzer piezo (se disponibile)

void setup() {
  Serial.begin(9600);
  pinMode(PIN_BUZ, OUTPUT);
  Serial.println("Inserisci un numero intero t tra 5 e 20 e premi invio:");
}

void loop() {
  int t = 0;

  // Attendi un numero valido nell'intervallo [5..20]
  while (t < 5 || t > 20) {
    if (Serial.available() > 0) {
      t = Serial.parseInt();  // legge il primo intero disponibile
      // Svuota residui (ad es. '\n')
      while (Serial.available() > 0) Serial.read();

      if (t < 5 || t > 20) {
        Serial.println("Valore non valido. Inserisci un numero tra 5 e 20:");
      }
    }
  }

  // Countdown con while(t > 0)
  while (t > 0) {
    Serial.print("T-");
    Serial.println(t);
    delay(1000);  // 1 secondo
    t--;
  }

  // Fine: beep + messaggio
  tone(PIN_BUZ, 880, 350);  // beep di 350 ms
  Serial.println("Decollo!");

  while (true) {}  // ferma la demo
}

Buon lavoro.

Arduino – istruzione “do…while”: eseguire almeno una volta, poi verificare

Pubblicherò alcuni approfondimenti che serviranno per lo svolgimento di futuri esercizi che svolgeremo in classe e che sicuramente potranno essere di aiuto per risolvere l’attività di educazione civica: “dirimere i conflitti con il pensiero computazionale”.

Gli approfondimenti saranno su:

  1. istruzione do…while
  2. istruzione while
  3. lettura caratteri da serial monitor (che affronteremo anche in questa lezione)
  4. loop infiniti con for, while, do while

Alla fine troverete esercizi da svolgere, se riuscirò pubblicherò su queste pagine la soluzione, altrimenti lo faremo direttamente in classe.

do…while

L’istruzione do…while è utile quando un blocco di codice deve essere eseguito almeno una volta prima di verificare una condizione. È ideale per interazioni utente-centriche (es. chiedere conferma), letture che vanno fatte comunque almeno una volta (prima misura da sensore), o cicli in cui la condizione si conosce solo dopo aver eseguito un passo (validazione di input).

Spiegazione

Sintassi

do {
  // corpo: eseguito almeno una volta
} while (condizione);
  • Il controllo è a fine ciclo: se condizione è vera, il ciclo ripete; se è falsa, esce.
  • Evita pre-inizializzazioni “finte” solo per entrare nel ciclo.

Esempio 01: conferma utente da Serial (Y/N)

// Prof. Maffucci Michele
// data: 26.10.2025
// Esempio 01 - Ripasso uso dell'istruzione do...while

// Chiede conferma almeno una volta; normalizza input
void setup() {
  Serial.begin(9600);  // inizializza la Serial Monitor
  Serial.println("Conferma operazione? (y/n)");
}
void loop() {
  bool confermato = false;
  char scelta;
  do {
    if (Serial.available()) {
      scelta = Serial.read();
      if (scelta >= 'A' && scelta <= 'Z') {
        scelta = scelta - 'A' + 'a';
      }
      confermato = (scelta == 'y' || scelta == 'n');
    }
  } while (!confermato);

  Serial.print("Hai scelto: ");
  Serial.println(scelta == 'y' ? "SI" : "NO");
  while (true) {}  // fine dimostrazione
}

A cosa serve inserire: “while (true) {}” alla fine dell’esempio?

Evita che il codice prosegua oltre la dimostrazione e che il loop() ricominci, quindi è possibile effettuare un solo inserimento.

Se si commenta while (true) {} è possibile continuare ad inserire “y” o “n”

Come rendiamo case-insensitive (indifferente a maiuscole/minuscole) l’input

if (scelta >= 'A' && scelta <= 'Z') {
  scelta = scelta - 'A' + 'a';
}

Controllo dell’intervallo: scelta >= 'A' && scelta <= 'Z'

  • Verifica se il carattere è una lettera maiuscola ASCII tra A e Z.

Conversione in minuscolo: scelta = scelta - 'A' + 'a';

  • Trasforma quella maiuscola nella corrispondente minuscola.

Perché si usa: “- ‘A’ + ‘a’”

Come indicato anche nelle mie slide: “Alfabeto Arduino”, nel set ASCII, le lettere maiuscole e minuscole sono “a blocchi” distanziati da una differenza costante (32 in decimale).

  • ‘A’ ha codice 65, ‘a’ ha codice 97;
  • qualsiasi lettera: 'C' - 'A' = 2 (offset dentro il blocco maiuscole);
  • sommando questo offset a 'a': 2 + 'a' = 'c'.

Quindi:

  • Esempio concreto:
    scelta = 'C' - 'A' + 'a' che sostituendo i codici ASCII otteniamo 67 – 65 + 97 = 99 che è il codice ASCII di ‘c’.

Scriverlo con ‘A’ e ‘a’ (invece di 65 e 97) è più leggibile e non vi fa ricordare numeri.

Quanto è utile

  • rendere i comandi indifferenti al minuscolo o maiuscolo: l’utente può digitare Y o y e il programma li tratta allo stesso modo;
  • Evitare duplicazioni: non servono due rami separati per maiuscolo/minuscolo.

Limiti

  • funziona per le lettere A-Z dell’ASCII standard;
  • non gestisce caratteri accentati né Unicode (Arduino classico usa byte ASCII);
  • lascia invariati numeri e simboli (non entrano nell’if).

Vedremo in successive lezioni l’uso di altri strumenti per la gestione di stringhe inserite sulla Serial Monitor.

Esempio 02: prima lettura sensore, poi ripeti finché entro soglia

Per simulare un sensore in questo esempio viene utilizzato un trimmer collegato sul reoforo centrale ad A0 ed i due reofori laterali uno a GND e l’altro a Vcc.

// Prof. Maffucci Michele
// data: 26.10.2025
// Esempio 02 - Ripasso uso dell'istruzione do...while
// LED su pin 13: lampeggia finché la lettura NON è entro la fascia [450..550]

void setup() {
  Serial.begin(9600);  // inizializza la Serial Monitor
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
  int valore;
  do {
    valore = analogRead(A0);  // lettura comunque almeno una volta
    Serial.print("Valore: ");
    Serial.println(valore);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
  } while (valore < 450 || valore > 550);  // ripeti finché fuori dalla fascia
  Serial.println("Valore entro soglia: ok");
  // ripete una sola volta l'analisi (non ripete il loop()), se desiderate ripetere eliminare il ciclo infinito
  while (true) {}
}

Esempio 03: menu: mostra almeno una volta, poi ripeti finché la scelta risulta non valida

// Prof. Maffucci Michele
// data: 26.10.2025
// Esempio 03 - Ripasso uso dell'istruzione do...while
// Mostra un piccolo menu e accetta comandi 'a' 'b' 'x'; richiede almeno un giro

void setup() {
  Serial.begin(9600);
}
void loop() {
  char cmd = 0;
  do {
    Serial.println("Menu: a=avvia  b=blocca  x=uscita");
    while (!Serial.available()) {}
    cmd = Serial.read();
  } while (cmd != 'a' && cmd != 'b' && cmd != 'x');

  Serial.print("Comando accettato: ");
  Serial.println(cmd);
  // ripete una sola volta l'analisi (non ripete il loop()), se desiderate ripetere eliminare il ciclo infinito
  while (true) {}
}

In questo caso se commentate while (true) {} potete effettuare nuovi inserimenti ma potrebbe accadere qualcosa di molto simile a ciò che è indicato nell’immagine che segue

Quello che vedete non è un bug misterioso 🙂 è il buffer seriale + newline, ma cosa vuol dire?

Quando togliamo while (true) {}, il loop() ricomincia da capo.

Consideriamo la parte di codice dell’esempio:

do {
  Serial.println("Menu: a=avvia  b=blocca  x=uscita");
  while (!Serial.available()) {}
  cmd = Serial.read();                 // <-- legge SOLO il primo byte
} while (cmd!='a' && cmd!='b' && cmd!='x');

la Serial Monitor di Arduino (a seconda dell’impostazione “Line ending”) invia anche \n e/o \r oltre alla lettera che digitate.
Poiché leggete un solo carattere (cmd = Serial.read()) e non svuotate il buffer, restano in coda \r e/o \n.

Al giro successivo del do...while (o al restart del loop()), Serial.available() è già > 0 (ci sono dei newline in coda) quindi:

  • il menu viene stampato subito;
  • viene letto il carattere successivo (che è \n o \r, quindi non valido);
  • la condizione del do...while fallisce e viene ristampato il menu.

Risultato: la stringa compare più volte di fila.

2 modi per risolvere il problema della ripetizione

01. Leggere il primo carattere utile, saltando CR/LF

Viene ignorato esplicitamente \r e \n:

char leggiCharPulito() {
  while (true) {
    while (!Serial.available()) {}
    char c = Serial.read();
    if (c == '\r' || c == '\n') continue;         // salta newline
    if (c >= 'A' && c <= 'Z') c = c - 'A' + 'a';  // normalizza
    while (Serial.available())
      Serial.read();  // svuota residui
    return c;
  }
}

// uso:
do {
  Serial.println("Menu: a=avvia  b=blocca  x=uscita");
  cmd = leggiCharPulito();
} while (cmd != 'a' && cmd != 'b' && cmd != 'x');

02. Impostare il Serial Monitor su “No line ending”

Soluzione molto più semplice che prevede di impostare nel menù a tendina del Serial Monitor (in basso a destra), la selezione di Nessun fine riga (in inglese: No line ending).
Così non verranno inviati \r o \n e il problema dei “doppioni” si elimina.

Proposta di esercizi

Esercizio 01 –  Attendi pulsante

  • Consegna: attendere che un pulsante su D2 venga premuto; durante l’attesa far lampeggiare il LED integrato.
  • Vincoli: usare while come attesa in ingresso (while(digitalRead(…)==HIGH)).
  • Extra: al termine, stampare “OK” e fermarsi.

Esercizio 02 – Svuota buffer seriale

  • Consegna: quando l’utente invia testo, fare echo e svuotare tutti i caratteri residui.
  • Vincoli: usare while(Serial.available()>0).
  • Extra: contare quanti byte sono stati letti e mostrarli.

Esercizio 03 – Timer regressivo

  • Consegna: da un valore t letto da Serial (es. 5..20), eseguire un countdown finché t>0.
  • Vincoli: usare while(t>0) con t– e stampa del tempo.
  • Extra: beep finale + messaggio “Decollo!”.

Dirimere i conflitti con il pensiero computazionale – educazione civica – diagramma di flusso e pseudocodice – lezione 02

Dal problema definito passiamo alla modellazione del processo: un diagramma di flusso rende visibile il percorso di mediazione (controllo sicurezza > turni > parafrasi > opzioni > decisione/mediatore). Poi tradurremo nella prossima lezione lo pseudocodice scritto in un linguaggio comprensibile (con nomi di variabili e commenti in italiano), in uno sketch Arduino.

Contenuto dell’attività

Obiettivi

  • Costruire un diagramma di flusso corretto (start/end, bivi, ciclo).
  • Scrivere pseudocodice coerente e leggibile.

Durata: 60–75 minuti
Materiali: fogli A3, pennarelli, template di blocchi; in alternativa editor con Mermaid.

Diagramma di flusso (Mermaid)

graph TD
    A([Start]) --> B{E' sicuro parlare}
    B -- No --> C[Time-out 2 minuti e chiama adulto]
    C --> B
    B -- Si --> D[Definisci il problema in una frase]
    D --> E[Turni di parola: A 60s, B 60s]
    E --> F{Parafrasi reciproca corretta}
    F -- No --> E
    F -- Si --> G[Genera almeno 2 opzioni di soluzione]
    G --> H{Accordo su una opzione}
    H -- Si --> I[Piano di azione: chi fa cosa entro quando]
    I --> J[Impegno reciproco]
    J --> K[Verifica dopo 24 ore]
    K --> L([End])
    H -- No --> M[Chiedi mediatore o rinvia confronto]
    M --> B

Diagramma di flusso

Pseudocodice

INIZIO
  mostra "Benvenuto: risoluzione conflitto (Base)"
  RIPETI
    chiedi "E' sicuro parlare? (y/n)"
    se risposta = 'n' allora
       mostra "Time-out breve"
       attendi breve tempo
    altrimenti esci dal ciclo
  FINO A quando è sicuro parlare

  mostra "Definisci il problema in UNA frase"
  attendi conferma

  RIPETI
     mostra "Turno A (60s simulati) → invio"
     attendi conferma
     mostra "Turno B (60s simulati) → invio"
     attendi conferma
     chiedi "Parafrasi reciproca corretta? (y/n)"
  FINO A quando risposta = 'y'

  numeroOpzioni = 0
  RIPETI
     chiedi "Aggiungi opzione? (a = aggiungi, f = fine)"
     se 'a' allora numeroOpzioni = numeroOpzioni + 1
  FINO A quando comando = 'f' e numeroOpzioni >= 2

  chiedi "C'e' accordo su una opzione? (y/n)"
  se 'y' allora
      mostra "Piano d'azione e verifica a 24h"
      FINE
  altrimenti
      mostra "Mediatore o rinvio"
      vai a controllo sicurezza
FINE

Nella prossima lezione si passerà dallo pseudocodice allo sketch Arduino.

Buon Coding a tutti, ma soprattutto che la pace sia con voi 🙂

Quick References per lo studio – Preparare un’esposizione orale

Una buona esposizione orale nasce prima di parlare: dalla struttura chiara, da esempi concreti, da transizioni semplici e da un tempo rispettato. L’obiettivo non è “dire tutto”, ma guidare l’ascoltatore: dichiarare dove stai andando, mostrare perché fidarsi (dati, definizioni, ragionamenti) e chiudere con ciò che vuoi che resti.

Per questo conviene usare una struttura guida: apertura breve che aggancia e definisce il perché (tesi/obiettivo), tre idee chiave sviluppate con esempi/definizioni/prove, una chiusura che sintetizza e collega a un’azione o domanda finale. Se c’è tempo per le domande, preparane alcune probabili e risposte essenziali.

Prima di esporre:

  • Scrivi un outline (schema) e non un copione; usa cue card (scheda promemoria) con parole-chiave.
  • Prova con un timer (2–3 volte), segna dove inciampi e accorcia.
  • Prepara definizioni precise, un esempio numerico (se serve), una figura/schema semplice.
  • Organizzi transizioni (“Ora passiamo a…”, “Questo ci porta a…”).

Durante:

  • Parla chiaro e piano; frasi brevi; verbi attivi.
  • Guarda l’aula o i docenti (dipende dal contesto), pausa dopo concetti importanti.
  • Se usi slide, ricordati: 1 idea per slide, titoli informativi, caratteri leggibili.

Errori tipici da evitare:

  • Riassumere il libro senza una tesi o un perché.
  • Correre sul tempo o superarlo (allenati con timer).
  • Esempi vaghi, definizioni imprecise, transizioni assenti.
  • Leggere tutto a voce o riempire le slide di testo.

Scarica PDF A4 della guida operativaApri il sorgente Markdown su GitHub

Se non sai cos’è il Markdown segui il link

---
title: "Esposizione orale – "
autore: ""
durata_target: "<3–5 min / 7–10 min>"
contesto: ""
versione: "1.0"
ultimo_aggiornamento: ""
---

## 0) Obiettivo & messaggio centrale
- Obiettivo: 
- Messaggio centrale (tesi): 

## 1) Apertura (30–45″)
- Gancio iniziale (domanda/curiosità/dato breve):
- Contesto in 1–2 frasi:
- Tesi/Obiettivo dichiarati:

## 2) Idea chiave #1 (≈ 1–2 min)
- Sottotitolo informativo:
- Definizione/dato essenziale:
- Esempio (concreto, breve; numerico se utile):
- Transizione verso l’idea #2:

## 3) Idea chiave #2 (≈ 1–2 min)
- Sottotitolo informativo:
- Evidenza (esperimento/argomento/immagine):
- Esempio / controesempio:
- Transizione verso l’idea #3:

## 4) Idea chiave #3 (≈ 1–2 min)
- Sottotitolo informativo:
- Collegamento con #1/#2 (perché ha senso insieme):
- Applicazione pratica / implicazione:
- Transizione verso chiusura:

## 5) Chiusura (15–30″)
- Riepilogo in 1 frase (torna alla tesi):
- Messaggio finale / domanda guida:
- (se richiesto) Call to action / cosa fare dopo:

## 6) Q&A — domande probabili (prepara risposte brevi)
- D1:
- D2:
- D3:

## 7) Supporti (facoltativi)
- Slide/immagine/schema n. 1: 
- Oggetto/esperimento: 
- Link/QR a risorse: 

## 8) Prova con timer (log)
- Prova #1:  — note:
- Prova #2:  — tagli/aggiunte:
- Prova #3:  — ok per esposizione

## 9) Checklist rapida
- [ ] Messaggio centrale chiaro
- [ ] 3 idee chiave ben separate
- [ ] Esempi concreti e comprensibili
- [ ] Transizioni pronte
- [ ] Tempo rispettato
- [ ] Linguaggio semplice e preciso

Esempio 01: “Diagrammi di flusso nella vita reale: decidere come andare a scuola” (3–5 minuti)

NOTA: i tempi indicati sono solo di esempio.

Obiettivo & messaggio centrale

  • Obiettivo: far capire come i diagrammi di flusso aiutano a prendere decisioni chiare e a prevedere i casi.
  • Tesi: “Un buon diagramma di flusso rende visibile la decisione e riduce gli errori nei casi particolari.”

Apertura (30–45″)

  • Gancio: “Quante volte arrivate in ritardo perché non sapevate se prendere bici o bus?”
  • Contesto: decisione quotidiana con variabili (tempo, meteo, orari).
  • Tesi: “Il diagramma di flusso traduce il problema in domande sì/no e azioni.”

Idea 01 – Simboli base e logica sì/no

  • Definizioni: Start/Stop (ellissi), Azione (rettangolo), Decisione (rombo), Connettori.
  • Esempio: blocco “Leggi orario e tempo residuo” -> decisione “Tempo ≥ 25′?”.
  • Transizione: “Capito il linguaggio, lo applichiamo al nostro problema.”

Idea 02 – Esempio concreto

  • Input: orario attuale, tempo residuo, meteo (piove sì/no), bici disponibile, orario bus.
    Flusso:

    • Se tempo < 25′ > controlla bus in arrivo ≤ 10′. Se sì -> BUS. Se no -> chiama passaggio/avvisa.
    • Se tempo ≥ 25′ -> se piove -> vai a BUS; se non piove -> se bici ok -> BICI, altrimenti A PIEDI.
  • Nota visiva: mostrare una mini-mappa o uno schema (anche disegnato) con 2–3 rombi e azioni.
  • Transizione: “Funziona, ma che succede nei casi speciali?”

Idea 03 – Gestione eccezioni e miglioramenti

  • Eccezione: bus pieno > ramo alternativo (seconda scelta).
  • Miglioramento: soglie personalizzabili (25′ > 20′ se cammini veloce).
  • Collegamento: stesso metodo per “scegliere metodo di studio” (Cornell/Pomodoro).

Chiusura (15–30″)

  • Riepilogo: “Dal problema all’azione, senza buchi logici.”
  • Messaggio finale: “Disegnare il flusso prima di agire fa risparmiare tempo e riduce le decisioni impulsive.”

Q&A previste

  • “Se ho due bus alternativi?” -> Aggiungi un rombo “Bus A entro x min?” -> se no, “Bus B entro y min?”.
  • “E se non ho i dati (orari)?” -> Prevedi un ramo “Recupera info” prima della decisione.

Timer (prove)

  • Prova 1: 6′20″ > taglia spiegazioni di simboli.
  • Prova 2: 4′55″ > ok.

Esempio 02 – “Legge di Ohm: capire la relazione tra V, I e R” (7–10 minuti)

Obiettivo & messaggio centrale

  • Obiettivo: mostrare come la legge di Ohm descrive il legame tra tensione, corrente e resistenza e come usarla per prevedere il comportamento di un circuito semplice.
  • Tesi: “V=R⋅I possiamo stimare e progettare rapidamente circuiti, riconoscendo anche quando il modello non basta.”

Apertura (30–45″)

  • Gancio: “Perché a volte un LED si brucia in un attimo?”
  • Contesto: corrente e resistenza di limitazione.
  • Tesi: “La legge di Ohm è la base per evitare errori e dimensionare componenti.”

Idea 01 – Definizioni e formula

  • Definizioni: tensione (V), corrente (I), resistenza (R) con unità SI.
  • Formula: V=R⋅I, grafico I-V lineare per resistori ideali.
  • Esempio numerico: con 5 V e R=220 Ω -> I=5/220≈0,023 A (23 mA).
  • Transizione: “Applichiamola ad un caso pratico con LED.”

Idea 02 – Caso pratico: LED + resistenza

  • Dati: LED rosso Vf ≈2,0 V; alimentazione 5 V; desidero I≈15 mA.
  • Calcolo resistenza: R=(5−2,0)/0,015≈200 Ω > uso 220 Ω (standard).
  • Mostra schema semplice; suggerisci una figura o foto del cablaggio.
  • Transizione: “La legge funziona, ma quando non basta?”

Idea 03 – Limiti e casi non ideali

  • Lampadine a incandescenza: resistenza varia con temperatura -> non lineari.
  • Cavi lunghi/contatti ossidati: resistenze parassite.
  • Misura reale con multimetro: piccole differenze ammesse.
  • Collegamento: serve anche a dimensionare partitori, sensori e a capire cadute di tensione.

Chiusura (15–30″)

  • Riepilogo: “Ohm = relazione semplice che evita errori grossolani.”
  • Messaggio finale: “Fai sempre il conto prima di collegare: risparmi tempo e componenti.”

Q&A previste

  • “Perché il LED brilla meno con 330 Ω?” -> Corrente più bassa: I=(5−2)/330≈9 mA.
  • “Perché una lampadina non segue I-V lineare?” -> Resistenza dipende dalla temperatura del filamento.

Timer (prove)

  • Prova 1: 10′30″ > ridurre spiegazione casi non ideali.
  • Prova 2: 8′50″ > ok per interrogazione lunga.

Buona interrogazione 🙂