Hallo Forum Welche Zeiten laufen innerhalb einer Statemaschine? Bei einer Abarbeitung der einzelnen Funktionen innerhalb der Statemaschine werden diese innerhalb der Zykluszeit ausgeführt. Die Zykluszeit wird durch die Taktzeit (Quarz) des Prozessors bestimmt. Je mehr Funktionen ausgeführt werden, um so länger dauert es. Wie komme ich aber eine Zeitfunktion? Die Zykluszeit geht viel zu schnell, als Basis ungeeignet, da es sich verändern kann. Was muss ich tun, wenn ich zwei LED unabhängig mit verschiedenen Zeiten Ein- und Ausschalten will? achim
Läubi .. schrieb: > Auch in einer Statemachine kann man warten... warten hört sich immer so nach einer delay-Funktion an, und die werden leider von Anfängern viel zu inflationär genutzt. Auserdem war das imho nicht die Frage des TE. Wenn ich den Beitrag richtig verstehe will er für seine SM einen festen Takt. Momentan ratert er wohl in einer Endlosschleife ungebremst durch die Zustände. Je nach aktuellen Zustand (und dessen Funktionsumfang) ergeben sich damit unterschiedliche Zeiten für einen Durchlauf. Statemachines taktet man genauso wie eine "normale" Mainloop: mit dem Timerinterrupt. Nur so kannst du dir eine feste Zeitbasis erzeugen. Das sollte eigentlich nach "LED blinken lassen" die vierte Übung am Mikrocontroller sein. Die zweite Übung wäre "LED mit Taster blinken lassen". In der dritten Übung lernt man dann, das man ab zwei Tasten und LEDs mit Delays nicht weit kommt und ein neues Konzept braucht.
man hat einen Timer und dessen Zustand : Timercame=true bewirkt eine Zustandsaenderung.
Du hast recht. Im Moment rattert er durch das Programm. Habe gelernt, delay nicht zu verwenden (In Abhängigkeit des Programms). Einer Timerinterrup verwende ich bereits in anderen Sachen. Wie kann ich es aber bei der SM einsetzen? achim
Dein Timerinterrupt ist nichts anderes als eine Eingabe zu deiner State-Machine. Diese Eingabe kann deine State-Machine aus einem sonst evtl statischen Zustand herausholen. Allerdings habe ich bei "rattert er das Programm durch" eher nicht den Eindruck einer StateMachine sondern einer Superloop (bzw. einem Endlichen Automaten erweitert nur aus epsilon-Übergänge, also Wechsel des Zustands ohne Eingabe/Event)
Hallo Wenn ich aus meinem anderen Tread ausgehe, könnte ein Teil so aussehen: #define PRINT_A 0 #define PRINT_B 1 #define PRINT_C 2 void meine_funktion(void) { static int zustand = PRINT_A; switch (zustand) { case PRINT_A: printf("A"); zustand = PRINT_B; break; case PRINT_B: printf("B"); zustand = PRINT_C; break; case PRINT_C: printf("C"); zustand = PRINT_A; break; } } Wenn ich das print durch das Blinken einer LED ersetzen will, brauche ich eine entsprechende Zeitbasis. Nehme ich einen Timer mit 1 MS brauche ich einen Zähler, der bis 999 geht. Bei jedem Durchlauf muss ich überprüfen, ob dieser Wert erreicht wurde. Wenn ja, schalten. Leider ist mir die Einbindung unklar. Hast du ein Beispiel für mich? achim
Die Zeitbasis schafft dir der TimerInterrupt! Du kannst den Interrupt so einstellen (Timer-Konfiguration), dass er z.B. jede Millisekunde "zündet". Wenn er dieses tut, kannst du beispielsweise eine Variable setzen. Diese kannst Du dann einfach in der Statemachine abfragen und schon wartet deine Statemachine auf diese Variable und damit auf den 1-Millisekunden-Impuls. Ich hoffe das hast du gemeint ;) derLars
@Achim Seeger (achims) >Die Zykluszeit geht viel zu schnell, als Basis ungeeignet, da es sich >verändern kann. Richtig. >Was muss ich tun, wenn ich zwei LED unabhängig mit verschiedenen Zeiten >Ein- und Ausschalten will? Den Artikel statemachine lesen und einen Timer benutzen. Wenn man es akademisch korrekt machen will, nimmt man pro LED eine state machine, man kann es aber auch sinnvoll zusammenfassen.
@ Achim Seeger (achims) >ich eine entsprechende Zeitbasis. Nehme ich einen Timer mit 1 MS brauche >ich einen Zähler, der bis 999 geht. Bei jedem Durchlauf muss ich >überprüfen, ob dieser Wert erreicht wurde. Wenn ja, schalten. Ja. >Leider ist mir die Einbindung unklar. Hast du ein Beispiel für mich? Hast du so ein schlechtes Gedächtnis? Den Artikel Multitasking kennst du ja schon, dort ist ein Beispiel drin.
Achim Seeger schrieb: > Wie kann ich es aber bei der SM einsetzen? > achim Wenn ich Dich richtig verstehe, suchst Du so etwas:
1 | while(1) |
2 | {
|
3 | SynchronisiereAufZeitbasis(); |
4 | DoWork(); |
5 | }
|
Das Synchronisieren sieht z.B. so aus: Ein Timer-Interrupt gibt die alle x ms ein Signal und Du wartest in der Funktion
1 | SynchronisiereAufZeitbasis(); |
auf dieses Signal (die CPU kann so lange schlafen). In
1 | DoWork(); |
kannst Du dann machen, was Du willst, z.B. StateMachines ausführen, Zeiten zählen, was auch immer. Der Trick ist, daß man festlegt, daß DoWork einmal alle x ms ausgeführt wird. Man muß aber sicher sein, daß 1. Die Zeitbasis (x ms) schnell genug ist, um die anfallenden Arbeiten zu machen 2. Die Funktion DoWork() unter allen Umständen (!!!) innerhalb der Zykluszeit (x ms) fertig wird und nicht "überzieht".
Ich kenne, in diesem Bereich, nur die klassische SPS. Ob man diese nun als Zustandmaschine oder als Schrittfolgeablauf programmiert - oder sogar, was fast normal ist, als beides - hat doch keinen Einfluss auf den verfügbaren Befehlssatz. Sogar sehr häufig hast Du, beim Übergang von einem Zustand in den anderen, eine zeitliche Abhängigkeit.
Hallo Falk habe es nicht übersehen. In der Tabelle hast du die Zeiten angegeben. Da steht z.B. 10 s für Rot drin. Die Zeit kommt durch den Zähler hinzu. Es steht kein Timer drin. Da fängt die stelle an, die ich nicht verstehe. In dem anderen teil fragst du mit der if .. ab wie hoch der wert ist. In dem anderen Beispiel verwendest du in der while delay 1000. Damit wartet ja die gesamte SM. Bei den anderen Multitasking verwende ich den Interrup der jede ms einen Impuls bringt. Leider ist mir die Einbindung nicht ganz klar achim
@ Achim Seeger (achims) >habe es nicht übersehen. In der Tabelle hast du die Zeiten angegeben. Da >steht z.B. 10 s für Rot drin. Die Zeit kommt durch den Zähler hinzu. Es >steht kein Timer drin. Da fängt die stelle an, die ich nicht verstehe. >In dem anderen teil fragst du mit der if .. ab wie hoch der wert ist. >In dem anderen Beispiel verwendest du in der while delay 1000. Damit >wartet ja die gesamte SM. Nein, IN der statemachine ist KEINERLEI delay() drin, nur in der Hauptschleife. Das ist genau so wie in dem 2. Beispiel zum Multitasking, dort ist auch ein delay in der Hauptschleifen. Das ist ein sehr einfaches Beispiel, damit der Leser sich nicht mit anderen Dingen zusätzlich beschäftigen muss. >Bei den anderen Multitasking verwende ich den Interrup der jede ms einen >Impuls bringt. Leider ist mir die Einbindung nicht ganz klar Versteh ich nicht. Du hast dich mit dem Thema Multitasking ausführlich beschäftigt und bekommst jetzt so eine einfache Sache nicht hin? Das 3. Beispiel im Artikel Multitasking ist deine Lösung! Und anstatt led_blinken() rufst du dort deine Funktion mit der statemachine auf. Wo ist das Problem?
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.