Aby se mi hodnota digitalRead() nemenila v cyklu, i kdyz to treba zrovna kmita, tak ji nactu jen jednou - do reading - a dal pracuju s touto hodnotou, co byla na zacatku cyklu:
Kód: Vybrat vše
int reading = digitalRead(buttonPin);
Pak tam jsou dve ruzne veci, ktere se tak nejak prolinaji:
nejdriv musim zjistit, zda mi to nekmita dost dlouho:
Kód: Vybrat vše
if (reading != lastButtonState) { // kmita to, od minule se to zmenilo, zacnu debounce cas pocitat znovu (tedy od posledni zmeny, ktera je ted)
lastDebounceTime = millis();
};
.....
lastButtonState = reading; // tady si to ulozim, v dalsim pruchodu loop() to zase porovnam s novym reading, zda se to mezi tim nezmenilo
(ze si lastButtonState ukladam az na konci nevadi, protoze s nim stejne nikde jinde nepracuju. Klidne by se dal ulozit jeste pred tema teckama a nic by to neovlivnilo - pokud bych ho pak nekde nepotreboval pouzit teda, coz tady nepotrebuju)
a pokud to nekmita uz dost dlouho, tak muzu neco delat:
Kód: Vybrat vše
if ((millis() - lastDebounceTime) > debounceDelay) { // jo, uz se to dlouho nezmenilo, tak je to stabilni a spravna hodnota
if (reading != buttonState) { // Pokud se stav tlačítka změnil
buttonState = reading; // zapamatuju si novy stav
// a tady (treba) budu neco delat
.....
};
};
a to neco delat by melo byt:
Kód: Vybrat vše
// a tady (treba) budu neco delat
if (buttonState == HIGH) { // tlacitko bylo pusteno
// nejake vrteni servama
};
pricemz nejake vrteni servama je:
Kód: Vybrat vše
// nejake vrteni servama
for (pos = 0; pos <= 180; pos += 1) {
myservo.write(pos);
delay(15);
};
for (pos = 180; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(15);
};
cili to Servo prijde na radu mezi zjistovanim, zda to kmita a ulozenim posledni zname hodnoty, ale prijde na radu jen, pokud se zjistilo, ze to uz nekmita.
(ackoli by to samozrejme mohlo byt i obracene, ze se nejdriv ulozi ten lastButtonState a pak az se osetruji serva.)
----
Jinak kazda slozitejsi vec (a spousta trivialnich veci taky) se da udelat nekolika ruznymi zpusoby -
napr. kiRRow resi debouncing tak, ze pokud se zmeni hodnota, tak ceka tak dlouho, az se prestane menit a zustane tak delsi dobu a to pak bere jako spravny vysledek a na jeho zaklade jedna.
Ja naopak beru jako spravny vysledek hned prvni zmenu hodnoty a jednam, zatimco nejakou dobu vstup ignoruju, dokud se neustali a teprve pak jsem ochoten prijmout nekdy dalsi zmenu.
Oboji ma sve vyhody a nevyhody - kiRRow nema problem, pokud tlacitko obcas na mzik ztrati (nebo ziska) kontakt, protoze se mu pak ustali a hodnota je stejna jako predtim. Cenou za to je, ze nez zacne reagovat, tak musi chvili cekat na ustaleni tlacitka. (a v extremnim pripade, pokud mu to zakmitava furt, tak se nikdy nedocka)
Ja naopak beru, ze kdyz se hodnota zmenila, tak to znamena, ze tlacitko se hnulo a jednam okamzite - tim ziskam extremne kratkou latenci a muzu udelat spoustu veci, nez se tlacitko umravni. Cenou za to je, ze zasumena tlacitka, ktera si "jen tak" obcas propusti falesny signal beru jako platne stisky a pusteni, cili nemam takovou odolnost proti ruseni. (a v extremnim pripade, pokud mi to zakmitava furt to beru jako hodne rychly autorepeat a furt na to reaguju)
Takze on eventualne nedostane signal nikdy, zatimco ja dostanu neomezene mnozstvi signalu - zalezi na aplikaci, co je prijatelnejsi reakce na chybu. (Ja to pouzivam pro hry a podobne, takze okamzita reakce a autorepeat/kulomet je pro me prijatelnesi nez odolnost proti ruseni, ztraty rychlych stisku a prodleva v reakci )
A samozrejme jde vymyslet i jine varianty, treba, ze se po zmene pevnou chvili ceka a pak se rozhodne podle aktualni hodnoty - bud je stejna a slo jen o ruseni, nebo je jina a slo o stisk, s tim, ze v extremnim pripade je celkem nahodne, zda vyjde stisk, ci ne, ale proste s tak blbym tlacitkem je to stejne asi fuk, protoze si dela co chce a nebudeme blokovat, dokud se samo neopravi.