Problema Incremento Variabili tramite pulsante

Salve a tutti sono nuovo, ho un problema e come da oggetto non riesco ad incrementare le variabili tramite un semplice pulsante, spiego meglio, il pulsante funziona ma quando vado a premerlo incrementa di circa 10,15 al posto di 1; penso sia perchè è molto veloce, ho pensato come soluzione di utilizzare qualche funzione di tempo e legarla allo stato del pulsante ad esempio

If([funzione tempo]&&BUTTO==LOW)
codice;
dovrebbe quindi se il pulsante è premuto per non so un 2, 3 secondi incrementare la variabile, avete qualche idea su come si possa fare???
grazie in anticipo.

Ciao, utilizzo sempre il seguente codice:

if(pulsante == LOW) {
  while (pulsante == LOW) {}
variabile ++;
}

Saluti.

Grazie per la tempestività, purtroppo ora non ho la possibilità di provare, l unico dubbio che mi viene è se l incremento della variabile non vada fatto nel ciclo while, così:

If(button==LOW)
{
while(button==LOW)
{
variabile++;
}
}

Otterresti lo stesso "malfunzionamento" che hai ora.
Questo pezzettino di codice è semplice e spesso risolutivo, però non è del tutto "safe" nei confronti dei rimbalzi del pulsante.

Anche se poco probabile dal punto di vista statistico, nel momento in cui vai a valutare la condizione del while, a causa del rimbalzo il segnale potrebbe essere tornato HIGH per una frazione di secondo e quindi generare comunque una falsa lettura.

La cosa migliore è aggiungere sempre in serie ai pulsanti (cosi come ai contatti di relè ad esempio) un filtro RC (resistenza + condensatore).

@albit10 : NON avendolo tu ancora fatto, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie.

@gonpezzi , @cotestatnt : Vi ricordo che, in conformità al REGOLAMENTO della sezione Italiana del forum, NON è permesso rispondere a chi NON si è ancora presentato ... cortesemente prestate più attenzione, grazie.

@albit10 : questo tuo thread viene solo temporaneamente bloccato in attesa che tu adempia a quanto richiesto.

Nel caso non dovessi accorgermene, quando avrai inserito la presentazione e letto il regolamento, avvertimi in MP che sblocco.

Guglielmo

Mi scuso per non essermi presentato,

Quindi suggerisci di aggiungere in serie un filtro RC e di utilizzare il codice con l incremento dopo il while nel if? O quello con l incremento dentro il while?
Se è come nel primo caso non capisco perché dovrebbe funzionare

Intanto devi pensare che, contrariamente ad un pulsante "ideale", un pulsante "reale" quando viene premuto o rilasciato genera un segnale, causa rimbazi meccanici delle parti, di questo tipo:

image

che, alla velocità a cui gira Arduino, viene spesso letto NON come una singola pressione o rilascio, bensì come una serie delle due cose.

Per evitare questo devi fare un debouncing ... lo puoi fare sia software (aspettando un determinato tempo), sia hardware (inserendo una rete R/C); la seconda opzione è quella che personalmente preferisco e che, nel caso il pulsante controlli degli interrupt, diventa praticamente obbligatoria.

Un possibile esempio di circuito R/C per il debouncing può essere:

image

Detto questo, una volta che hai un segnale pulito, è molto semplice da codice verificare la pressione del bottone, aspettare tutto il tempo che il bottone resta premuto e, al rilascio, fare quello che si deve fare ... che è quello che il codice di gonpezzi, al post #2 fa :slight_smile:

Guglielmo

Perfetto! Grazie mille a tutti, appena sono a casa faccio una prova e vi faccio sapere, buonagiornata :smiley:

Ma no (ammettendo che sia stato implementato il debounce) lo scopo di quel codice ossia della while() è quello di incrementare il contatore solo dopo aver "atteso" che il tasto venga rilasciato. Nel codice che hai messo tu, dato che Arduino lavora molto velocemente otterresti un rapidissimo incremento del valore (migliaia di volte al secondo...) per tutto il tempo in cui tieni premuto, e non un incremento di una unità ogni volta che premi il pulsante, quindi va fatto fuori dalla while come ha indicato gonpezzi.
Attenzione però a due cose:

  1. in quel codice "pulsante" appare come una variabile e se dentro al while non viene aggiornata, una volta entrato lì il codice non uscirà mai. Deve essere una cosa del tipo:
if(digitalRead(PIN_PULS) == LOW) {
  while (digitalRead(PIN_PULS) == LOW) {}
  variabile ++;
}
  1. Con questo approccio, Arduino non potrà fare nulla per tutto il tempo in cui il pulsante viene premuto! Questo significa che se ci sono cose da controllare (leggere valori, inviare comandi, contare temporizzazioni...) in tempo quasi-reale ossia in modo continuativo rischi di "saltare" temporizzazioni o letture di altre cosa quindi in tal caso non va usato questo approccio ma bisogna lavorare solamente con gli interrupt (sai cosa sono e come si gestiscono su Arduino? Se non lo sai magari è l'occasione per farlo, perché ti assicuro che su molti progetti è quasi necessario usarli..).

Credo di aver capito, in ogni caso finalmente stasera potrò provare, effettivamente sono nuovo nel mondo arduino, andrò a studiare gli interrupt (e anche basi di circuiti perchè l RC per il debouncing non l avrei mai sognato)
grazie mille a tutti e buona continuazione! :slight_smile:

Diciamo che per il debounce puoi anche non studiare in modo approfondito, usa quello schema consigliato quando hai necessità di farlo via hardware che è la soluzione migliore. Occhio che quello è in configurazione "pull up" ossia è a "logica invertita": l'ingresso sarà sempre HIGH e diventa LOW quando viene premuto (semmai informati su questo aspetto ossia la differenza tra un ingresso "pull up" ed un "pull down").

In alcuni casi puoi limitarti al "debounce software" ossia quando rilevi la pressione del pulsante (es. passaggio da HIGH a LOW, quindi ad ogni ciclo dovresti memorizzare il precedente stato del pulsante) attendere con un delay() un tempo fisso, diciamo tra 50 e 100 millisecondi che è la durata "media" dei rimbalzi meccanici, sempre a patto che questa attesa non sia importante per fare altre cose.

Comunque per darti qualche altra indicazione di massima su cosa studiare, nel mondo Arduino è importante saper usare gli interrupt perché in alcuni casi è utile non dover stare a monitorare le transizioni di un ingresso (ad esempio di un pulsante da LOW a HIGH se gestito in "pull down", o al contrario da HIGH a LOW se gestito con "pull-up") ma ancora più importante ed usata è la funzione millis() che serve per poter dare temporizzazioni a controlli/azioni evitando cicli di attesa con while(), o con la funzione delay, che tiene fermo il codice in quel punto, impedendo di fare altro.