Ich habe hier eine Skizze angefertigt, in der man die Zustände (SCHWARZ), die Ereignisse (ROT), welche die Übergänge auslösen und die Aktionen (BLAU), die dabei ausgeführt werden, sieht. Das hat mir geholfen besser durchzublicken.
Ich habe mir im Internet dieses Video hier angeschaut State Machine - ganz einfach - YouTube und diesen Beispielcode, der im Video vorkommt:
/***********************************
* State machine 4, Vers. 1.0
* Einfache Schaltung mit Taster
* Taster 1 schaltet Zustände rot - gelb - grün - rot
* Der Hobbyelektroniker, 12.06.2018
***********************************/
// Pin - Definitionen
const int PIN_LED_GRUEN = 12;
const int PIN_LED_GELB = 11;
const int PIN_LED_ROT = 10;
const int PIN_TASTE1 = 7;
const int PIN_TASTE2 = 6;
// Zustände //hier muss man dazusagen, dass
const int Z_KEINE = 0;
const int Z_ROT = 1;
const int Z_GELB = 2;
const int Z_GRUEN = 3;
// Variablen für Ereignisse
bool e_taste1;
bool e_taste2;
// Variablen für Zustände
int zustand;
void keine() {
digitalWrite(PIN_LED_GRUEN,LOW);
digitalWrite(PIN_LED_GELB,LOW);
digitalWrite(PIN_LED_ROT,LOW);
zustand = Z_KEINE; // der Zustand wird Z_KEINE, weil Z_Keine aber das gleich ist wie 0 wird er auch 0
e_taste1 = false;
e_taste2 = false;
}
void rot() {
Serial.println("rot");
digitalWrite(PIN_LED_GRUEN,LOW);
digitalWrite(PIN_LED_GELB,LOW);
digitalWrite(PIN_LED_ROT,HIGH);
zustand = Z_ROT;
e_taste1 = false;
}
void gruen() {
Serial.println("gruen");
digitalWrite(PIN_LED_GRUEN,HIGH);
digitalWrite(PIN_LED_GELB,LOW);
digitalWrite(PIN_LED_ROT,LOW);
zustand = Z_GRUEN;
e_taste1 = false;
}
void gelb() {
digitalWrite(PIN_LED_GRUEN,LOW);
digitalWrite(PIN_LED_GELB,HIGH);
digitalWrite(PIN_LED_ROT,LOW);
zustand = Z_GELB;
e_taste1 = false;
}
void ereignisse() {
if (digitalRead(PIN_TASTE1) == LOW) {
e_taste1 = true;
delay(300);
}
if (digitalRead(PIN_TASTE2) == LOW) {
e_taste2 = true;
delay(300);
}
}
void verarbeitung() {
if (e_taste2) keine(); // Taste 2 schaltet sofort aus
if (e_taste1) { // Die Aktion hängt vom aktuellen Zustand ab
switch(zustand) { // Die Variable zustand wird der Reihe nach mit den case verglichen, bei Übereinstimmung wird die Anweisung nach dem Doppelpunkt durchgeführt. Wenn der Vergleich üereinstimme unterbrückt break die weiteren Tests
case Z_KEINE: rot(); break; // Wenn Zustand (0= KEINE) und (
case Z_ROT: gelb(); break;
case Z_GELB: gruen(); break;
case Z_GRUEN: rot(); break;
}
}
}
void setup() {
// Pin's vorbereiten
pinMode(PIN_LED_GRUEN,OUTPUT);
pinMode(PIN_LED_GELB,OUTPUT);
pinMode(PIN_LED_ROT,OUTPUT);
pinMode(PIN_TASTE1,INPUT_PULLUP);
pinMode(PIN_TASTE2,INPUT_PULLUP);
// Ausgangszustand herstellen
digitalWrite(PIN_LED_GRUEN,LOW);
digitalWrite(PIN_LED_GELB,LOW);
digitalWrite(PIN_LED_ROT,LOW);
zustand = Z_KEINE;
e_taste1 = false;
e_taste2 = false;
}
void loop() {
ereignisse();
verarbeitung();
}
Diesen habe ich soweit verstanden. Ich habe dann versucht diesen auf meine Bedürfnisse umzuschreiben. Das ist dabei rausgekommen:
//State Machine
// Pin - Definitionen
const int Relais1 = 8;
const int Relais2 = 9;
const int Relais3 = 10;
const int Relais4 = 11;
const int Bewegungsmelder = 7;
const int EndschalterOben = 6;
const int EndschalterUnten = 5;
//Zustände
const int Z_ArmUnten = 0;
const int Z_ArmNachOben = 1;
const int Z_ArmOben = 2;
const int Z_ArmNachUnten = 3;
//Variablen für Ereignisse
bool e_Empfaenger;
//Variablen für Zustände
int Zustand;
void ArmUnten()
{
Serial.println("Arm ist unten");
digitalWrite(Relais1, HIGH);
digitalWrite(Relais2, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
Zustand = Z_ArmUnten;
e_Empfaenger = false;
}
void ArmNachOben()
{
Serial.println("Arm geht nach oben");
digitalWrite(Relais1, LOW);
digitalWrite(Relais2, LOW);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
Zustand = Z_ArmNachOben;
e_Empfaenger = false;
}
void ArmOben()
{
Serial.println("Arm ist oben");
digitalWrite(Relais1, HIGH);
digitalWrite(Relais2, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
Zustand = Z_ArmOben;
e_Empfaenger = false;
}
void ArmNachUnten()
{
Serial.println("Arm ist unten");
digitalWrite(Relais1, HIGH);
digitalWrite(Relais2, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
e_Empfaenger = false;
}
void Ereignisse()
{
if (digitalRead(Bewegungsmelder) == HIGH || digitalRead(EndschalterOben) == HIGH || digitalRead(EndschalterUnten) == HIGH) { // ich weiß leider nicht wie ich das anders lösen soll
e_Empfaenger = true;
}
}
void Verarbeitung()
{
if (e_Empfaenger) // Wenn einer der Empfaenger ausgelöst hat
{
switch (Zustand)
{
case Z_ArmUnten: ArmNachOben(); break;
case Z_ArmNachOben: ArmOben(); break;
case Z_ArmOben: ArmNachUnten(); break;
case Z_ArmNachUnten: ArmUnten; break;
}
}
}
void setup() {
// Pin's vorbereiten
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
pinMode(Bewegungsmelder, INPUT);
pinMode(EndschalterOben, INPUT_PULLUP);
pinMode(EndschalterUnten, INPUT_PULLUP);
//Ausgangszustand herstellen
digitalWrite(Relais1, HIGH);
digitalWrite(Relais2, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
Zustand = Z_ArmUnten;
e_Empfaenger = false;
// hier fehlt noch ein der Pausenzeitgeber als Empfänger
}
void loop()
{
Ereignisse(); // Ereignisse werden abgefragt
Verarbeitung(); // Anhand der Ereignisse werden die einzelnen Funktionen abgerufen
}
Ich habe keine Ahnung wie ich den Pausenzeitgeber, der als Ereignis dienen soll um vom Zustand "Arm oben" in den Zustand "Arm nach unten" zu wechseln bewerkstellige. Kann mir da bitte jemand helfen?
@paulpaulson: Danke für den Code, den Du mir geschickt hast, leider verstehe ich da vieles nicht, sodass mir das Umbauen des Codes aus dem Video lieber war. Ich verstehe bei dem code zum Beispiel nicht wo die Ereignisse Platz finden sollen, die den Übergang zwischen den Zuständen auslösen. Auch bei dem Sketch den ich umgeschrieben habe war das die große Schwierigkeit.
void Ereignisse()
{
if (digitalRead(Bewegungsmelder) == HIGH || digitalRead(EndschalterOben) == HIGH || digitalRead(EndschalterUnten) == HIGH) { // ich weiß leider nicht wie ich das anders lösen soll
e_Empfaenger = true;
}
}
Ich habe jetzt einfach aus allen möglichen Empfängern, ein Ereignis gemacht, bin mir aber nicht ganz sicher ob das so funktioniert.
P.S.: Wie Ihr seht bin ich nicht so der Crack, ich habe alles gegeben, aber jetzt bin ich reif für die Heia:D. Ich würde mich sehr über Eure Hilfe freuen! Gute Nacht.