Hallo zusammen
Im Moment bin ich dabei eine stateMachine zu programmieren und hätte es
wie im Bild oben dargestellt vor zu tun. Leider bin ich gerade dabei mir
langsam die Zähne auszubeissen, weil ich nicht weiss, was mein Fehler
ist.
Das Programm macht sich nämlich selbständig und schaltet zwischen den
States ab und zu hin und her. (Debugger)
Es stehen mir 2 Touchkeys zur Verfügung, die mir dabei helben das
Programm in die jeweiligen Zustände zu versetzen.
Touchkey 1 -> TK1
Touchkey 2 -> TK2
Ich habe nach der Initialisierung 3 Zustände, bei denen ich solange
warten möchte, bis ein Touchkey betätigt wird.
Standby, SetTemp und Locked
Die Realisierung habe ich folgendermassen vollzogen, aber ich sehe
leider nicht, wo sich mein Programmier- oder Denkfehler befindet. Ich
hoffe sehr, dass mir hier jemand behilflich sein kann und hoffe, dass
ich alles Notwendige hinzugefügt bzw. beschrieben habe.
Um nicht zu verwirren, habe ich nur das Notwendigste eingefügt
Fragender schrieb:> Das Programm macht sich nämlich selbständig und schaltet zwischen den> States ab und zu hin und her. (Debugger)
Vermutlich hat deine Tastenauswertung eine Macke.
> Es stehen mir 2 Touchkeys zur Verfügung, die mir dabei helben das> Programm in die jeweiligen Zustände zu versetzen.> Touchkey 1 -> TK1> Touchkey 2 -> TK2
Schön. Du mußt die Dinger aber entsprechend auswerten und die Flanke
(berührt/nicht berührt) dekodieren. Dieser Information geht dann an
deine FSM, welche nach Auswertung der Flanke diese löscht. Damit
verhindert man eine Mehrfachauswertung.
> Ich habe nach der Initialisierung 3 Zustände, bei denen ich solange> warten möchte, bis ein Touchkey betätigt wird.> Standby, SetTemp und Locked
Einfach.
Deine Tastenauswertung muss IMMER ausgeführt werden, nicht nur in
bestimmten Zuständen. Diese liefert dann die entprellten und dekodierten
Tastenereignisse. Siehe
https://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
In der FSM werden die Tastenergebnisse ausgewertet und danach GELÖSCHT!
Das fehlt bei dir.
Falk B. schrieb:> Fragender schrieb:>>> Das Programm macht sich nämlich selbständig und schaltet zwischen den>> States ab und zu hin und her. (Debugger)>> Vermutlich hat deine Tastenauswertung eine Macke.>>> Es stehen mir 2 Touchkeys zur Verfügung, die mir dabei helben das>> Programm in die jeweiligen Zustände zu versetzen.>> Touchkey 1 -> TK1>> Touchkey 2 -> TK2>> Schön. Du mußt die Dinger aber entsprechend auswerten und die Flanke> (berührt/nicht berührt) dekodieren. Dieser Information geht dann an> deine FSM, welche nach Auswertung der Flanke diese löscht. Damit> verhindert man eine Mehrfachauswertung.>>> Ich habe nach der Initialisierung 3 Zustände, bei denen ich solange>> warten möchte, bis ein Touchkey betätigt wird.>> Standby, SetTemp und Locked>> Einfach.>> Deine Tastenauswertung muss IMMER ausgeführt werden, nicht nur in> bestimmten Zuständen. Diese liefert dann die entprellten und dekodierten> Tastenereignisse. Siehe>> https://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29>> In der FSM werden die Tastenergebnisse ausgewertet und danach GELÖSCHT!> Das fehlt bei dir.
Guten Morgen Falk
Vielen Dank für deine Hinweise.
Noch bevor ich darauf eingehe, möchte ich vorerst noch eine Frage
stellen, da ich die Vermutung habe, dass das Problem noch irgendwo
anders liegt und zwar ist es so, dass ich beim Programmstart
taskState = STANDBY;
nextTaskState= DEFAULT
oldTaskState = DEFAULT setze.
Im Betrieb dann stelle ich die Temperatur ein und sehe zu wie das Gerät
vor sich hin arbeitet. Die States sind dann:
taskState = LOCKED;
nextTaskState = LOCKED;
oldTaskState = SHOW_SIGN;
Das würde ja soweit passen.
Aber auf einmal stellt das Gerät ab und geht in den Standby Modus.
Die States sind dann wieder wie am Anfang,
taskState = STANDBY;
nextTaskState= DEFAULT
oldTaskState = DEFAULT
obwohl das nicht sein kann, weil ich ja die States vor allem
oldTaskState und nextTaskState im Programm immer auf irgend einem Wert
habe. Da ist doch noch irgend etwas anderes nicht richtig am Laufen.
Fragender schrieb:> obwohl das nicht sein kann, weil ich ja die States vor allem> oldTaskState und nextTaskState im Programm immer auf irgend einem Wert> habe. Da ist doch noch irgend etwas anderes nicht richtig am Laufen.
Falls diese Werte nur bei nach der Initialisierung auftreten können,
könnte es ja sein, das sie wieder Initialisiert wurden.
Hast du schon ausgeschlossen dass dein uC neu startet? (Problem in der
Hardware, Watchdog, Brown Out, etc...)
Fragender schrieb:> if((TOUCHKEY1 <= SWITCHING_THRESHOLD_LOCK_UNPRESSED) &> tscLockButtonPressed)Fragender schrieb:> if((touchkey1>= SWITCHING_THRESHOLD_LOCK_PRESSED) &> !tscLockButtonPressed)
Fragst du da wirklich zwei verschiedene 'TOUCHKEY1' bzw. 'touchkey1' ab?
Gross- und Kleinschreibung spielt bei so gut wie allen Compilern eine
Rolle.
Fragender schrieb:> anders liegt und zwar ist es so, dass ich beim Programmstart> taskState = STANDBY;> nextTaskState= DEFAULT> oldTaskState = DEFAULT setze.
Wozu brauchst du nextTaskState und oldTaskState? Das braucht man im
Normalfall nicht. Ich glaube du machst die Sache zu kompliziert.
> Aber auf einmal stellt das Gerät ab und geht in den Standby Modus.> Die States sind dann wieder wie am Anfang,> taskState = STANDBY;> nextTaskState= DEFAULT> oldTaskState = DEFAULT
Klingt nach einem Reset. Der kann durch die Hardware erzeugt werden
(Brown Out, Störung) oder durch Software (Sprung in nichtvorhandene
ISR), Stack Overflow etc.
Christian U. schrieb:> Hast du schon ausgeschlossen dass dein uC neu startet? (Problem in der> Hardware, Watchdog, Brown Out, etc...)
Hallo Christian
Ja, das vermute ich auch leider irgendwie, dass er selbständig resettet.
Ich habe noch keinen Watchdog implementiert.
Matthias S. schrieb:> Fragender schrieb:>> if((TOUCHKEY1 <= SWITCHING_THRESHOLD_LOCK_UNPRESSED) &>> tscLockButtonPressed)>> Fragender schrieb:>> if((touchkey1>= SWITCHING_THRESHOLD_LOCK_PRESSED) &>> !tscLockButtonPressed)>> Fragst du da wirklich zwei verschiedene 'TOUCHKEY1' bzw. 'touchkey1' ab?> Gross- und Kleinschreibung spielt bei so gut wie allen Compilern eine> Rolle.
Hallo Matthias
Nein, das kommt deshalb, weil mein Code hier so verschoben war und ich
versehentlich Teile des ifs gelöscht habe.
Dann habe ich es von Hand offensichtlich "alles falsch klein"
geschrieben.
Falk B. schrieb:> Fragender schrieb:>>> anders liegt und zwar ist es so, dass ich beim Programmstart>> taskState = STANDBY;>> nextTaskState= DEFAULT>> oldTaskState = DEFAULT setze.>> Wozu brauchst du nextTaskState und oldTaskState? Das braucht man im> Normalfall nicht. Ich glaube du machst die Sache zu kompliziert.
Ich würde es mir auch gerne ersparen, wie wäre es einfacher?
Für jeden Ablauf vom Dauerzustand zB STANDBY oder LOCKED eigene States?
>> Aber auf einmal stellt das Gerät ab und geht in den Standby Modus.>> Die States sind dann wieder wie am Anfang,>> taskState = STANDBY;>> nextTaskState= DEFAULT>> oldTaskState = DEFAULT>> Klingt nach einem Reset. Der kann durch die Hardware erzeugt werden> (Brown Out, Störung) oder durch Software (Sprung in nichtvorhandene> ISR), Stack Overflow etc.
Wie prüfe ich einen Brown Out, oder Sprung in nichtvorhandene ISR?
Ich kann das ja nicht einfach debuggen?
Stefanus F. schrieb:> Ich würde mehrere BEEP Tasks verwenden, die jeweils den> nextTaskState> hard-codiert enthalten. Das wäre einfacher zu überblicken.
Klingt gut, das versuche ich auch mal.
Fragender schrieb:> Christian U. schrieb:>>> Hast du schon ausgeschlossen dass dein uC neu startet? (Problem in der>> Hardware, Watchdog, Brown Out, etc...)>> Hallo Christian>> Ja, das vermute ich auch leider irgendwie, dass er selbständig resettet.> Ich habe noch keinen Watchdog implementiert.
Den braucht man meistens eher nicht!
> Nein, das kommt deshalb, weil mein Code hier so verschoben war und ich> versehentlich Teile des ifs gelöscht habe.> Dann habe ich es von Hand offensichtlich "alles falsch klein"> geschrieben.
Eben sowas macht man NIEMALS! Code NIE abtippen sondern das unveränderte
Original senden. Sei es als Ausschnitt oder meist besser als
Dateianhang. Siehe Netiquette.
>> Wozu brauchst du nextTaskState und oldTaskState? Das braucht man im>> Normalfall nicht. Ich glaube du machst die Sache zu kompliziert.>> Ich würde es mir auch gerne ersparen, wie wäre es einfacher?
Sicher.
> Für jeden Ablauf vom Dauerzustand zB STANDBY oder LOCKED eigene States?
Warum nicht? Die kosten kein Geld, bringen aber gute Struktur.
> Wie prüfe ich einen Brown Out,
Dafür gibt es ein Reset-Register, wo die Reset-Quellen drinstehen.
> oder Sprung in nichtvorhandene ISR?
Das ergibt je nach Compiler meist eine stillstehenden CPU oder Reset.
> Ich kann das ja nicht einfach debuggen?
Warum nicht?
Falk B. schrieb:>>> Für jeden Ablauf vom Dauerzustand zB STANDBY oder LOCKED eigene States?>> Warum nicht? Die kosten kein Geld, bringen aber gute Struktur.
Na dann passe ich das an.
>>> Wie prüfe ich einen Brown Out,>> Dafür gibt es ein Reset-Register, wo die Reset-Quellen drinstehen.
Ich hätte jetzt einfach einmal gemessen, ob der Controller die 3.3V
durchgehend hat um so den Brown Out festzustellen.
Ich habe vorher nämlich im Datenblatt RM0091 schon nachgesehen, aber
eine Brown Out detection hat dieser Controller offensichtlich nicht.
Daher wüsste ich jetzt nicht in welchem Register ich nachsehen muss.
Ich habe den APB peripheral reset register 1 und 2.
>>> oder Sprung in nichtvorhandene ISR?>> Das ergibt je nach Compiler meist eine stillstehenden CPU oder Reset.>>> Ich kann das ja nicht einfach debuggen?>> Warum nicht?
Debuggen schon, aber wie stelle ich fest wo er gerade ist, wenn es die
ISR nicht gibt. Ich kann keinen STOP Punkt hinzufügen dort wo nichts
ist.
Fragender schrieb:>> Dafür gibt es ein Reset-Register, wo die Reset-Quellen drinstehen.>> Ich hätte jetzt einfach einmal gemessen, ob der Controller die 3.3V> durchgehend hat um so den Brown Out festzustellen.
Da muss man aber mit einem Oszi messen.
> Ich habe vorher nämlich im Datenblatt RM0091 schon nachgesehen, aber
Nun ja, bis jetzt kannten WIR deinen Controller nicht, ich hab
instinktiv auf AVR getippt. Klappt halt nicht immer ;-)
> Debuggen schon, aber wie stelle ich fest wo er gerade ist,
Wenn man im Debugger Pause drückt, sieht man, wo die CPU gerade steht.
Falk B. schrieb:> Fragender schrieb:>>>> Dafür gibt es ein Reset-Register, wo die Reset-Quellen drinstehen.>>>> Ich hätte jetzt einfach einmal gemessen, ob der Controller die 3.3V>> durchgehend hat um so den Brown Out festzustellen.>> Da muss man aber mit einem Oszi messen.
Das hätte ich vorgehabt ;)
>>> Ich habe vorher nämlich im Datenblatt RM0091 schon nachgesehen, aber>> Nun ja, bis jetzt kannten WIR deinen Controller nicht, ich hab> instinktiv auf AVR getippt. Klappt halt nicht immer ;-)>>> Debuggen schon, aber wie stelle ich fest wo er gerade ist,>> Wenn man im Debugger Pause drückt, sieht man, wo die CPU gerade steht.
Ich habe im Keil bisher keinen Pausebutton gefunden. :)
Ich danke dir und allen anderen vorerst einmal. Ich werde die paar
Änderungen vornehmen und mich wieder rückmelden, wenn es mir gestattet
ist.
Grüsse
Fragender schrieb:> Ich habe im Keil bisher keinen Pausebutton gefunden. :)
Hast Du einen Debugger oder einen reinen Programmieradapter angesteckt?
Die ARM µCs haben eigentlich hervorragende Debugging Möglichkeiten.
Übrigens ist die Groß- und Kleinschreibung in Deinen Touchkey Funktionen
höchst verdächtig.
Hallo zusammen
Ich habe inzwischen die states abgeändert und für jeden Ablauf eigene
hart programmierte Zustände erstellt.
Auch wenn es so nun funktioniert und das andere wesentlich
unübersichtlicher war, frage ich mich dennoch, warum die andere Version
mit dem taskState = nextTaskState eigentlich nicht funktioniert hat. Die
Zustände müssten demnach trotzdem definierte Zustände sein, ala wenn das
und das der Fall ist nextTaskState = x, wenn das und das nextTaskState =
y.
Warum das Programm dann hin und her springt ist mir noch nicht ganz so
klar.
Wegen des Resets habe ich mal die steigende Flanke der
uC-Versorgungsspannung gemessen und einen entsprechenden Kondensator
gegen GND an den RESET pin angeschlossen. (RC-Glied am NRST)
Mal sehen, ob so der Reset auch von selbst kommt. Das sollte das Problem
eigentlich lösen.
Jim M. schrieb:> Fragender schrieb:>> Ich habe im Keil bisher keinen Pausebutton gefunden. :)>> Hast Du einen Debugger oder einen reinen Programmieradapter angesteckt?> Die ARM µCs haben eigentlich hervorragende Debugging Möglichkeiten.
Programmieradapter ST-Link, über diesen debugge ich das Ganze.