Antirimbalzo senza delay(n)

Mi serve un' antirimbalzo per leggere lo stato di alcuni pulsanti.

Nel forum ho trovato alcuni post dove pero' si usa il delay, che a me non va bene perche' il micro deve fare parecchie cose, e non puo' permettersi di stare ad aspettare...

Se non usi gli appositi IC che eliminano i rimbalzi non puoi non utilizzare delle attese per convalidare gli stati del pulsante/interruttore, questo non significa che il micro deve rimanere fermo ad aspettare, semplicemente che non deve considerare valide variazioni dello stato per un certo tempo, tipicamente da 20 a 50 ms.
Guardati l'esempio blink senza delay dove viene usata la millis per determinare quando accendere/spegnere il led senza fermare l'elaborazione, il concetto e la tecnica da utilizzare è la stessa.

Su ogni pin è gia presente, all'interno del micro, un trigger di schmitt con soglie Vcc/3 e 2Vcc/3, quindi non hai bisogno di hardware o software supplementare in questo senso.

Janos, però questo non risolve il problema del bounce, no?

Janos:
Su ogni pin è gia presente, all'interno del micro, un trigger di schmitt con soglie Vcc/3 e 2Vcc/3, quindi non hai bisogno di hardware o software supplementare in questo senso.

Non si parlava di questo e comunque dubito che le entrate sono realizzate come trigger di schmitt.
Un integrato che risolve i rimbalzi via HW é il MC14490 http://www.onsemi.com/pub_link/Collateral/MC14490-D.PDF
Ciao Uwe

Altre soluzioni hardware:
MAX6816 MAXIM Single Switch Debounce SOT143-4
MAX6817 MAXIM Double Switch Debounce SOT23-6
MAX6818 MAXIM Octal Switch Debounce TSSOP-20

il vantaggio dell'IC consigliato da Uwe è che esiste in formato PDIP. Personalmente con un banalissimo Delay(100) ho risolto il problema, ma nel mio caso la situazione è semplice, visto che devo semplicemente aspettare che venga premuto un pulsante; se invece hai problemi ad interrompere il firmware, allora la soluzione di Astro (millis) è perfetta.

Janos:
Su ogni pin è gia presente, all'interno del micro, un trigger di schmitt con soglie Vcc/3 e 2Vcc/3, quindi non hai bisogno di hardware o software supplementare in questo senso.

No, solo su alcuni pin c'è il trigger, e comunque non risolve nulla per quanto riguarda i rimbalzi degli switch, semmai serve un flipflop RS con reset temporizzato.

astrobeed:

Janos:
Su ogni pin è gia presente, all'interno del micro, un trigger di schmitt con soglie Vcc/3 e 2Vcc/3, quindi non hai bisogno di hardware o software supplementare in questo senso.

No, solo su alcuni pin c'è il trigger, e comunque non risolve nulla per quanto riguarda i rimbalzi degli switch, semmai serve un flipflop RS con reset temporizzato.

YES, la soluzione che ho adottato io per il cambi portata del mio capacimetro: un pulsante con pull-down sul SET ed un clock da 5Hz sul RESET, qualche incertezza c'è se becchi proprio il fronte, più che altro perché a volte c'è la necessità di cambiare più portate per arrivare a quella desiderata, ma il risultato finale è accettabilissimo.

Nel forum ho trovato alcuni post dove pero' si usa il delay, che a me non va bene perche' il micro deve fare parecchie cose,

ciao , strano che nessuno te l'abbia proposto, ma invece del delay puoi utilizzare millis, che non blocca di fatto l'esecuzione del codice*, come già proposto da Astro e ribadito da Menniti*:

Oltretutto nell'IDE c'è un esempio che calza a pennello:
example -> Digital -> Debounce

Pitusso, l'unica cosa strana è che tu non ti sia accorto che se n'è parlato almeno in due post (Astro e io a riferimento) all'inizio, di solito sei più attento :slight_smile:

@menniti
c'hai proprio ragione :roll_eyes:

Ma: repetita iuvant :wink:

Una resistenza di pull-*** un condensatore ceramico in parallelo al pulsante risolve il 50% e un delay di 5ms risolve l'altro 50%. Se dici che il programma è piuttosto affaticato dubito che lo stato di quella porta venga letto più di 50-60 volte al secondo dallo sketch.
A me funziona alla grande anche senza delay, mai avuto un falso segnale da normali contatti.

ciao

pablos:
Una resistenza di pull-*** un condensatore ceramico in parallelo al pulsante risolve il 50% e un delay di 5ms risolve l'altro 50%. Se dici che il programma è piuttosto affaticato dubito che lo stato di quella porta venga letto più di 50-60 volte al secondo dallo sketch.
A me funziona alla grande anche senza delay, mai avuto un falso segnale da normali contatti.

ciao

che capacità usi? se ti funziona bene è perché evidentemente usi i classici pulsantini a membrana, prova con qualcosa di metallico e cambierai idea, visti all'oscilloscopio, i rimbalzi di una sola pressione sembrano fuochi d'artificio :fearful:, però il tuo caso a me capita spesso e mi piacerebbe risolvere buona parte con una C, quindi vorrei fare qualche prova. tnx :slight_smile:

menniti:
che capacità usi? se ti funziona bene è perché evidentemente usi i classici pulsantini a membrana, prova con qualcosa di metallico e cambierai idea,

Indubbiamente il tipo di contatto fa la differenza, il classico pulsante/switch a lamelle metalliche produce una marea di impulsi spuri per molti millisecondi, un contatto di tipo a membrana non metallica, per capirci tipo quelli dei telecomandi, produce pochi impulsi spuri e un semplice filtro RC può bastare per fermarli tutti.

il condensatore è questo http://italian.alibaba.com/product-gs/the-best-selling-ceramic-capacitor-104-302506208.html
10K di pull down
io uso dei microswitch per finecorsa industriali come test, ho provato anche con un filo a fare il ponticello e va bene lo stesso
Probabilmente con l'oscilloscopio qualche fuoco d'artificio lo vedrai ancora, sarei curioso di sapere come rende ad altri

Prova a visualizzare il serial monitor con e senza C vedi la differenza :slight_smile:

esempio di passo-passo

// condensatore ceramico in parallelo al puls. d'obbligo altrimenti non funziona 
const int ledPin = 40; // pin del relè
#define BUTTON 38      // pin di input dove è collegato il pulsante
long cont; // contatore

void setup() 
{
  Serial.begin(9600);
  pinMode(BUTTON, INPUT);     
  pinMode(ledPin, OUTPUT);
}

void loop() 
{
        if (digitalRead(BUTTON) == HIGH) cont++; else cont=0;
       
        if (digitalRead(ledPin)==LOW && cont == 1) 
        {
          cont++;
          //delay(5); // senza condensatore (comunque opzionale)
          digitalWrite(ledPin, HIGH);
          Serial.println("ON");
        } 
        
        if (digitalRead(ledPin)==HIGH && cont == 1) 
        {
          cont++;
          //delay(5); // senza condensatore (comunque opzionale)
          digitalWrite(ledPin, LOW);
          Serial.println("OFF");
        }
}

ciao

menniti:
Pitusso, l'unica cosa strana è che tu non ti sia accorto che se n'è parlato almeno in due post (Astro e io a riferimento) all'inizio, di solito sei più attento :slight_smile:

effetto calimero ... :wink: :wink: :wink:

Dipende molto dal tipo e dalla costruzione del contatto. Esistono anche pulsnti costruiti a posta senza rimbalzo. Non posso darti nessun modello.
Ciao Uwe