Video 4 - Arduino pulsante come interruttore
Da pulsante momentaneo a interruttore toggle: logica di stato, if-else, boolean, debounce e memoria dello stato LED.
2. Di cosa parla questo video
In questo tutorial ti guiderò nella realizzazione di un progetto con Arduino attraverso l'ambiente di lavoro di Tinkercad, facciamo funzionare un pulsante come interruttore per accendere e spegnere un LED con una singola pressione, introducendo logica di stato, memoria e istruzione if.
Nel Video 3 LED ON solo mentre tieni premuto. Ora pulsante toggle: premi una volta → LED resta ON, ripremi → LED OFF, come interruttore luce casa. Serve memoria dello stato: variabile bool statoLed = false;, bool ultimoStatoPulsante = LOW;. Logica edge detection: leggi pulsante, se passa da LOW a HIGH (fronte salita) → inverti statoLed statoLed = !statoLed;, poi digitalWrite(led, statoLed);. Problema debounce: pulsante rimbalza 20ms, serve delay(50) o millis(). Cablaggio: INPUT_PULLUP pin 2 → pulsante → GND (2 fili, logica LOW premuto). Codice con if per rilevare pressione singola, non pressione continua.
Questo è il video che separa chi copia codice da chi capisce la logica. Nel video al minuto 9 mostro l'errore che fa fallire tutti: usano if(digitalRead(pulsante)==HIGH) digitalWrite(led, HIGH) else LOW come Video 3, così LED resta ON solo mentre premi, non come interruttore. Per fare interruttore serve variabile statoLed che ricorda se LED era acceso. Al minuto 14 mostro debounce: senza delay 50ms, una singola pressione viene letta come 3-4 pressioni per rimbalzo meccanico, LED fa ON-OFF-ON velocissimo. Vi mostro Serial Monitor che stampa 1 pressione = 4 letture HIGH. E al minuto 18 mostro edge detection: se non controllate ultimoStatoPulsante, tenendo premuto LED continua a togglare all'infinito invece di una volta sola.
3. Obiettivi di apprendimento
- ✅ Differenza pulsante (momentaneo) / interruttore (toggle con memoria)
- ✅ Familiarizziamo con l'istruzione if nello sketch e boolean NOT !
- ✅ Creazione e simulazione del tuo quarto circuito Arduino con debounce
Alla fine saprai trasformare un pulsante momentaneo in interruttore toggle, usare variabili boolean per memoria stato, usare if con edge detection (LOW→HIGH), implementare debounce con delay o millis, usare operatore NOT ! per invertire stato, distinguere pressione singola da pressione continua, e creare interazione tipo interruttore luce domestico.
4. Perché interruttore - Da momentaneo a toggle
Pulsante Video 3 = momentaneo, Video 4 = interruttore:
| Pulsante momentaneo (Video 3) | Interruttore toggle (questo video) |
|---|---|
| LED ON solo mentre premi | Premi → LED resta ON, ripremi → OFF |
| No memoria, if diretto su digitalRead | Memoria bool statoLed che ricorda stato |
| digitalWrite(led, statoPulsante) | statoLed = !statoLed su fronte salita |
| Nessun debounce critico | Debounce 50ms obbligatorio per rimbalzo |
| Premi continuo = LED ON continuo | Edge detection: toggle solo su transizione LOW→HIGH |
| Base input | Base logica di stato, domotica, interruttore luce |
Se vi chiedono "Differenza pulsante e interruttore in Arduino?", rispondete: "Pulsante momentaneo Video 3: LED ON mentre premi, codice if(digitalRead==HIGH) HIGH else LOW, senza memoria. Interruttore Video 4: premi una volta LED resta ON, ripremi OFF, serve variabile bool statoLed per memoria, edge detection per rilevare fronte salita LOW→HIGH, debounce 50ms per rimbalzo meccanico, statoLed = !statoLed per toggle, digitalWrite(led, statoLed). Così trasformo momentaneo in toggle come luce casa". Risposta da programmatore embedded.
5. Concetti chiave - Stato, if, boolean, debounce, edge detection
Cuore del video, minuto 6-16:
6. Lab in Tinkercad - Circuito toggle
Nel video (minuto 3-21):
- Setup: Duplica Video 3 o nuovo "Video4 Toggle" → Arduino Uno + breadboard + pushbutton + LED rosso + 220Ω (no 10kΩ se INPUT_PULLUP)
- Cablaggio INPUT_PULLUP (consigliato): Arduino pin 2 → cavo giallo → breadboard → pulsante pin 1, pulsante pin 2 → cavo nero → bus GND → Arduino GND. Pin 13 → 220Ω → anodo LED → catodo → GND. Solo 2 fili per pulsante, senza resistenza esterna
- Codice toggle con edge + debounce: const int button=2 led=13, bool statoLed=false, bool ultimoStato=HIGH, unsigned long ultimoTempo=0, setup pinMode button INPUT_PULLUP led OUTPUT Serial, loop leggi statoAttuale digitalRead button, se statoAttuale LOW && ultimoStato HIGH && millis()-ultimoTempo>50 → toggle statoLed=!statoLed digitalWrite led statoLed ultimoTempo=millis, ultimoStato=statoAttuale, delay 10
- Simulazione: Start → LED OFF → clic pulsante → LED ON resta → riclicca → LED OFF → Serial mostra toggle ON/OFF con debounce
- Variante semplice con delay: if digitalRead LOW → statoLed=!statoLed digitalWrite delay 200 per evitare rimbalzo (meno professionale ma didattica)
INPUT_PULLUP: pin 2 → pulsante → GND, 2 fili, logica LOW premuto. Memoria: bool statoLed false OFF true ON, statoLed = !statoLed toggle. Edge detection: controlla ultimoStatoPulsante HIGH e attuale LOW = pressione singola. Debounce: millis() - ultimoTempo >50ms o delay 50ms semplice. Così 1 pressione = 1 toggle, non 4. Serial per debug toggle ON/OFF. Nel video al minuto 19 mostro Serial con millis e stato.
7. Errori comuni da evitare
- Codice Video 3 per interruttore: if HIGH LED ON else OFF senza memoria → LED ON solo mentre premi, non resta ON. Serve bool statoLed e !statoLed su edge.
- Toggling continuo tenendo premuto: if LOW toggle senza edge detection → tenendo premuto LED continua ON-OFF-ON velocissimo. Controlla transizione HIGH→LOW, non stato LOW continuo.
- Debounce mancante: senza delay 50ms o millis, 1 pressione = 3-4 toggle per rimbalzo meccanico, LED fa ON-OFF-ON in una pressione. Sempre debounce 50ms.
- Boolean vs int confusione: int statoLed = 0 poi statoLed = !statoLed con int → !0=1 ok ma !1=0 ok ma tipo errato, usa bool per chiarezza.
- INPUT invece di INPUT_PULLUP: pinMode INPUT senza resistenza esterna → pin flottante come Video 3 errore, toggle casuale. Usa INPUT_PULLUP senza resistenza esterna o pull-down 10kΩ con INPUT.
- UltimoStato non aggiornato: dimentichi ultimoStatoPulsante = statoAttuale a fine loop → edge detection fallisce dopo prima pressione. Sempre aggiorna ultimo stato.
- Delay lungo blocca tutto: delay 500 dopo toggle → sistema bloccato 0.5s, pressioni perse. Usa 50ms debounce o millis non bloccante.
Toggle senza edge detection e senza debounce. Sintomo: premi una volta, LED fa ON-OFF-ON-OFF velocissimo, Serial mostra 4 toggle per 1 pressione, tenendo premuto LED lampeggia continuo, comportamento casuale. Soluzione: edge detection: if attuale LOW && ultimo HIGH allora toggle, debounce con millis()-ultimoTempo>50, aggiorna ultimoStato = attuale a fine loop, statoLed = !statoLed, digitalWrite statoLed. Nel video al minuto 14 mostro oscilloscopio con rimbalzo 20ms e Serial con 4 letture.
8. Approfondimento: if-else e memoria
Introduciamo programmazione con stato:
| Concetto | Video 3 | Video 4 (toggle) |
|---|---|---|
| Memoria | Nessuna | bool statoLed ricorda ON/OFF |
| if | if(HIGH) ON else OFF diretto | if(LOW && ultimo HIGH) edge + debounce |
| Operatore | = assegna | ! NOT inverte, == confronta, && AND |
| Pressione | Continua = ON continuo | Singola transizione = toggle |
| Debounce | Opzionale | Obbligatorio 50ms millis o delay |
| Uso | Luce finché premi | Interruttore luce casa, domotica |
Prossimo video: Pulsante che attiva blink alternato di due LED - combina Video 2 e 4.
📚 Compito per casa
Crea su Tinkercad circuito Video 4 toggle: Arduino Uno, breadboard, pushbutton, LED rosso + 220Ω, cablaggio INPUT_PULLUP pin 2 → pulsante → GND, pin 13 → 220Ω → LED → GND. Codice con bool statoLed=false ultimoStato=HIGH millis debounce 50ms, setup pinMode INPUT_PULLUP e OUTPUT, loop edge detection HIGH→LOW toggle statoLed=!statoLed digitalWrite, Serial toggle ON/OFF. Simula: LED OFF iniziale, premi pulsante LED resta ON, ripremi OFF, con debounce singolo toggle per pressione. Prova variante semplice con delay 200 e while attesa rilascio. Screenshot LED ON stabile dopo pressione + Serial toggle + codice. Mandamelo prima del Video 5 pulsante + 2 LED alternati.
