Hallo, Ich möchte gerne die Entprellroutine von Herrn Dannegger besser verstehen. Ich habe nichts davon wenn ich einfach den Code rauskopiere und nicht weiß was da passiert. Habe ich richtig verstanden dass: 1. Tasten beim Drücken prellen = Die Taste schaltet nicht einfach nur ein sondern schaltet ein und ständig aus im ms Bereich bis der Kontakt letztendlich hergestellt ist. Je nach Taster mehrmals ... und verschieden lang. 2. Um falschen Einschalt-Folgen zu entgehen lesen wir nach dem ersten Einschaltvorgang den Zustand der Taste ein und warten bis zum nächsten Zustand. Ist dieser entgegengesetzt machen wir das ganze Spiel nochmal sodass wir idealerweise die Folge 1 0 1 0 haben. Diesen ganzen Ablauf versuchen wir in möglichst unter 20ms hinzubekommen und zwar OHNE delays. Deswegen dann auch die Interrupts die den µC nicht "anhalten". Das würde dann praktisch bedeuten das wir einen Taster 4 mal innerhalb z.b. 20ms abfragen und bei einer Folge von 1 0 1 0 einen Tastvorgang registrieren. - Sind meine Überlegungen so richtig oder habe ich es nicht ganz verstanden? - Herr Dannegger benutzt 10ms für die gesamte Abfrage wenn ich mich nicht täuschen sollte. Ist das ein vernünftiger Richtwert den man ohne weiteres nutzen kann? Danke schonmal für hilfreiche Beiträge! Gruß H. M.
hansi mausi schrieb: > Ich habe nichts davon wenn ich einfach den Code rauskopiere und nicht > weiß was da passiert. In diesem Fall ist das ausnahmsweise OK. Die Funktion ist ziemlich trickreich und es ist keine Schande, wenn man die nicht gleich durchschaut. > 1. Tasten beim Drücken prellen = Die Taste schaltet nicht einfach nur > ein sondern schaltet ein und ständig aus im ms Bereich bis der Kontakt > letztendlich hergestellt ist. Je nach Taster mehrmals ... und > verschieden lang. Das hast du richtig. > 2. Um falschen Einschalt-Folgen zu entgehen lesen wir nach dem ersten > Einschaltvorgang den Zustand der Taste ein und warten bis zum nächsten > Zustand. Ist dieser entgegengesetzt machen wir das ganze Spiel nochmal > sodass wir idealerweise die Folge 1 0 1 0 haben. Diesen ganzen Ablauf > versuchen wir in möglichst unter 20ms hinzubekommen und zwar OHNE > delays. Nö. Im Timer Interrupt wird einfach nur ein Zähler hochgezählt, wenn der jetzige Zustand des Input Pins identisch ist mit dem vorhergehenden. Ist er das nicht, wird der Zähler auf 0 zurückgesetzt. Vom Prinzip her passiert da für einen einzelnen Pin folgendes (aber wie gesagt: nur vom Prinzip, die tatsächliche Implementierung ist viel trickreicher)
1 | uint8_t keyState; |
2 | uint8_t keyPressed; |
3 | uint8_t oldState; |
4 | uint8_t pinCount; |
5 | |
6 | ISR( ... ) |
7 | {
|
8 | uint8_t newState; |
9 | |
10 | newState = PIN & ( 1 << bewusster_Pin ); |
11 | |
12 | if( newState != oldState ) |
13 | pinCount = 0; |
14 | else
|
15 | pinCount++; |
16 | |
17 | oldState = newState; |
18 | |
19 | if( pinCount == 4 ) { |
20 | if( newState == 1 && keyState == 0 ) |
21 | keyPressed = TRUE; |
22 | keyState = newState; |
23 | }
|
24 | }
|
Ich habe das nicht getestet aber für einen einzelnen Pin müsste das logikmässig in etwa dem entsprechen, was die veröffentlichte PeDa Lösung auch macht. Nur dass die PeDa Lösung das ganze trickreicherweise für maximal 8 Tasten gleichzeitig macht und es nicht 8 Variablen gibt, sondern das ganze Bitweise in verschiedenen Variablen organisiert ist :-) > - Herr Dannegger benutzt 10ms für die gesamte Abfrage wenn ich mich > nicht täuschen sollte. Ist das ein vernünftiger Richtwert den man ohne > weiteres nutzen kann? Ja, kann man. Aber die 10ms sind nicht in Stein gemeisselt. Wenn du sowieso schon eine Timer ISR hast, die alle 8ms aufgerufen wird, oder alle 15ms, oder alle 20ms, dann ist das auch in Ordnung und du kannst den Entprellcode da mit reinnehmen. Wie gesagt: Die PeDa Entprellung ist so trickreich, dass es i.O. ist, sie nicht zu verstehen. Hauptsache sie funktioniert. Und das tut sie ausgezeichnet.
vielen Dank für die nützlichen Hinweise! Braucht sich also keiner schämen wenn er den Code nicht ganz durchschaut... dachte schon ich bin alleine damit :O). Gruß H.M.
@Buchegger Kannst Du mir Bitte sagen was Dein Code hier genau tut? if( newState == 1 && keyState == 0 ) keyPressed = TRUE; keyState = newState; beim 2ten Durchlauf würde diese Bedingung doch nicht mehr wahr werden oder? Dein keystate ist ja praktisch immer dann eine 1. Wo würde dieser Wert denn wieder zurückgesetzt werden und welche Rolle spielt er hier? Gruß H.M.
hansi mausi schrieb: > @Buchegger > > > Kannst Du mir Bitte sagen was Dein Code hier genau tut? > > if( newState == 1 && keyState == 0 ) > keyPressed = TRUE; > keyState = newState; > > beim 2ten Durchlauf würde diese Bedingung doch nicht mehr wahr werden > oder? Genau das ist der Sinn der Sache. Einen 0->1 Übergang zu erkennen > Dein keystate ist ja praktisch immer dann eine 1. Wo würde dieser Wert > denn wieder zurückgesetzt werden und welche Rolle spielt er hier? Irgendwann (nämlich wenn du den Taster wieder löslässt) wird newState wieder 0. keyState erhölt diese 0 dann durch Zuweisung von newState keyState = newState;
Ich habe den Code jetzt bei mir folgendermaßen eingebaut ISR(TIMER2_OVF_vect) { uint8_t newState; //nur so funktioniert bei mir der Schalter newState = !(PIND & (1 << PD2)); if( newState != oldState ) pinCount = 0; else pinCount++; oldState = newState; if( pinCount == 4 ) { if( newState == 1 && keyState == 0 ) { //keyPressed = 1; PORTC ^= (1 << PC5); } //nachdem ich keystate aus dem IF genommen hab funzt der Schalter keyState = newState; } } Soweit klappt alles wunderbar. LED blinkt bei jedem Tastendruck. Prellabfrage bei 10ms. Werde mal versuchen das nun auf nen LCD zu bringen. Da kann man dann noch besser sehen wie oft der tatsächlich gezählt hat. Danke für die Hilfe!! Gruß H.M.
Richtiger wäre es aber die Tasten anders auszuwerten. Nicht ein Tastendruck , sondern das loslassen der Taste führt besagte Aktionen durch. Ebenso ob die gedrückte Taste auch die losgelassene war.
>Nicht ein Tastendruck , sondern das loslassen der Taste führt besagte >Aktionen durch. 1.) was soll das bringen? 2.) Ist das Verhalten für den Anwender sehr unangenehm. Ich empfinde das immer als seltsam, wenn man eine gedrückte Taste erst loslassen muss, um eine Reaktion zu erreichen. Gefällt mir nicht.
>Wie gesagt: Die PeDa Entprellung ist so trickreich, dass es i.O. ist, >sie nicht zu verstehen. Ähmm, ohne die Funktion jetzt angeschaut zu haben: die Entprellung eines Tasters bzw. mehrerer Taster sind doch wirklich absolute Basics. Ich brauche halt irgend eine Zeit. Woher ich die nehme, ist völlig wurscht. Und dann warte ich halt, bis ein Eingang für mindestens z.B. 10ms lang true ist. So mache ich das seit Jahren, und ich verstehe jetzt nicht, was daran auch nur im Entferntesten kompliziert sein soll. Werde mir die berühmte Dannegger-Funktion doch mal kurz anschauen, wenn ich Zeit habe ;-)
High Performer schrieb: > Ähmm, ohne die Funktion jetzt angeschaut zu haben: die Entprellung eines > Tasters bzw. mehrerer Taster sind doch wirklich absolute Basics. Was viele aber nicht einsehen wollen. Z.B. bei unserem teuren Kaffeautomat prellt der Drehgeber zur Mengeneinstellung wie Sau. > Ich > brauche halt irgend eine Zeit. Woher ich die nehme, ist völlig wurscht. Ist es eben nicht. Am nebenwirkungsfreiesten ist ein Timerinterrupt zur Tastenabfrage. Dann geht nirgends CPU-Zeit verloren und Tastendrücke können sogar gemerkt werden. Ohne Timerinterrupt muß beim Drücken oder Loslassen (an den Flanken) die Entprellzeit verwartet werden. Ist nicht schön, aber bei einfachen Programmen oftmals tolerabel. > Und dann warte ich halt, bis ein Eingang für mindestens z.B. 10ms lang > true ist. Heißt das, solange jemand auf eine Taste drückt, werden der Mainloop ständig 10ms geklaut? > So mache ich das seit Jahren, und ich verstehe jetzt nicht, > was daran auch nur im Entferntesten kompliziert sein soll. Ich behaupte mal, jeder kennt mindestens ein kommerzielles Gerät mit schlecht funktionierender Entprellung. Peter
High Performer schrieb: >>Wie gesagt: Die PeDa Entprellung ist so trickreich, dass es i.O. ist, >>sie nicht zu verstehen. > > Ähmm, ohne die Funktion jetzt angeschaut zu haben Tu das. Die Funktionalität ist nicht schwer, aber die Art und Weise wie sie implementiert ist, ist trickreich. Für einen C-Anfänger ist das mit Sicherheit nicht leicht zu durchschauen. Ich halte mich nicht für einen Anfänger, aber ich habe auch eine gute Stunde die 5 Zeilen Code studiert und mit Beispielen durchgespielt, bis ich verstanden habe wie das funktioniert. Der Knackpunkt ist der 'vertikale Zähler'. Hat man den erst mal erkannt, fällt alles andere von selbst in die "richtige Schublade".
hansi mausi schrieb: > Ich möchte gerne die Entprellroutine von Herrn Dannegger besser > verstehen. Hallo, um welche routine handelt sich? wo finde ich die Entprellroutine von Herrn Dannegger? Gruß
Chris schrieb: > hansi mausi schrieb: >> Ich möchte gerne die Entprellroutine von Herrn Dannegger besser >> verstehen. > > Hallo, um welche routine handelt sich? wo finde ich die Entprellroutine > von Herrn Dannegger? http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
@ high performer die Art und Weise WIE eine Entprellung funktionieren soll kann man recht gut dem Forum sowie den Tutorials entnehmen... diese allerdings dann erfolgreich und effektiv umzusetzen ist eine Andere. Herr Dannegger hat mit seiner Lösung mit Sicherheit hohe Maßtäbe gesetzt. Es macht jedoch wie eingangs erwähnt nicht wirklich Sinn nur rauszukopieren. Mir hat als Anfänger die Lösung von Herrn Buchegger sehr gut gefallen da "leicher" nachvollziehbar. Wenn wir Anfänger mal weiter sind mit Registern und dem Arbeiten auf BIT-Ebene werden mit Sicherheit auch die PEDA Lösung besser verstehen. Bis dahin heißt es erstmal alles zum Laufen bringen und zwar mit einem Code den man selbst auch versteht. btw. die von mir mit einer geschweiften Klammer abgeänderte Buchegger Lösung funktioniert übrigens perfekt!!! Danke nochmal für diese zunächst "1-Tasten-Lösung" Gruß H.M.
hansi mausi schrieb: > rauszukopieren. Mir hat als Anfänger die Lösung von Herrn Buchegger sehr > gut gefallen da "leicher" nachvollziehbar. Ich denke du hast das misverstanden oder ich habe es schlecht formuliert. Diese 'Lösung' hab ich nur schnell zusammengestrickt (noch nicht mal gtestet) um das grundsätzliche Prinzip der PeDa Entprellung zu zeigen. Beide funktionieren nach dem gleichen Schema, nur ist die PeDa Lösung der präsentierten, was Eleganz angeht, haushoch überlegen. Du kannst und sollst auch die PeDa Lösung nehmen. Es ist ausnahmsweise völlig in Ordnung, wenn du die den Inhalt in der ISR nicht verstehst. Das ist nichts worüber man sich Kopfzerbrechen machen muss.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.