Folgende Erklärung zum Code steht dabei - Zitat: "Da ist keine Hexerei
dabei: In key_state wird der letzte bekannte entprellte Zustand der
Taste gehalten. Der Pin-Eingang wird mit diesem Zustand verglichen und
wenn sich die beiden unterscheiden, dann wird ein Zähler
heruntergezählt. Produziert dieses herunterzählen einen Unterlauf des
Zählers, dann gilt die Taste als entprellt und wenn dann auch noch die
Taste gerade gedrückt ist, dann wird dieses in key_press entsprechend
vermerkt."
Dazu habe ich folgende Fragen:
- Mit welcher Frequenz sollte die ISR (sinnvollerweise) aufgerufen
werden?
- Wenn ich es richtig verstehe, gilt die Taste dann als gedrückt, wenn
bei vier Aufrufen der ISR (in Folge) der Zustand der Taste abweichend
vom jeweils vorherigen Aufruf ist und die Taste aktuell gedrückt ist?
Wie "zuverlässig" ist das? Wenn z. B. in der Entprellungsphase bei zwei
aufeinanderfolgenden Aufrufen der Zustand der Taste ("immer") gleich
wäre und dann wechselt, würde die Taste nie als gedrückt erkannt, oder?
Z. B.:
Aufruf 1: gedrückt
Aufruf 2: gedrückt
Aufruf 3: nicht gedrückt
Aufruf 4: nicht gedrückt
...
Was wahrscheinlich auch von der Frequenz der ISR abhängt?
Oder falls die Taste Hardware-seitig schon entprellt wäre, würde dieser
Wechsel gedrückt/nicht gedrückt auch nicht auftreten und der Tastendruck
würde nicht erkannt?
Oder versteh ich etwas vollkommen falsch?
Danke & VG
Mike
Hi!
20 bis 30 ms Timer-Intervall sind völlig ausreichend.
In der ISR wird die Variable bei fertigem Entprell-Vorgang gesetzt. Im
Hauptprogramm sollte sie nach dem Abarbeiten wieder gelöscht werden.
Gruß
Carsten
Danke!
Carsten Wille schrieb:> In der ISR wird die Variable bei fertigem Entprell-Vorgang gesetzt.
Und funktioniert der Entprell-Vorgang wie von mir angenommen? 4x Aufruf
mit unterschiedlichem Tastezustand und dann Variable gesetzt? Und sind
die von mir genannten "Bedenken" unbegründet?
Mike schrieb:
> - Mit welcher Frequenz sollte die ISR (sinnvollerweise) aufgerufen> werden?
Ist nicht kritisch.
Wenn dein Timer in deinem Programm schon eine andere Aufgabe hat und die
ISR eine Aufruf-Zeitdifferenz im Bereich 5ms bis ca. 50ms hat, dann
passt das schon. Du kannst die Tastenentprellung da mit dazuhängen.
Hast du noch keinen Timer im Einsatz, dann such dir eine Zeit in diesem
Bereich aus, die dir genehm ist.
> - Wenn ich es richtig verstehe, gilt die Taste dann als gedrückt, wenn> bei vier Aufrufen der ISR (in Folge) der Zustand der Taste abweichend> vom jeweils vorherigen Aufruf ist
nicht vom 'jeweils vorhergehenden Aufruf'.
Die Taste gilt als erkannt, wenn sie 4 mal hintereinander in einem
abweichenden Zustand zum zuletzt als gültig erkannten Zustand
angetroffen wird.
> und die Taste aktuell gedrückt ist?
gedrückt ist wurscht. Die Entprellung arbeitet ja auch beim Loslassen
einer Taste.
> Wie "zuverlässig" ist das?
Extrem zuverlässig
> Wenn z. B. in der Entprellungsphase bei zwei> aufeinanderfolgenden Aufrufen der Zustand der Taste ("immer") gleich> wäre und dann wechselt, würde die Taste nie als gedrückt erkannt, oder?> Z. B.:>> Aufruf 1: gedrückt> Aufruf 2: gedrückt> Aufruf 3: nicht gedrückt> Aufruf 4: nicht gedrückt> ...
Im Prinzip richtig.
Nur wird das nie passieren. Und zwar deshalb nicht, weil kein Mensch es
schafft eine Taste innerhalb von 20ms (4 * 5ms) zu drücken und wieder
loszulassen. 20ms sind 2 Hunderstelsekunden. In der Zeit kannst du noch
nicht mal zwinkern, geschweige denn eine Taste drücken.
> Oder falls die Taste Hardware-seitig schon entprellt wäre, würde dieser> Wechsel gedrückt/nicht gedrückt auch nicht auftreten und der Tastendruck> würde nicht erkannt?>> Oder versteh ich etwas vollkommen falsch?
Du überschätzt Menschen. Für uns sind 20 oder 50ms eine unglaublich
kurze Zeit. Ein Skirennläufer legt in dieser Zeit bei Vollgas gerade mal
ein paar Zehn Zentimeter zurück. Für uns Menschen ist alles kürzer als
1/10 Sekunde unglaublich kurz. 1/10 Sekunde sind 100ms. Und für einen µC
ist das 'alle heilige Zeiten'.
> ich habe eine Frage zu einem Code-Beispiel im Artikel "Entprellung":
Na ja.
Eigentlich ist das ja kein 'Code-Beispiel' im Sinne von
produktionstauglichem Code. Der von dir zitierte Code soll den
eigentlichen Entprellcode vom Prinzip her nur verdeutlichen, da hier
immer wieder im Forum die Aussage auftaucht "Der ist sooo kompliziert,
den versteh ich nicht". Der von dir zitierte Code ist nur ein
umgeschriebener Code, für den Fall einer einzelnen Taste und so
aufgedröselt, dass er leichter verstehbar ist. Der eigentliche Code
macht genau dasselbe. Nur macht er es für maximal 8 Tasten gleichzeitig,
ist kürzer und auch schneller, so dass es keinen wirklichen Grund gibt
die 'Langform' zu benutzen, ausser zu Studienzwecken um sich die
Systematik zu Gemüte zu führen und einen algorithmischen Ansatzpunkt bei
der Analyse des Originalcodes zu haben.
Vielen Dank!
Karl Heinz Buchegger schrieb:> Und zwar deshalb nicht, weil kein Mensch es>> schafft eine Taste innerhalb von 20ms (4 * 5ms) zu drücken und wieder>> loszulassen.
Dann hatte ich doch was missverstanden... mein Verständnis war, dass der
schnelle Wechsel "an <> aus" beim Drücken (bzw. Loslassen) nicht durch
den Menschen verursacht wird, sondern durch so eine Art "Wackelkontakt"
im Schalter (im Artikel heißt es "mechanische Vibrationen des
Schaltkontaktes") verursacht würde - und die könnten ja extrem kurz
sein...
Karl Heinz Buchegger schrieb:> Die Taste gilt als erkannt, wenn sie 4 mal hintereinander in einem>> abweichenden Zustand zum zuletzt als gültig erkannten Zustand>> angetroffen wird.
"hintereinander" bedeutet doch bei aufeinander folgenden ISR-Aufrufen.
D. h. dass der "Wackelkontakt" die gleiche Frequenz wie die ISR haben
müsste?
Karl Heinz Buchegger schrieb:> Der von dir zitierte Code ist nur ein>> umgeschriebener Code, für den Fall einer einzelnen Taste und so>> aufgedröselt, dass er leichter verstehbar ist
Ja, hab ich gelesen - aber wenn ich die "leichter verstehbare" Version
schon nicht verstehe... ;-)
Karl Heinz Buchegger schrieb:> Extrem zuverlässig
...glaube ich (auch wenn ich's wohl noch nicht 100% gerafft habe...)
Mike schrieb:> Vielen Dank!>> Karl Heinz Buchegger schrieb:>> Und zwar deshalb nicht, weil kein Mensch es>>>> schafft eine Taste innerhalb von 20ms (4 * 5ms) zu drücken und wieder>>>> loszulassen.>> Dann hatte ich doch was missverstanden... mein Verständnis war, dass der> schnelle Wechsel "an <> aus" beim Drücken (bzw. Loslassen) nicht durch> den Menschen verursacht wird, sondern durch so eine Art "Wackelkontakt"> im Schalter (im Artikel heißt es "mechanische Vibrationen des> Schaltkontaktes") verursacht würde - und die könnten ja extrem kurz> sein...
können sie.
Aber irgendwann pendelt sich jeder Taster dann mal in einen stabilen
Zustand ein. Und das geht um Größenordnungen schneller, als du die Taste
wieder loslassen kannst.
So ein Taster wechselst ja nicht ewig zwischen gedrückt und nicht
gedrückt.
> "hintereinander" bedeutet doch bei aufeinander folgenden ISR-Aufrufen.> D. h. dass der "Wackelkontakt" die gleiche Frequenz wie die ISR haben> müsste?
Nö.
Das bedeutet lediglich, dass die 4 mal hintereinander abfragen so
bemessen sind, dass auch der schleissigste Taster nach dieser Zeitspanne
nicht mehr prellen wird. Hat er sich noch nicht eingependelt, dann
beginnt eben die Zählung bis 4 jedesmal wieder von vorne. Aber
irgendwann hat er sich eingependelt und dann wird 4 mal hintereinander
der gleiche Zustand festgestellt und der Tastenzustand gilt als stabil.
Karl Heinz Buchegger schrieb:> dann wird 4 mal hintereinander>> der gleiche Zustand festgestellt und der Tastenzustand gilt als stabil.
vermutlich steh ich komplett auf dem Schlauch, aber muss nicht 4 mal
hintereinander ein unterschiedlicher Zustand festgestellt werden?
if( input != key_state )
Sonst müsste es doch heißen:
if( input == key_state )
Mike schrieb:> Karl Heinz Buchegger schrieb:>> dann wird 4 mal hintereinander>>>> der gleiche Zustand festgestellt und der Tastenzustand gilt als stabil.>> vermutlich steh ich komplett auf dem Schlauch, aber muss nicht 4 mal> hintereinander ein unterschiedlicher Zustand festgestellt werden?
unterschiedlich zu wem?
Antwort: zum letzten definitiv richtig erkanntem Tastenzustand.
if( input != key_state )
.....
key_state = input
(vermutlich reden wir eh vom selben).
Die Taste ist momentan nicht gedrückt und der Rest vom Programm weiß das
auch.
Jetzt wird niedergedrückt.
Die Stati sind damit unterschiedlich und der Zähler zählt auf 2
Hoppla. Der Taster prellt: Der Tastenzustand ist wieder gleich dem
letzten gemeldeten Zustand. Der Zähler wird wieder auf 3 gesetzt.
Die Kontaktzunge federt nach und stellt den Kontakt wieder her.
Damit ist (momentan nicht gedrückt) von (jetzt gedrückt unterschiedlich)
und der Zähler geht auf 2.
Beim nächsten mal nachsehen ist der Kontakt immer noch gedrückt und der
Zähler geht auf 1, da ja der zuletzt korrekt erkannte Zustand 'nicht
gedrückt' (also unterschiedlich) war.
Blöder Taster, der prellt immer noch und der Kontakt geht noch mal auf.
Portzustand und letzter gemeldeter Zustand sind damit wieder gleich und
der Zähler geht, marsch marsch, wieder zurück auf 3
Aber irgendwann hat auch dieser Preller ein Ende, der Pinzustand wird
als gedrückt gemeldet (und damit unterschiedlich zum letzten stabilen
Tastenzustand). Der Zähler geht auf 2
Erneutes Nachsehen, ein paar Millisekunden später. Der Kontakt ist immer
noch geschlossen (und damit unterschiedlich zum letzten bekannten
stabilen Zustand, welcher ja nicht gedrückt war - sieh ganz oben die
Ausgangssituation) und der Zähler geht auf 1
Nochmal nachsehen. Der Pinzustand ist immer noch unterschiedlich. Zähler
auf 0
Und kurze Zeit später nochmal nachsehen. Der Pinzustand ist immer noch
unterschiedlich zum letzten stabilen Zustand. Der Zähler geht auf -1
(0xFF) und damit ist der UNterlauf da: Die Taste ist entprellt, sie
wurde 4 mal hintereinander in einem anderen Zustand als dem zuletzt
stabilen Zustand (welcher nicht gedrückt war) angetroffen und gilt damit
dann tatsächlich als gedrückt. Neuer stabiler Tastenzustand ist daher:
Die Taste ist gedrückt - und der Zähler geht wieder auf 3.
Mike schrieb:> vermutlich steh ich komplett auf dem Schlauch, aber muss nicht 4 mal> hintereinander ein unterschiedlicher Zustand festgestellt werden?
Du hast doch in Deinem Eingangspost das Zitat aus dem Artikel
aufgeführt:
> In key_state wird der letzte bekannte entprellte Zustand der> Taste gehalten. Der Pin-Eingang wird mit diesem Zustand verglichen und> wenn sich die beiden unterscheiden, dann wird ein Zähler> heruntergezählt.
Also, wenn sich Zustand am Eingangspin und der in "key_state"
gespeicherte letzte entprellte Zustand unterscheiden, dann wird der
Zähler dekrementiert. Sind sie gleich, wird der Zähler zurückgesetzt.
Damit eine Zustandsänderung als gewollt interpretiert wird, müssen also
zwei Bedingungen erfüllt sein:
1. Es muss 4x hintereinander der gleiche Zustand am Eingangspin
festgestellt werden.
2. Dieser 4x festgestellte "neue" Zustand muss sich vom "alten" Zustand
unterscheiden.
Erst dann wird der "neue Zustand" in "key_state" gespeichert und ist ab
sofort der "alte" Zustand.
ah, ich verstehe (glaube ich zumindest) - danke für die super
Erläuterung!
Mein Denkfehler war wohl, dass key_state nur aktualisiert wird, wenn das
Prellen abgeschlossen ist - genau wie Du sagst, vom "definitiv richtig
erkanntem Tastenzustand" abweicht. Da ist ja noch ein "if( key_counter
== 0xFF )" dazwischen, bevor key_state aktualisiert wird... dachte
irgendwie, key_state wäre der Zustand beim letzten Aufruf der ISR
Jetzt kann ich die Routine auch "bedenkenlos" einsetzen :-) oder sogar
die schnellere und kürzere "Produktivversion" - aber da werd ich gar
nicht versuchen sie zu verstehen, manchmal muss man auch vertrauen.
Mike schrieb:> ah, ich verstehe (glaube ich zumindest) - danke für die super> Erläuterung!
Na siehste.
Ist eigentlich gaaaaaanz einfach.
Du hast ein Kabel in der Hand und wenn ich den Taster schliesse kriegst
du Strom ab.
Spürst du den Strom, dann zählst du langsam von 3 bis auf 0.
Setzt der Strom zwischendurch mal kurz aus, dann war es falscher Alarm
und du beginnst beim nächsten Stromfluss wieder bei 3, denn dann hat
mein Taster geprellt oder es war ein ganz kurzer Fehlalarm.
Gelingt es dir bis 0 zu zählen, dann schreist du 'aua' und dein Arzt
weiß, dass der Strom jetzt definitiv eingeschaltet ist.
:-)
(und beim Ausschalten natürlich auch in der umgekehrten Richtung. Spürst
du nichts mehr, beginnst du wieder von 3 bis 0 zu zählen und erst wenn
du bis 0 gekommen bist, kann man davon ausgehen, dass der Strom auch
wirklich abgeschaltet ist. Selbst dann, wenn es dich kurzfristig noch
mal gebeutelt hat und du erneut bei 3 hast anfangen müssen)