Hallo, folgende Situation, ich habe z.B drei Taster am Mikrocontroller , und möchte 7 Zustände darstellen: 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 folgender Pseudocode: WENN TASTER 1 DANN ZUSTAND 1 WENN TASTER 2 DANN ZUSTAND 2 WENN TASTER 1 UND TASTER 2 DANN ZUSTAND 3 WENN TASTER 3 DANN ZUSTAND 4 WENN TASTER 1 UND TASTER 3 DANN ZUSTAND 5 WENN TASTER 2 UND TASTER 3 DANN ZUSTAND 6 WENN ALLE TASTER DANN ZUSTAND 7 WENN KEIN TASTER und VORHER IRGENDEIN TASTER GEDRÜCKT DANN ZUSTAND 0 zB wenn drei Taster gleichzeitig gedrückt sind und ich die ersten beiden Taster loslasse, soll das Programm in Zustand 4 gehen. wie kann man das geschickt im C Code zB für einen AVR verarbeiten.
Ich würde das folgendermaßen realisieren: zustand = taster1 + 2*taster2 + 4*taster3 Hierbei hat tasterx den Wert 0, wenn Taster nicht gedrpckt ist und denr Wert 1 wenn der Taster gedrückt ist. Beachte jedoch, dass die Taster ggf. noch entprellt werden müssen.
Ich habe bereits ne Funktion taster1(), taster2(),taster3() mit return 1 bei gedrückt und return 0 bei losgelassen. Wie kann ich das noch machen, dass die if Routinen nur einmal ausgeführt werden und der Zustand 0 nur einmal ausgeführt wird wenn vorher Zustand 1-7 ausgeführt war. if (Zustand==0) { fuhereFunktionAus(0); } if (Zustand==1) { fuhereFunktionAus(0); }
> if (Zustand==0) > { > fuhereFunktionAus(0); > > } > > else if (Zustand==1) > { > fuhereFunktionAus(0); > > }
AVR schrieb im Beitrag #3376346: > Wie kann ich das noch machen, dass die if Routinen nur einmal ausgeführt > werden Mach das am besten mit switch case: http://www.c-howto.de/tutorial-verzweigungen-switch-case.html AVR schrieb im Beitrag #3376346: > und der Zustand 0 nur einmal ausgeführt wird wenn vorher Zustand > 1-7 ausgeführt war. Es gibt nur 8 Zustände, oder? Dann ist zwingend vor Zustand 0 immer Zustand 1-7 aktiv gewesen. Oder habe ich das falsch verstanden?
Ja das hast du richtig verstanden, aber wenn ich das mit switch case mache kann kann ich nur auf Zustand abfragen. und falls ich gedrückt halte, wird das Programm ständig die Anweisung ausführen, das soll ja eben verhindert werden oder sehe ich das falsch switch(Zustand) { case 0: fuehreFunktionAus(0); break; case 1: fuehreFunktionAus(0); break; ... ... }
Stichwort hast Du ja selber vorgegeben das nennt sich Statemachine. Üblicherweise definiert man die Zustände via defines und wertet das in einem switch/case aus. Wenn zu den Übergängen noch Sonderbehandlungen kommen bzw. das flexibel werden soll schreibst Du in die cases die Funktionen für den Übergang.
AVR schrieb im Beitrag #3376303: > Hallo, folgende Situation, ich habe z.B drei Taster am Mikrocontroller , > und möchte 7 Zustände darstellen > [...] Schon falsch. Du hast nicht erkannt, daß du eigentlich acht Zustände darstellen willst. > WENN KEIN TASTER Aha, da isser ja. > und VORHER IRGENDEIN TASTER GEDRÜCKT DANN ZUSTAND 0 Hier verläßt du das Gebiet der boolschen Logik, denn du führst hier eine temporale Komponente ein. Nämlich ein Bit, in dem steht, ob "zuvor" eine Taste gedrückt wurde. Da wird es das erste Mal spannend bei der Definition von "zuvor". Das kann nämlich bedeuten "irgendwann zuvor" oder "irgendwann seit dem letzten ZUSTANDx" (wahrscheinlich ist wohl ZUSTAND0 gewünscht). Und natürlich muß du dir unabhängig von der Definition dieses "zuvor" erstens das "zuvor" merken und zweitens als zusätzliches Eingangsbit deiner Statemachine verwenden. Die bekommt dadurch zwingend 16 statt 8 Zustände. Das hast du wohl nicht erkannt...
Was hat denn die ZusätzlichE Übergangsbedingung damit zu tun, dass man aufeinmal 16 Zustände bekommt. Es gibt nach wie vor 8 Zustände. Hier kurz mal was geschrieben was mir auf die schnelle eingefallen ist. char StatusVariable=0; switch(Zustand) { case 0: if(StatusVariable !=0){ fuehreFunktionAus(0); } StatusVariable=0 break; case 1: if (StatusVariable !=1){ fuehreFunktionAus(1); } StatusVariable=1; break; ... ..... case 7: if (StatusVariable !=7){ fuehreFunktionAus(6); } StatusVariable=7; break; }
avr avr schrieb: > Was hat denn die ZusätzlichE Übergangsbedingung damit zu tun, dass man > aufeinmal 16 Zustände bekommt. Es gibt nach wie vor 8 Zustände. betrachtet man das ganze streng als Zustandsautomat, so hätte man tatsächlich 16 Zustände, die von dem Zustand er Taster (8 Zustände) sowie der Statusvariable (2 Zustände) abhängen, also 2*8=16 Zustände Praktisch gesehen würde ich es jedoch auch so realisieren wie "avr avr"
AVR schrieb im Beitrag #3376303: > zB wenn drei Taster gleichzeitig gedrückt sind Dazu ist kein Mensch aus der Sicht eines MC in der Lage. Selbst innerhalb 50ns ist nicht garantiert gleichzeitig. Aber es gibt Lösungen dafür. Die Einschränkung dabei ist, das gleichzeitig muß innerhalb eines festgelegten Zeitfensters oder bis zu Loslassen einer Taste erfolgen. Beitrag "Re: Universelle Tastenabfrage"
:
Bearbeitet durch User
Hier wieder der Verweis auf die Routinen zum Taster entprellen: http://www.mikrocontroller.net/articles/Entprellung Bei den Komfortroutinen kann man die Tasten hervorragend mit einer Maske abfragen! Mir stellt sich nur die Frage, ob man immer in den gewünschten Zustand kommt, da man ja nie die gewünschten Tasten synchron drücken kann, es sei den die Taktfrequenz des uC ist niedrig genug.
Das Entprellen ist schon mit eingebaut es geht um den Zustandsautomat. Das Ziel ist auch nicht das synchrone Drücken. Du kannst die Tasten nacheinander drücken zb. hälst du einen Taster gedrückt und drückst dabei den zweiten, dann soll er in den dazugehörigen Zustand übergehen.
avr avr schrieb: > Das Entprellen ist schon mit eingebaut es geht um den Zustandsautomat. Dann läßte eben die 2 Zeilen weg.
Zeichne Dir erstmal auf einem Blatt Papier alle Deine Zustände und deren Transitionen auf. Dann überlege Dir welche Zustände Sinn ergeben und wie deren Zusammenhänge sind. So wie das bis jetzt verstehe hast Du nur bestimmte Tastendrücke die in einen bestimmten Zustand führen sollen alle anderen sind Zustand0 = default.
Lies Dir nochmal Deinen ersten Post durch, Du bist doch der TE ? Was fällt Dir dabei auf ?
avr avr schrieb: > Was hat denn die ZusätzlichE Übergangsbedingung damit zu tun, dass man > aufeinmal 16 Zustände bekommt. Es gibt nach wie vor 8 Zustände. Ob man das als zusätzliche Übergangsbedingung auffaßt oder als Erweiterung des Zustandsraums spielt von der Funktion her keine Rolle, sehr wohl aber für die Implementierung. Die Variante mit den 16 Zuständen läßt nämlich eine um Längen fixere Implementierung per Lookup-Tabelle zu, die sich obendrein noch durch eine konstante Laufzeit auszeichnet, was manchmal auch nicht ganz unwichtig ist. Und, last but not least, es schreibt sich auch noch viel schneller als endlose switch..case- oder if..elseif..else-Wüsten.
avr avr schrieb: > Du kannst die Tasten nacheinander drücken zb. hälst du einen Taster > gedrückt und drückst dabei den zweiten, dann soll er in den > dazugehörigen Zustand übergehen. Und woher weiß der Controller, dass er nicht noch auf den dritten Taster warten soll? Auf den zweiten wartet er ja wohl auch ... Oder werden bei dem drücken von zwei Tastern immer alle damit auszulösenden Funktionen für jede Kombination ausgeführt? Beschreib doch mal genau, was Du überhaupt vor hast. Siehe Netiquette - vor allem Punkt 3 Gruß Jobst
Nimm 'ne ordentliche Tastenerkennung, z.B. die von P. Dannegger und Google dann mal nach boolescher Algebra.
Die von mir gepostete Lösung hab ich nun getestet, sie Funktioniert. Es soll folgendermaßen Funktionieren. Es gibt 3 Taster die 8 Zustände darstellen. Jeder Zustand hat eine Funktion einmal auszuführen. zB: Es wird der 1.Taster gedrückt gehalten und dabei der zweite gedrückt, dann springt das Programm in Zustand 3. In diesem Zustand wird eine beliebige Funktion nur einmal ausgeführt. Wenn also die beiden Taster weiterhin gedrückt gehalten werden soll die Funktion nicht nochmal ausgeführt werden. Nun wird sagen wir mal Taster 2 losgelassen, dann landet man im Zustand 1. Es passiert das Gleiche wie in allen Zuständen, eine beliebige Funktion wird einmalig ausgeführt. Der Zustand 0 soll nur erreicht werden, wenn vorher irgendein oder mehrere Taster gedrückt waren.
"Amateur (Gast)" Toller Beitrag, Ich hab doch bereits geschrieben, dass ich eine Tastenerkennung mit Entprellung habe, mittlerweile funktionieren die Zustände auch.
Alle 20 ms ausführen:
1 | StateOld = State; |
2 | State = (KeyC<<2) | (KeyB<<1) | (KeyA<<0); |
3 | |
4 | if (StateOld != State) { |
5 | Action(State) |
6 | };
|
wobei die int-Variablen KeyA, KeyB, KeyC die (ggf. entprellten) Tastenzustände enthalten: KeyX = 0(1) wenn Taster X up(down)
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.