
In riferimento alla lezione: “Arduino – while: ripetere finché la condizione è vera (controllo in ingresso)“, pubblico una possibile soluzione agli esercizi proposti.
Ho utilizzato come finecorsa un pulsante.
Soluzione 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”.
/*
Prof. Maffucci Michele
data: 03.11.25
Esercizio 1 — Validazione input (1..10) con while
- Chiede un intero all'utente
- Finché il valore NON è nel range [1..10], lo richiede
*/
void setup() {
Serial.begin(9600);
Serial.setTimeout(5000); // tempo max attesa lettura riga
Serial.println("Inserisci un numero intero tra 1 e 10:");
}
void loop() {
bool valido = false;
int numero = 0;
// Continua finché non ottieni un valore valido
while (!valido) {
if (Serial.available() > 0) {
// leggi una riga intera e converti
String riga = Serial.readStringUntil('\n');
// rimuove spazi/a-capo all’inizio e alla fine (es. '\r', '\n', ' ')
riga.trim();
if (riga.length() > 0) { // verifica che l’utente abbia scritto qualcosaa
numero = riga.toInt(); // converte in intero; '12abc' -> 12, 'abc'/'': 0
if (numero >= 1 && numero <= 10) {
valido = true; // uso del valore
} else {
Serial.println("Valore non valido. Reinserisci (1..10):");
}
}
}
}
Serial.print("Valore accettato: ");
Serial.println(numero);
while (true) {} // fine dimostrazione
}

Soluzione 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.
Ripasso:
Cos’é il MCD (Massimo Comun Divisore)
Il MCD tra due interi positivi a e b è il più grande intero che divide entrambi senza resto.
Esempi:
- MCD(8, 12) = 4
- MCD(18, 24) = 6
Algoritmo di Eulide
Ripetere finché b != 0;
- calcola resto r = a mod b
- sposta i valori: a <- b, b <- r
Quando b = 0, il MCD è a
/*
Prof. Maffucci Michele
data: 03.11.25
Esercizio 2 — MCD con algoritmo di Euclide usando while
- Legge due interi positivi a e b
- Esegue: mentre (b != 0) { resto = a % b; a = b; b = resto; }
- Stampa il MCD = a
*/
void setup() {
Serial.begin(9600);
Serial.setTimeout(20000);
Serial.println("Calcolo MCD (Euclide). Inserisci due interi positivi separati da invio:");
Serial.println("Valore a:");
}
void loop() {
long a = 0, b = 0;
// Leggi 'a'
while (a <= 0) { if (Serial.available() > 0) {
// Legge dal Serial Monitor il secondo intero (a).
// Attende l’arrivo di cifre, ignora spazi/CR/LF iniziali,
// Se non trova numeri, restituisce 0 (entro il Timeout).
a = Serial.parseInt();
while (Serial.available() > 0)
Serial.read(); // pulizia CR/LF
if (a <= 0) Serial.println("Valore non valido. Reinserisci a (>0):");
}
}
Serial.println("Valore b:");
// Leggi 'b'
while (b <= 0) { if (Serial.available() > 0) {
// Legge dal Serial Monitor il secondo intero (b).
// Attende l’arrivo di cifre, ignora spazi/CR/LF iniziali,
// Se non trova numeri, restituisce 0 (entro il Timeout).
b = Serial.parseInt();
while (Serial.available() > 0)
Serial.read();
if (b <= 0) Serial.println("Valore non valido. Reinserisci b (>0):");
}
}
// Algoritmo di Euclide con while
long resto = 0;
while (b != 0) {
resto = a % b; // resto della divisione
a = b; // shift dei valori
b = resto;
}
Serial.print("MCD = ");
Serial.println(a); // quando b==0, a è il MCD
while (true) {} // fine dimostrazione
}

