Hallo liebe community,
Ich habe vor einiger Zeit die Arbeit "Serienmodell" ( Link zum Video: https://youtu.be/0sWcb4pMzpc ) gemacht und möchte sie bald in einer Ausstellung zeigen.
Wenn man den Reed- Schalter einer Figur mit einem Magneten auslöst, dann streicht diese der anderen Figur mit einem grünen Ast über die Schulter. Dabei löst ein Magnet im grünen Ast den Reed- Schalter in der Schulter der der anderen Figur aus, die daraufhin wieder die Bewegung ausführt usw.- in Dauerschleife.
Ihr findet im Anhang eine Skizze des Prinzips der verwendeten State Machine (Skizze State Machine). Auf die Hardware beider Figuren im Video ist dieser Sketch hochgeladen:
//State Machine - Serienmodell
// Pin - Definitionen
const int Relais1 = 8;
![State Machine Skizze|353x500](upload://ifYPzScHdchACUaAXZJIl4Ki1bo.jpeg)
![State machine Skizze 2|690x487](upload://jzb3o2tx5nsX8XPxo7jMliuTEOr.jpeg)
const int Relais2 = 9;
const int Relais3 = 10;
const int Relais4 = 11;
const int ReedSchalter = 7;
const int EndschalterOben = 13;
unsigned long Pausenzeitgeber;
const int EndschalterUnten = 12;
//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_ReedSchalter;
bool e_EndschalterOben;
bool e_Pausenzeitgeber;
bool e_EndschalterUnten;
//Variablen für Zustände
int Zustand;
void ArmUnten()
{
Serial.println("Arm unten");
digitalWrite(Relais2, HIGH);
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais1, HIGH);
Zustand = Z_ArmUnten;
e_EndschalterUnten = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
}
void ArmNachOben()
{
Serial.println("Arm geht nach oben nach Anfangspause");
delay(20000); // Anfangspause// erst waren es 10000, das war mir ein bisschen zuschnell! 15000 sind okay aber vielleicht immer noch ein bisschen zu schnell
digitalWrite(Relais1, LOW); // Das muss immerso herum
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais2, HIGH); // hier stehen, sonst kommt es zu einer Störung!
Zustand = Z_ArmNachOben;
e_EndschalterUnten = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
}
void ArmOben()
{
Serial.println("Arm ist oben");
digitalWrite(Relais1, HIGH);
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais2, HIGH);
Zustand = Z_ArmOben;
e_EndschalterUnten = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
Pausenzeitgeber = millis();
}
void ArmNachUnten()
{
Serial.println("Arm geht nach unten");
digitalWrite(Relais2, LOW);
delay(500); //Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais1, HIGH);
Zustand = Z_ArmNachUnten;
e_EndschalterUnten = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
}
void Ereignisse()
{
if (digitalRead(ReedSchalter) == LOW) { // Reedschalter schaltet GND und ist INPUT_PULLUP
e_ReedSchalter = true;
}
if (digitalRead(EndschalterOben) == LOW)
{
e_EndschalterOben = true;
// hier darf: Pausenzeitgeber = millis(); nicht stehen, weil der Schalter ja gedrückt bleibt!!!
}
if (millis() - Pausenzeitgeber > 4000 && millis() - Pausenzeitgeber < 4500) // erst waren es 6000 und 6500, die Pause ist auf jeden Fall zu lang, Messung hat ergeben, dass 4000 ganz gut wären
{
e_Pausenzeitgeber = true;
}
if (digitalRead(EndschalterUnten) == LOW )
{
e_EndschalterUnten = true;
}
}
void Verarbeitung()
{
if (e_ReedSchalter)
{
switch (Zustand)
{
case Z_ArmUnten: ArmNachOben(); break;
}
}
if (e_EndschalterOben)
{
switch (Zustand)
{
case Z_ArmNachOben: ArmOben(); break;
}
}
if (e_Pausenzeitgeber)
{
switch (Zustand)
{
case Z_ArmOben: ArmNachUnten(); break;
}
}
if ( e_EndschalterUnten)
{
switch (Zustand)
{
case Z_ArmNachUnten: ArmUnten(); break;
}
}
}
void setup() {
// Schnittstelle für den seriellen Monitor
Serial.begin(9600);
// Pin's vorbereiten
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
pinMode(ReedSchalter, INPUT_PULLUP);
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_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
e_EndschalterUnten = false;
}
void loop()
{
Ereignisse(); // Ereignisse werden abgefragt
Verarbeitung(); // Anhand der Ereignisse werden die einzelnen Funktionen abgerufen
}
Für die Ausstellung ist es jedoch erwünscht, dass die Bewegung nicht pausenlos durchläuft.
Ich will, dass man die Bewegung der einen Figur durch einen Taster auslöst und die beiden Figuren dann 5- mal abwechselnd gegenseitig über ihre Körper streichen.
Meine Idee ist Folgende:
Ich nehme einen weiteren Zustand mit in die StateMachine und zwar den Zustand void Pause() (siehe Skizze State Machine 2).
Wenn der Taster gedrückt wird, wird das Ereignis e_Taster true und die Variable AnzahlZustandsaenderungen wird 0 gesetzt. Bei jedem Wechsel von einem Zustand in einen Anderen erhöht sich die Variable AnzahlZustandsaenderrungen um 1. Nach 5 Durchgängen sollte die Variable AnzahlZustansaenderungen dann über 20 sein und ein Wechsel von void Pause() zu void ArmNachOben ist nur noch durch erneutes Drücken des Tasters möglich.
Was haltet Ihr von der Idee? Fällt Euch eine bessere Möglichkeit ein?
Ihr findet im Anhang eine Skizze zur Veränderung der State Machine (Skizze State Machine 2). Hier ist der Sketch, der meine Idee beinhaltet. Wenn Ihr Fehler erkennt lasst es mich bitte wissen.
//State Machine_Sender_Versuch
// Pin - Definitionen
const int Relais1 = 8;
const int Relais2 = 9;
const int Relais3 = 10;
const int Relais4 = 11;
const int Taster = 6; // Taster
const int ReedSchalter = 7;
const int EndschalterOben = 13;
unsigned long Pausenzeitgeber;
const int EndschalterUnten = 12;
int AnzahlZustandsaenderungen;
//Zustände
const int Z_ArmUnten = 0;
const int Z_Pause = 1;
const int Z_ArmNachOben = 2;
const int Z_ArmOben = 3;
const int Z_ArmNachUnten = 4;
//Variablen für Ereignisse
bool e_ReedSchalter;
bool e_EndschalterOben;
bool e_Pausenzeitgeber;
bool e_EndschalterUnten;
bool e_Taster; // Taster
bool e_AnzahlZustandsaenderungen; // Anzahl der Zustandsänderungen
//Variablen für Zustände
int Zustand;
void ArmUnten()
{
Serial.println("Arm unten");
digitalWrite(Relais2, HIGH);
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais1, HIGH);
Zustand = Z_ArmUnten;
e_EndschalterUnten = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
AnzahlZustandsaenderungen + 1;
}
void Pause()
{
Serial.println("Pause");
Zustand = Z_Pause;
}
void ArmNachOben()
{
Serial.println("Arm geht nach oben nach Anfangspause");
delay(20000); // Anfangspause// erst waren es 10000, das war mir ein bisschen zuschnell! 15000 sind okay aber vielleicht immer noch ein bisschen zu schnell
digitalWrite(Relais1, LOW); // Das muss immerso herum
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais2, HIGH); // hier stehen, sonst kommt es zu einer Störung!
Zustand = Z_ArmNachOben;
e_EndschalterUnten = false;
e_Taster = false;
e_AnzahlZustandsaenderungen= false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
AnzahlZustandsaenderungen + 1;
}
void ArmOben()
{
Serial.println("Arm ist oben");
digitalWrite(Relais1, HIGH);
delay(500); // Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais2, HIGH);
Zustand = Z_ArmOben;
e_EndschalterUnten = false;
e_Taster = false;
e_AnzahlZustandsaenderungen= false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
Pausenzeitgeber = millis();
AnzahlZustandsaenderungen + 1;
}
void ArmNachUnten()
{
Serial.println("Arm geht nach unten");
digitalWrite(Relais2, LOW);
delay(500); //Software- Verzögerung zum Beheben der Störung
digitalWrite(Relais1, HIGH);
Zustand = Z_ArmNachUnten;
e_EndschalterUnten = false;
e_Taster = false;
e_AnzahlZustandsaenderungen = false;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
AnzahlZustandsaenderungen + 1;
}
void Ereignisse()
{
if (digitalRead(Taster) == LOW) // Taster schaltet GND und ist INPUT_PULLUP
{
e_Taster = true;
AnzahlZustandsaenderungen = 0;
}
if (digitalRead(ReedSchalter) == LOW) // Reedschalter schaltet GND und ist INPUT_PULLUP
{
e_ReedSchalter = true;
}
if (AnzahlZustandsaenderungen < 20) // Wenn die Anzahl der Zustandsänderungen unter 20 ist
{
e_AnzahlZustandsaenderungen = true;
}
if (digitalRead(EndschalterOben) == LOW)
{
e_EndschalterOben = true;
// hier darf: Pausenzeitgeber = millis(); nicht stehen, weil der Schalter ja gedrückt bleibt!!!
}
if (millis() - Pausenzeitgeber > 4000 && millis() - Pausenzeitgeber < 4500) // erst waren es 6000 und 6500, die Pause ist auf jeden Fall zu lang, Messung hat ergeben, dass 4000 ganz gut wären
{
e_Pausenzeitgeber = true;
}
if (digitalRead(EndschalterUnten) == LOW )
{
e_EndschalterUnten = true;
}
}
void Verarbeitung()
{
if (e_ReedSchalter || e_Taster)
{
switch (Zustand)
{
case Z_ArmUnten: Pause(); break;
}
}
if (e_AnzahlZustandsaenderungen)
{
switch (Zustand)
{
case Z_Pause: ArmNachOben(); break;
}
}
if (e_EndschalterOben)
{
switch (Zustand)
{
case Z_ArmNachOben: ArmOben(); break;
}
}
if (e_Pausenzeitgeber)
{
switch (Zustand)
{
case Z_ArmOben: ArmNachUnten(); break;
}
}
if ( e_EndschalterUnten)
{
switch (Zustand)
{
case Z_ArmNachUnten: ArmUnten(); break;
}
}
}
void setup() {
// Schnittstelle für den seriellen Monitor
Serial.begin(9600);
// Pin's vorbereiten
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
pinMode(ReedSchalter, INPUT_PULLUP);
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;
AnzahlZustandsaenderungen = 0;
e_ReedSchalter = false;
e_EndschalterOben = false;
e_Pausenzeitgeber = false;
e_EndschalterUnten = false;
}
void loop()
{
Ereignisse(); // Ereignisse werden abgefragt
Verarbeitung(); // Anhand der Ereignisse werden die einzelnen Funktionen abgerufen
}
Herzliche Grüße Leonardo