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);
}
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.htmlAVR 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"
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.
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.
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
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.