Soluzione 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.
/*
Prof. Maffucci Michele
data: 03.11.25
Esercizio 3 — Servo: scansione finché NON scatta il finecorsa
- Servo su D9
- Finecorsa su D2 (INPUT_PULLUP): NON premuto = HIGH, premuto = LOW
- All'avvio di Arduino il servo aumenta l'angolo
finché il finecorsa non diventa LOW (premuto)
- Sulla Serial Monitor viene mostrato l'angolo percorso
*/
#include <Servo.h>
const int PIN_SERVO = 9;
const int PIN_FINECORSA = 2; // collegato a GND, usare INPUT_PULLUP
Servo servoBraccio;
void setup() {
Serial.begin(9600);
pinMode(PIN_FINECORSA, INPUT_PULLUP);
servoBraccio.attach(PIN_SERVO);
// Porta il servo all'angolo di partenza (0°)
servoBraccio.write(0);
delay(500);
Serial.println("Inizio scansione servo: attendo finecorsa...");
}
void loop() {
int angolo = 0;
// Scansione: finché il finecorsa NON è premuto (HIGH), prosegui
while (digitalRead(PIN_FINECORSA) == HIGH && angolo <= 180) {
servoBraccio.write(angolo);
delay(15); // piccolo tempo per muovere il servo
angolo += 2; // passo di scansione
}
// Se siamo usciti perché premuto, stampiamo l'angolo
Serial.print("Finecorsa attivato a ~");
Serial.print(angolo);
Serial.println(" gradi (valore approssimativo).");
// Ferma la dimostrazione: lascia il servo dove si è fermato
while (true) {}
}
Variante all’esercizio 03
Aggiungo una variante all’esercizio 3 in cui alla pressione di un secondo pulsante, il servo torna a 0° e riparte la scansione.
- Pulsante finecorsa su D2 (INPUT_PULLUP): quando viene premuto (LOW) la scansione si ferma e si mostra l’angolo raggiunto.
- Pulsante reset su D3 (INPUT_PULLUP): se premuto in qualunque momento:
- il servo torna a 0°,
- la scansione riparte da capo.
/*
Prof. Maffucci Michele
data: 03.11.25
Variante — Servo: scansione fino al finecorsa con pulsante di reset
- Servo su D9
- Finecorsa su D2 (INPUT_PULLUP): NON premuto = HIGH, premuto = LOW
- Pulsante RESET su D3 (INPUT_PULLUP): premuto = LOW
- Comportamento:
* Aumenta l'angolo 0 -> 180 a passi di 2° finche' il finecorsa NON è premuto.
* In QUALSIASI momento, se si preme RESET: il servo torna a 0° e la scansione riparte.
* Se il finecorsa scatta: stampa l'angolo e attende RESET per ricominciare.
Note:
- Debounce semplice con piccoli delay.
- while(...) usato come "controllo in ingresso" su eventi esterni (finecorsa/reset).
*/
#include <Servo.h>
const int PIN_SERVO = 9;
const int PIN_FINECORSA = 2; // a GND, usare INPUT_PULLUP
const int PIN_RESET = 3; // a GND, usare INPUT_PULLUP
const int PASSO_GRADI = 2;
Servo servoBraccio;
void tornaAZeroERiparti() {
// Porta il servo a 0° e attende il rilascio del pulsante RESET
servoBraccio.write(0);
delay(200);
// attesa rilascio per evitare ri-trigger immediati
while (digitalRead(PIN_RESET) == LOW) { /* aspetta rilascio */
}
delay(30); // debounce
Serial.println("RESET: servo a 0° — riparte la scansione.");
}
void setup() {
Serial.begin(9600);
pinMode(PIN_FINECORSA, INPUT_PULLUP);
pinMode(PIN_RESET, INPUT_PULLUP);
servoBraccio.attach(PIN_SERVO);
servoBraccio.write(0);
delay(400);
Serial.println("Scansione servo: finecorsa su D2, RESET su D3.");
Serial.println("Premi RESET per tornare a 0° e ripartire; premi il finecorsa per fermare.");
}
void loop() {
// 01. Posizione iniziale
int angolo = 0;
servoBraccio.write(angolo);
delay(150);
// 02. Ciclo di scansione: continua FINCHE' il finecorsa NON è premuto
while (digitalRead(PIN_FINECORSA) == HIGH && angolo <= 180) {
// Se in qualunque momento premo RESET: torna a 0° e riparte da capo
if (digitalRead(PIN_RESET) == LOW) {
delay(30); // debounce
if (digitalRead(PIN_RESET) == LOW) { // ancora premuto? conferma
tornaAZeroERiparti(); // porta a zero e gestisci rilascio
angolo = 0; // riparte da 0°
continue; // salta al prossimo giro del while
}
}
// Avanza l'angolo e muove il servo
servoBraccio.write(angolo);
delay(15); // tempo per il movimento
angolo += PASSO_GRADI;
}
// 03. Se esco dal while perche' il finecorsa è premuto (LOW), stampo l'angolo
if (digitalRead(PIN_FINECORSA) == LOW) {
// attendo che il pulsante finecorsa venga rilasciato prima di procedere
delay(30); // debounce
Serial.print("Finecorsa attivato a ~");
Serial.print(angolo);
Serial.println(" gradi. Premi RESET per ricominciare.");
// Attendo RESET per ripartire
while (digitalRead(PIN_RESET) == HIGH) {
// attesa "passiva": qui potreste far lampeggiare un LED o mostrare stato
// (teniamo il servo dove si è fermato)
}
// debounce e rilascio
delay(30);
while (digitalRead(PIN_RESET) == LOW) {
/* aspetta rilascio */
}
delay(30);
// Riporta a zero e riparte automaticamente al prossimo loop()
servoBraccio.write(0);
delay(200);
Serial.println("Ripartenza da 0°...");
}
// Se si è arrivati oltre 180° senza finecorsa, chiedi RESET per ripartire
if (angolo > 180 && digitalRead(PIN_FINECORSA) == HIGH) {
Serial.println("Limite 180° raggiunto senza finecorsa. Premi RESET per ripartire.");
while (digitalRead(PIN_RESET) == HIGH) {
/* attesa */
}
delay(30);
while (digitalRead(PIN_RESET) == LOW) {
/* rilascio */
}
servoBraccio.write(0);
delay(200);
}
// Il loop ricomincia: nuova scansione partirà da 0°
}
Buon lavoro 🙂









