Accendere un led con una sequenza di tasti

Io avevo messo 100 come delay, delay(100); // per debounce dei pulsanti
Il problema di base è il debounce o rimbalzo del pulsante. Quando lo premi una volta in realtà (non sempre) lo premi più volte a causa del contatto elettrico. Se cerchi nel forum o su internet trovi parecchie spiegazioni e rimedi software e hardware.

Per le resistenze ai led, non servono per far funzionare il programma ma per non bruciare i led.

Poi non ho capito, se premi un pulsante di seguito esempio l'1 certo che var diventa zero, è come se premessi 1 e poi invece della seuenza stabilita 1 e poi 2 !?!

per risolvere il problema che premendo i tre tasti si accende il led prova ad invertire l'ordine di lettura dei tasti, visto che adesso sono tasto 1, 2 e 3 modifica il programma in modo che legga prima il tasto 3 poi il 2 e infine il primo in questo modo penso dovrebbe funzionare

nid69ita:
Io avevo messo 100 come delay, delay(100); // per debounce dei pulsanti
Il problema di base è il debounce o rimbalzo del pulsante. Quando lo premi una volta in realtà (non sempre) lo premi più volte a causa del contatto elettrico. Se cerchi nel forum o su internet trovi parecchie spiegazioni e rimedi software e hardware.

Per le resistenze ai led, non servono per far funzionare il programma ma per non bruciare i led.

Poi non ho capito, se premi un pulsante di seguito esempio l'1 certo che var diventa zero, è come se premessi 1 e poi invece della seuenza stabilita 1 e poi 2 !?!

Onestamente non conoscevo il problema del rimbalzo dei pulsanti e mi hai insegnato un'altra cosa nuova.Grazie mille!

Tu lo avevi inserito solo dopo l'else, ma dopo varie prove l'ho inserito sotto ogni if e di 200 delay(200) e questo problema sembra risolto.

Grazie anche per il consiglio riguardo ai led, dove ho messo una resistenza di 220.

Io vorrei fare in modo che ogni volta che si prema il primo tasto la variabile vada ad 1 e non so se tecnicamente è corretto, ma ho risolto sostituendo il primo if con questi 3: if(var==0) var=1; else var=1; if(var==1) var=1; else var=1; if(var==2) var=1; else var=1; e funziona!

stefanodaimler:
Onestamente non conoscevo il problema del rimbalzo dei pulsanti e mi hai insegnato un’altra cosa nuova.Grazie mille!

È cosa di cui, su questo forum, si è parlato centinaia di volte e … prima di mettersi a fare qualsiasi progetto, un po’ di ricerche per capire quali possono essere eventuali problemi è sempre bene farle ::slight_smile:

Comunque, vediamo di chiarire il concetto …
… contrariamente a quanto tu puoi pensare, un pulsante “reale” ha un comportamneto del tutto differente da un pulsante “ideale” che si apre e chiude in modo pulito. Un pulsante “reale” quando lo premi produce un qualche cosa di simile a questo:

… per cui, il tuo pin su Arduino, interpreta tutti quei “rimbalzi” meccanici del contatto, come tante aperture e chiusure.

Una strada è quella che ti è stata suggerita, ma introduce dei delay() che NON sempre possono essere usati (es. in ISR molto veloci), l’altra è quella di eliminarli alla fonte con un apposito circuitino in ingresso al pin (vd. allegato).

Guglielmo

debouncing_hw.pdf (22.8 KB)

gpb01:
È cosa di cui, su questo forum, si è parlato centinaia di volte e ... prima di mettersi a fare qualsiasi progetto, un po' di ricerche per capire quali possono essere eventuali problemi è sempre bene farle ::slight_smile:

Onestamente non ero proprio a conoscenza del problema e quindi non avevo fatto ricerche in merito.

Da ora in poi starò piu' attento e cercherò ancora meglio. Grazie ancora!

stefanodaimler:
Onestamente non ero proprio a conoscenza del problema e quindi non avevo fatto ricerche in merito.

Il consiglio è valido anche se non si è a conoscenza di problemi (... anzi, è la normalità) ... cercando/verificando l'esistenza di problematiche che possono esserci a secondo di cosa si cerca di collegare ad Arduino :wink:

Spesso ti risparmi svariate ore di "mal di testa" :smiley: :smiley: :smiley:

