Preparare gli strumenti
Prima della lezione 1: orientati fra scheda e strumenti.
Apri su YouTube ↗ATLANTE / IMPARA FACENDO
Una guida pratica da zero alle competenze avanzate di programmazione: leggi, monta, modifica il codice e verifica il risultato.

Non serve sapere programmare. Inizia dalle lezioni Base e passa oltre soltanto quando sai spiegare e ripetere la prova. Le sezioni Professionale insegnano metodo, test e documentazione: completarle non conferisce una qualifica professionale.
Occorrente iniziale: UNO R3, cavo USB dati, PC con Arduino IDE 2, breadboard, cavetti, LED rosso, resistenza 330 Ω, pulsante e potenziometro 10 kΩ. Le lezioni I²C e interrupt richiedono hardware aggiuntivo scelto e verificato separatamente.
Su Android puoi leggere la guida e usare il simulatore Atlante; questa guida non aggiunge compilazione o caricamento USB dal telefono. Il simulatore non esegue automaticamente tutti gli sketch del corso.
Progressi conservati solo su questo dispositivo.

Risorse del canale Arduino, in inglese. Controlla sul player la disponibilità di sottotitoli. Il video viene caricato da YouTube solo quando premi Riproduci; se non parte, usa il collegamento esterno. Riproduzione non verificata in questa sessione.
Prima della lezione 1: orientati fra scheda e strumenti.
Apri su YouTube ↗Prima delle lezioni 2–3: osserva LED e pulsante.
Apri su YouTube ↗01 / Base
Caricare un programma e riconoscere le sue due parti.
Uno sketch è il programma di Arduino. setup() viene eseguito una volta dopo accensione o reset; loop() viene richiamato continuamente. Le parentesi graffe delimitano un blocco, il punto e virgola chiude molte istruzioni. Il testo dopo // è un commento. Per cominciare usa soltanto il LED già sulla scheda: non serve costruire un circuito.
UNO R3 collegata al PC via USB; nessun filo esterno.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // LED L: uscita
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(400); // millisecondi acceso
digitalWrite(LED_BUILTIN, LOW);
delay(800); // millisecondi spento
}
pinMode sceglie il ruolo del pin. digitalWrite imposta HIGH o LOW. delay ferma il normale avanzamento del programma: per questo primo esempio va bene; più avanti lo elimineremo.
Cambia 400 in 100 e 800 in 900. Prima prevedi il risultato, poi carica.
Il LED resta acceso circa 0,1 s e spento circa 0,9 s. Sai distinguere Verifica (compilazione) da Carica (scrittura sulla scheda).
Porta assente: controlla cavo dati e collegamento. Errore di compilazione: leggi il primo messaggio e la riga indicata. Upload fallito: verifica scheda e porta; non cambiare codice a caso.
02 / Base
Dare un nome ai pin e separare configurazione e comportamento.
Una costante descrive qualcosa che non deve cambiare durante il programma, come il numero di un pin. Una variabile conserva un valore che può cambiare. byte è utile per piccoli numeri non negativi; bool contiene true o false. Scegli nomi che spieghino il compito: ledSegnale è più chiaro di x. Una breadboard collega alcuni fori al suo interno: controlla i gruppi di contatti, non affidarti alla sola vicinanza.
D9 → resistenza 330 Ω → anodo LED rosso; catodo → GND. Un LED rosso con caduta indicativa 2 V assorbe circa (5−2)/330 = 9 mA. La caduta reale dipende dal componente.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
const byte ledSegnale = 9;
const unsigned long intervalloMs = 500;
bool acceso = false;
void setup() { pinMode(ledSegnale, OUTPUT); }
void loop() {
acceso = !acceso; // inverte true e false
digitalWrite(ledSegnale, acceso ? HIGH : LOW);
delay(intervalloMs);
}
const protegge il nome da assegnazioni successive. ! inverte un valore logico. L’espressione condizione ? valore1 : valore2 sceglie il valore da scrivere.
Rinomina ledSegnale in luceBanco in ogni punto. Imposta 250 ms.
La compilazione riesce; il periodo completo è 500 ms, non 250 ms.
LED spento: controlla polarità, resistenza e GND. Non collegare il LED direttamente fra un pin e GND. Due terminali nella stessa fila collegata possono cortocircuitare il componente.
03 / Base
Leggere un ingresso e comandare un’uscita con if.
Con INPUT_PULLUP il pin ha uno stato definito quando il pulsante è aperto. Premendo, il collegamento a GND porta la lettura a LOW. La variabile premuto traduce questo livello elettrico in un significato: true vuol dire premuto. In C++, = assegna un valore; == confronta due valori. if esegue un blocco quando la condizione è vera.
D2 → pulsante → GND; LED integrato. Nessuna resistenza esterna di pull-up in questo esempio.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
const byte pulsante = 2;
void setup() {
pinMode(pulsante, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
bool premuto = (digitalRead(pulsante) == LOW);
if (premuto) digitalWrite(LED_BUILTIN, HIGH);
else digitalWrite(LED_BUILTIN, LOW);
}
Il confronto == LOW produce un bool. Il programma legge e aggiorna continuamente: non conserva l’accensione dopo il rilascio.
Inverti il comportamento: LED acceso soltanto con pulsante rilasciato.
Premuto: LED spento; rilasciato: LED acceso. Sai spiegare perché LOW può significare true.
Ingresso casuale: controlla INPUT_PULLUP e massa. Il rimbalzo meccanico diventa importante quando conti pressioni o cambi stato: verrà gestito nella lezione 8.
04 / Base
Osservare misure nel monitor seriale e distinguere numero e unità.
analogRead su UNO R3 restituisce un conteggio a 10 bit, da 0 a 1023. Non è automaticamente una temperatura o una tensione precisa. Per trasformarlo in una grandezza servono riferimento, scala e caratteristiche del sensore. Inizia con un potenziometro da 10 kΩ: il cursore fornisce una tensione regolabile. Serial invia informazioni al PC; monitor e programma devono usare la stessa velocità.
Potenziometro 10 kΩ: estremi a 5 V/GND, cursore ad A0. Valori riferiti a UNO R3; non trasferire 5 V a una scheda a 3,3 V.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
void setup() { Serial.begin(115200); }
void loop() {
int conteggio = analogRead(A0);
Serial.print("ADC=");
Serial.println(conteggio);
delay(100);
}
int contiene il conteggio. print continua sulla stessa riga; println aggiunge un fine riga. Il ritardo rende leggibile l’uscita seriale.
Aggiungi una variabile bool sopraSoglia = conteggio >= 600 e stampala dopo il conteggio.
Intorno a metà corsa il valore è vicino a 512, con tolleranze. Non chiamare la lettura “gradi” senza una conversione verificata.
Valori che saltano: controlla cursore e GND. Testo incomprensibile: controlla i baud. Non superare i limiti elettrici dell’ingresso.
05 / Intermedio
Trasformare una lettura in un comando di uscita.
PWM alterna velocemente acceso e spento. Cambia il rapporto fra tempo acceso e periodo, detto duty cycle. Su UNO R3 analogWrite usa normalmente valori da 0 a 255 sui pin PWM: non è un’uscita analogica continua. Qui usiamo D9 e convertiamo il conteggio 0–1023 in 0–255. Non alimentare motori o carichi di potenza direttamente da un pin.
Potenziometro su A0; D9 → 330 Ω → LED rosso → GND.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
const byte ledPwm = 9;
void setup() { pinMode(ledPwm, OUTPUT); }
void loop() {
int lettura = analogRead(A0);
int comando = lettura / 4; // 0..1023 diventa 0..255
analogWrite(ledPwm, comando);
}
La divisione intera scarta la parte frazionaria. analogWrite mantiene il PWM mentre loop continua. D9 è una scelta specifica per UNO R3.
Limita il comando massimo a 128. Confronta il risultato con 255.
Zero spegne; 255 imposta il massimo. Sai distinguere conteggio ADC, comando PWM e tensione misurata.
Un pin non PWM non offre la stessa regolazione. Se aggiungi librerie che usano timer, verifica eventuali conflitti con PWM.
06 / Intermedio
Ridurre le ripetizioni senza perdere chiarezza.
Una funzione raccoglie un compito. Un parametro è un valore che le passi; return restituisce il risultato. Un array conserva più elementi dello stesso tipo. Gli indici partono da zero: per tre elementi sono 0, 1 e 2. Un ciclo for è comodo per elaborare una piccola quantità di dati; non deve però bloccare per molto tempo il resto del programma.
Nessun componente esterno: esempio di organizzazione C++.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
int media(const int valori[], byte quanti) {
if (quanti == 0) return 0;
long somma = 0;
for (byte i = 0; i < quanti; i++) somma += valori[i];
return somma / quanti;
}
void setup() {
Serial.begin(115200);
const int campioni[] = {100, 200, 300};
Serial.println(media(campioni, 3));
}
void loop() {}
const impedisce alla funzione di modificare i valori ricevuti. long rende la somma più ampia di int su UNO R3. La dimensione passata deve corrispondere agli elementi disponibili.
Sostituisci i campioni con 0, 512 e 1023. Spiega l’arrotondamento.
Il primo risultato è 200; il secondo è 511 per divisione intera. Non accedi mai all’indice 3 di un array da tre elementi.
Dimensioni errate possono leggere memoria estranea senza un errore evidente. Non usare <= quanti nel ciclo.
07 / Intermedio
Eliminare le attese bloccanti dal ciclo principale.
Non serve un secondo processore per alternare attività brevi. loop legge un pulsante continuamente e controlla se è passato abbastanza tempo per cambiare il LED. millis fornisce un contatore di millisecondi. Su UNO R3 si riavvolge dopo circa 49,7 giorni: il confronto mediante sottrazione unsigned gestisce il passaggio, purché il controllo sia eseguito regolarmente e l’intervallo sia appropriato.
D2 → pulsante → GND; LED integrato.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
const byte pulsante = 2;
unsigned long ultimo = 0;
bool acceso = false;
void setup() {
pinMode(pulsante, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
unsigned long ora = millis();
unsigned long periodo = digitalRead(pulsante) == LOW ? 120UL : 700UL;
if (ora - ultimo >= periodo) {
ultimo = ora;
acceso = !acceso;
digitalWrite(LED_BUILTIN, acceso ? HIGH : LOW);
}
}
ultimo conserva quando è avvenuto l’ultimo cambio. UL indica una costante unsigned long. Ogni passaggio di loop resta breve; questo non è parallelismo hardware.
Prevedi quanto impiega il LED a reagire al cambio di periodo. Aggiungi una stampa ogni secondo con un secondo timestamp.
Il pulsante influenza il ritmo senza attendere un delay. Sai spiegare perché ora >= ultimo + periodo è meno robusto al riavvolgimento.
Non usare int per millis. Una stampa seriale eccessiva o una libreria bloccante possono comunque rallentare loop.
08 / Intermedio
Cambiare stato una sola volta per pressione.
Un pulsante reale può aprire e chiudere il contatto più volte in pochi millisecondi. Il programma mantiene una lettura grezza e uno stato stabile: accetta la nuova lettura solo dopo 30 ms senza variazioni. Il cambio del LED avviene sul fronte che porta lo stato stabile a premuto, non mentre il pulsante rimane tenuto.
D2 → pulsante → GND con INPUT_PULLUP.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
const byte pulsante = 2;
bool grezzo = HIGH, stabile = HIGH, acceso = false;
unsigned long cambiato = 0;
void setup() {
pinMode(pulsante, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
unsigned long ora = millis();
bool lettura = digitalRead(pulsante);
if (lettura != grezzo) { grezzo = lettura; cambiato = ora; }
if (ora - cambiato >= 30 && stabile != grezzo) {
stabile = grezzo;
if (stabile == LOW) acceso = !acceso;
}
digitalWrite(LED_BUILTIN, acceso ? HIGH : LOW);
}
!= significa diverso. cambiato viene aggiornato a ogni variazione grezza, facendo ripartire il tempo di stabilizzazione.
Confronta 5, 30 e 100 ms. Registra conteggi errati e ritardo percepito; non assumere che lo stesso valore vada bene per ogni interruttore.
Una pressione mantenuta genera un evento. Una sequenza di rimbalzi più breve di 30 ms non viene accettata come pressioni multiple.
Contare ogni LOW dentro loop produce migliaia di eventi. L’antirimbalzo software non risolve cablaggi errati o disturbi elettrici fuori specifica.
09 / Intermedio
Evitare che un’uscita oscilli vicino a una soglia.
Un filtro riduce le variazioni rapide ma introduce ritardo. L’isteresi usa due soglie: si accende sopra 650 e si spegne sotto 550; nella fascia intermedia conserva lo stato. Sono compiti diversi. La calibrazione richiede un riferimento noto e più punti: un valore ADC non diventa una misura affidabile soltanto perché è stato mediato.
Potenziometro 10 kΩ su A0; LED integrato.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
float filtrato = 0;
bool acceso = false;
unsigned long ultimo = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
filtrato = analogRead(A0);
}
void loop() {
unsigned long ora = millis();
if (ora - ultimo < 100) return;
ultimo = ora;
int grezzo = analogRead(A0);
filtrato += 0.2f * (grezzo - filtrato);
if (filtrato >= 650) acceso = true;
else if (filtrato <= 550) acceso = false;
digitalWrite(LED_BUILTIN, acceso ? HIGH : LOW);
Serial.print(grezzo); Serial.print(',');
Serial.print(filtrato); Serial.print(','); Serial.println(acceso);
}
Il nuovo valore si avvicina del 20% alla lettura a ogni campione. return interrompe questa chiamata di loop, non ferma Arduino.
Confronta coefficiente 0,2 e 0,5 con lo stesso gradino del potenziometro. Registra il tempo prima del cambio di stato.
Fra 550 e 650 lo stato dipende dalla storia precedente. Il filtro non elimina la necessità di verificare unità e sensore.
Soglie uguali annullano l’isteresi. Una misura piatta può indicare un collegamento interrotto: non considerarla automaticamente valida.
10 / Avanzato
Definire un piccolo protocollo controllabile e non bloccante.
Un protocollo chiarisce i comandi accettati e le risposte. Questo esempio accetta un carattere alla volta: 1 accende, 0 spegne, ? legge lo stato. Non serve attendere un’intera frase o accumulare testo senza limite. I terminatori di riga vengono ignorati. Ogni altro carattere produce un errore esplicito; l’uscita mantiene il suo stato.
Solo USB e LED integrato; UART via convertitore USB della UNO R3.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
bool acceso = false;
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (Serial.available() <= 0) return;
char comando = Serial.read();
if (comando == '\r' || comando == '\n') return;
if (comando == '1') acceso = true;
else if (comando == '0') acceso = false;
else if (comando != '?') { Serial.println("ERR comando"); return; }
digitalWrite(LED_BUILTIN, acceso ? HIGH : LOW);
Serial.println(acceso ? "ON" : "OFF");
}
Le virgolette singole indicano un carattere; quelle doppie una stringa. available controlla i dati già presenti: loop non aspetta una risposta.
Scrivi una tabella richiesta/risposta. Prova righe vuote, sequenze 10? e caratteri non previsti.
1? risponde ON due volte; X risponde ERR comando e non cambia lo stato. Il formato è documentato prima di collegare un altro programma.
Inviare parole intere a questo protocollo genera più comandi o errori: non è un parser di frasi. Per messaggi lunghi usa buffer limitati, scadenze e validazione.
11 / Avanzato
Separare collegamento elettrico, indirizzo e interpretazione dei dati.
I²C usa SDA e SCL con indirizzi. Su UNO R3 SDA corrisponde ad A4 e SCL ad A5. Uno scanner può rilevare una risposta ma non identifica con certezza modello o significato dei registri. Per un sensore serve la libreria corretta per la variante e un esempio del produttore. Pull-up e livelli devono essere compatibili: un chip a 3,3 V non è automaticamente compatibile con il bus a 5 V.
UNO R3: A4/SDA e A5/SCL; GND comune. Alimentazione e adattamento dei livelli dipendono dal breakout scelto.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Wire.setWireTimeout(25000, true); // core AVR con timeout Wire
byte trovati = 0;
for (byte indirizzo = 8; indirizzo < 120; indirizzo++) {
Wire.beginTransmission(indirizzo);
byte esito = Wire.endTransmission();
if (esito == 0) {
Serial.print("Risposta 0x"); Serial.println(indirizzo, HEX);
trovati++;
}
if (Wire.getWireTimeoutFlag()) {
Serial.println("Timeout bus: controllare i collegamenti");
Wire.clearWireTimeoutFlag();
break;
}
}
Serial.print("Totale: "); Serial.println(trovati);
}
void loop() {}
La scansione avviene una volta in setup. endTransmission restituisce un codice: zero indica un ACK. Le API di timeout sono specifiche del core: controlla che la tua versione le supporti.
Annota indirizzo, codice esito, modello e versione libreria. Aggiungi una lettura solo dopo aver consultato l’esempio ufficiale del sensore.
Lo scanner senza dispositivi stampa Totale: 0. Un ACK non basta a dichiarare che temperatura o pressione siano corrette.
Due sensori con lo stesso indirizzo possono entrare in conflitto. Un bus bloccato o senza pull-up richiede verifica del cablaggio; ripetere all’infinito non è recupero degli errori.
12 / Avanzato
Contare eventi brevi mantenendo la routine di interrupt minima.
Un interrupt richiama una funzione quando accade un evento. Su UNO R3 D2 e D3 supportano gli interrupt esterni tramite digitalPinToInterrupt. La routine deve durare poco: aggiorna un contatore e torna. volatile indica che il valore può cambiare fuori dal flusso normale, ma non rende atomica una lettura a più byte su un processore a 8 bit.
D2 ingresso impulsi; GND comune. Nessun carico controllato.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
volatile unsigned long impulsi = 0;
unsigned long ultimo = 0;
void contaImpulso() { impulsi++; }
void setup() {
Serial.begin(115200);
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), contaImpulso, FALLING);
}
void loop() {
unsigned long ora = millis();
if (ora - ultimo < 1000) return;
ultimo = ora;
noInterrupts();
unsigned long copia = impulsi;
interrupts();
Serial.println(copia);
}
La sezione critica copia il contatore in poche istruzioni. La stampa avviene dopo aver riabilitato gli interrupt. Questo schema si usa qui nel normale loop, con interrupt inizialmente abilitati.
Fornisci dieci impulsi puliti e verifica l’incremento. Documenta la frequenza provata, senza estendere il risultato a frequenze mai misurate.
La routine non contiene delay o Serial. Sai spiegare la differenza fra volatile e accesso atomico.
Un contatto meccanico non filtrato non genera un solo impulso per pressione. Disabilitare gli interrupt troppo a lungo può perdere eventi e interferire con altre funzioni.
13 / Avanzato
Integrare ingresso, soglie, stato iniziale e ripristino manuale.
Una macchina a stati assegna significato alle situazioni. Questo monitor didattico parte disarmato. Il pulsante deve essere rilasciato, poi premuto stabilmente per armare. Una lettura almeno 700 porta in allarme; l’allarme resta memorizzato. Una pressione, con lettura non superiore a 600, riconosce l’allarme e torna disarmato. Il LED lampeggia quando armato e resta acceso in allarme. Non è un sistema di protezione.
Potenziometro 10 kΩ: 5 V/GND e cursore A0. Pulsante D2–GND. Uscita LED integrato.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
enum Stato { DISARMATO, ARMATO, ALLARME };
Stato stato = DISARMATO;
bool grezzo = HIGH, stabile = HIGH, rilascioVisto = false;
unsigned long cambiato = 0;
void setup() {
pinMode(2, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
unsigned long ora = millis();
bool letturaPulsante = digitalRead(2);
bool pressione = false;
if (letturaPulsante != grezzo) { grezzo = letturaPulsante; cambiato = ora; }
if (ora - cambiato >= 30) {
if (grezzo == HIGH) rilascioVisto = true;
if (stabile != grezzo) {
stabile = grezzo;
pressione = (stabile == LOW && rilascioVisto);
}
}
int misura = analogRead(A0);
switch (stato) {
case DISARMATO: if (pressione) stato = ARMATO; break;
case ARMATO: if (misura >= 700) stato = ALLARME; break;
case ALLARME: if (pressione && misura <= 600) stato = DISARMATO; break;
}
bool led = stato == ALLARME || (stato == ARMATO && (ora / 300) % 2 == 0);
digitalWrite(LED_BUILTIN, led ? HIGH : LOW);
}
enum assegna nomi agli stati. switch rende esplicite le transizioni consentite. Nessun comando deve avere effetti non descritti dalla tabella di stato.
Disegna la tabella stato/evento/stato successivo. Verifica 699, 700, 601 e 600 conteggi. Registra il comportamento anche dopo reset.
La lettura bassa da sola non cancella l’allarme. Il pulsante mantenuto al riavvio non arma; dopo rilascio e nuova pressione può armare.
Il progetto non rileva affidabilmente il distacco di un sensore analogico: una futura funzione diagnostica richiede hardware e criteri specifici. Non usare per comandare impianti o protezioni.
14 / Professionale
Dimostrare cosa funziona e conoscere i limiti della verifica.
Prima definisci i requisiti osservabili, poi separa la logica pura dall’hardware. La funzione decide non legge pin: riceve dati e restituisce una scelta. È più facile provarla con valori di confine. Un test che stampa OK non prova alimentazione, cablaggio o comportamento temporale. Su UNO R3 la memoria è limitata: controlla il rapporto di compilazione e evita allocazioni dinamiche ripetute in applicazioni lunghe.
Solo scheda USB; test della logica, non del sensore.
#include <Arduino.h>
// Atlante: esempio originale per UNO R3.
// Verificare core, cablaggio e hardware prima dell’uso.
bool decide(bool precedente, int valore) {
if (valore >= 650) return true;
if (valore <= 550) return false;
return precedente;
}
void setup() {
Serial.begin(115200);
bool ok = !decide(false, 550) && decide(false, 650)
&& decide(true, 600) && !decide(false, 600);
Serial.println(ok ? "OK" : "KO");
}
void loop() {}
I quattro casi verificano soglia inferiore, superiore e memoria nella fascia intermedia. Il test di mutazione volontaria controlla che la prova sia capace di trovare un errore.
Aggiungi casi 0, 549, 551, 649, 651 e 1023. Esporta tabella con ingresso, stato precedente, atteso e osservato.
Il difetto introdotto deve far fallire almeno una prova. Sai distinguere test logici, compilazione per la scheda e test hardware.
Non chiamare “validato” un progetto perché compila. La memoria libera stimata non dimostra assenza di errori nello stack o negli accessi agli array.
15 / Professionale
Portare un progetto su un altro dispositivo senza ipotesi nascoste.
UART, I²C e SPI risolvono esigenze diverse. UART scambia flussi di byte; I²C indirizza periferiche su due segnali; SPI usa clock, dati e selezione del dispositivo. Il protocollo non garantisce compatibilità di tensione. Una libreria nasconde registri e sequenze, ma va scelta per chip e scheda esatti. Il porting da UNO R3 a ESP32 o UNO R4 richiede verifiche: numerazione pin, tensioni, ADC, PWM, timer, dimensioni dei tipi e API possono cambiare.
Cablaggio solo dal datasheet della variante scelta. Nessun esempio universale di collegamento valido per tutti i moduli.
Per un driver robusto definisci almeno begin, acquisisci e statoErrore. Non riavviare indefinitamente senza una scadenza e un messaggio diagnostico.
Prepara una matrice: scheda, core, libreria, pin, alimentazione, esito compilazione, esito hardware. Lascia “non provato” dove manca una misura.
Un’altra persona riesce a riprodurre la configurazione senza indovinare il modello del sensore. I moduli non provati restano dichiarati tali.
Non scambiare pin con etichetta simile per equivalenti. Wi-Fi e aggiornamenti remoti richiedono gestione credenziali, autenticazione, errori di rete e aggiornamenti verificabili.
16 / Professionale
Trasformare il prototipo in una consegna verificabile.
Un progetto professionale comprende requisiti, codice, schema elettrico, distinta materiali, versioni, piano di prova e limiti. Il fatto che un prototipo funzioni una volta non ne dimostra affidabilità. Definisci comportamento all’avvio, perdita alimentazione, ingresso fuori intervallo, comunicazione assente e ripristino. La breadboard è utile per imparare ma non equivale a un assemblaggio qualificato per esercizio continuo.
Il percorso usa solo USB e circuiti didattici a bassa tensione. Motori, relè e potenza richiedono driver e verifiche specifiche.
La competenza professionale si dimostra con progetti e prove. La percentuale del corso indica soltanto le tappe che hai segnato come completate; non è una certificazione.
Consegna a un’altra persona il progetto completo. Chiedile di riprodurre configurazione, caricamento e prove senza spiegazioni aggiuntive; annota ciò che manca.
Consegna minima: requisiti, codice versionato, schema, distinta, istruzioni di compilazione, tabella prove, risultati, limiti e procedura di ripristino. Nessun campo critico lasciato implicito.
Una libreria aggiornata può cambiare il comportamento: ripeti i test coinvolti. Non pubblicare chiavi, password o dati personali nel repository.
Conserva obiettivi, versioni, misure e risultati. Il quaderno di Atlante ti aiuta a preparare una relazione riproducibile.
Apri il quaderno progetti →Verifica del materiale: 15 ottobre 2026. Sketch controllati con compilatore C++ host e API Arduino simulate; non compilati per AVR e non provati su una scheda fisica. Le prove richieste nelle lezioni restano da eseguire dall’allievo. I contenuti non sostituiscono datasheet e istruzioni della variante hardware scelta.