Forum: Mikrocontroller und Digitale Elektronik Zeiten innerhalb Statemaschine


von Achim S. (achims)


Lesenswert?

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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Auch in einer Statemachine kann man warten...

von Le X. (lex_91)


Lesenswert?

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.

von flopp (Gast)


Lesenswert?

man hat einen Timer und dessen Zustand : Timercame=true bewirkt eine 
Zustandsaenderung.

von Achim S. (achims)


Lesenswert?

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

von Maxx (Gast)


Lesenswert?

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)

von Achim S. (achims)


Lesenswert?

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

von derLars (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@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.

von Falk B. (falk)


Lesenswert?

@ 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.

von Bronco (Gast)


Lesenswert?

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".

von amateur (Gast)


Lesenswert?

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.

von Achim S. (achims)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@ 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
Noch kein Account? Hier anmelden.