Guglielmo

stefanodaimler:
ho risolto sostituendo il primo if con questi 3: if(var==0) var=1; else var=1; if(var==1) var=1; else var=1; if(var==2) var=1; else var=1; e funziona!

Ma ti sembra che quell'if abbia senso? :o Tanto vale scrivere solo var=1...

-zef-:
per risolvere il problema che premendo i tre tasti si accende il led prova ad invertire l'ordine di lettura dei tasti, visto che adesso sono tasto 1, 2 e 3 modifica il programma in modo che legga prima il tasto 3 poi il 2 e infine il primo in questo modo penso dovrebbe funzionare

Grazie mille anche per il tuo consiglio! Il programma funziona alla grande!

SukkoPera:
Ma ti sembra che quell'if abbia senso? :o Tanto vale scrivere solo var=1...

Scusami ma ho premesso che probabilmente non sarebbe stato tecnicamente perfetto, ma scrivendo solo var=1, il programma non funzionava.
Sicuramente avrò fatto degli errori prima , ma riprovando ora funziona quindi ho sostituito i 3 if con var=1;

Grazie ancora

Non è questione di essere tecnicamente perfetti o meno (non lo si è mai :D), quanto del fatto che se vuoi imparare, devi iniziare a chiederti perché facendo una certa modifica (magari inizialmente pure casuale!) una cosa inizia a funzionare. Nella fattispecie, ragionando adeguatamente su quell'if, dovresti capire che se il suo corpo e quello dell'else sono uguali, tanto vale mettere il corpo e basta!

SukkoPera:
Non è questione di essere tecnicamente perfetti o meno (non lo si è mai :D), quanto del fatto che se vuoi imparare, devi iniziare a chiederti perché facendo una certa modifica (magari inizialmente pure casuale!) una cosa inizia a funzionare. Nella fattispecie, ragionando adeguatamente su quell'if, dovresti capire che se il suo corpo e quello dell'else sono uguali, tanto vale mettere il corpo e basta!

Hai perfettamente ragione, mi sono fatto fregare dal fatto di aver provato e aver rilevato un errore.

Voglio imparare e quindi devo ragionarci di piu'.

Per esempio, se volessi cambiare la sequenza e quindi al posto di 1,2,3, volessi usare la sequenza 1,2,2,3 per accendere il led, come potrei fare?

Usando 2 if diversi per lo stesso tasto, mi viene letto solo il primo e quindi ho provato ad inserire un if dopo un else, ma sto cercando per avere la sintassi corretta, ma inutilmente.

Secondo me la soluzione dovrebbe essere quella o no?

stefanodaimler:
Usando 2 if diversi per lo stesso tasto, mi viene letto solo il primo e quindi ho provato ad inserire un if dopo un else, ma sto cercando per avere la sintassi corretta, ma inutilmente

Quello che serve è capire se è la prima o la seconda volta che si preme quel tasto, e questo probabilmente richiede anche di determinare, in un modo o nell'altro, se è già avvenuto il primo rilascio.

Queste cose si risolvono con variabili di stato, per cui il programma deve tenere conto non solo delle letture degli ingressi attuali, ma anche delle informazioni di stato generate nei cicli precedenti.

Non per forza la variabile var che poi è la variabile di stato DEVE essere uguale a numero del tasto.
Se la sequenza è tasto 1,2,2,3 la var avrà gli stati 1,2,3,4 quindi quando premi il 2 la prima volta se var==1 diventa 2 ma se era già 2 diventa 3.
Quando premi il 3 diventa il 4
Ripeto, var= un numero che indica lo stato della sequenza. Non per forza deve corrispondere al tasto

nid69ita:
Non per forza la variabile var che poi è la variabile di stato DEVE essere uguale a numero del tasto.
Se la sequenza è tasto 1,2,2,3 la var avrà gli stati 1,2,3,4 quindi quando premi il 2 la prima volta se var==1 diventa 2 ma se era già 2 diventa 3.
Quando premi il 3 diventa il 4
Ripeto, var= un numero che indica lo stato della sequenza. Non per forza deve corrispondere al tasto

Si, giustissimo! Era semplice ma a volte le cose piu' semplici sfuggono.

Grazie mille!

Problema risolto!

E mi avete insegnato tanto!