@Tommy56: Super, danke, das schaue ich mir mal an.
Die Frage ist jetzt aber nicht bezogen auf dieses Projekt, sondern auf das nächste;). Dieses Programm würde ich gerne selber schreiben mit Eurer Hilfe, deshalb würde ich mich sehr freuen wenn Ihr mir auf #38 antworten würdet:).
Herzlichst Leonardo
welcher ist jetzt "der neue Sketch"????
Bitte einfach noch einmal posten und dann auch eine Zeilennummer benennen
in der die Verzögerung steht.
Wenn es da mehr Verzögerung gibt als erwartet dann wird irgendwo anders noch eine Verzögerung sein.
Um herauszufinden wo
würde ich einfach an allen Stellen an denen das sinnvoll erscheint eine Ausgabe auf den seriellen Monitor machen. Am seriellen Monitor kann man einen Zeitstempel ein/ausschalten
damit kann man dann sehen welche Ausgabe zu welchem Zeitpunkt gemacht wurde.
Noch eine Möglichkeit bei Start eines Zyklusses mit millis() im Programm einen Zeitstempel machen und dann relativ dazu jeweils die vergangene Zeit ausgeben lassen. Umgerechnet von Millisekunden auf Sekunden.
vgs
das hier ist der neue Sketch:
// 30 ms sind zu knapp für die Software Verzögerung für die gegenseitig verriegelten Schütze, mit 500 geht es, vielleicht geht es auch mit weniger ich sollte es jedoch einfach so stehen lassen!
// Die Bewegung des Armes erfolgt erst nach 30000 ms nach dem Auslösen des Reed- Schalters s
// Mit einem Drücken des Tasters zwischen den Durchgängen passiert nichts, das ist aber auch gut so.
// Die Bewegung des Armes stoppt am oberen Punkt für 4000ms, so wie es sein soll!
// Pin - Definitionen
const uint8_t relaisNachOben = 8;
const uint8_t relaisNachUnten = 9;
const uint8_t Relais3 = 10; // unbenutzt
const uint8_t Relais4 = 11; // unbenutzt
const uint8_t Taster = 6; // manuelle Ausloesung
const uint8_t ReedSchalter = 7; // Magnetauslöser
const uint8_t EndschalterUnten = 12;
const uint8_t EndschalterOben = 13;
const uint32_t wartezeitUmschalten = 4000; // regelt die Zeit, die der Arm oben stehen bleibt
void setup()
{
// Schnittstelle für den seriellen Monitor
Serial.begin(9600);
// Pin's vorbereiten
pinMode(relaisNachOben, OUTPUT);
pinMode(relaisNachUnten, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
//Ausgangszustand herstellen
digitalWrite(relaisNachOben, HIGH);
digitalWrite(relaisNachUnten, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
pinMode(ReedSchalter, INPUT_PULLUP);
pinMode(EndschalterOben, INPUT_PULLUP);
pinMode(EndschalterUnten, INPUT_PULLUP);
pinMode(Taster, INPUT_PULLUP);
}
void loop()
{
Verarbeitung();
}
void Verarbeitung()
{
enum {warten, wartenUnten, ArmNachOben, ArmOben, wartenOben, ArmNachUnten, ArmUnten};
static uint8_t zustand = warten; // Anfangszustand ist Warten
static uint8_t zaehler = 0; // Variable für Schleifenzähler
static uint32_t lastmillis = 0; // Variable Zeitmerker
static bool reedUnten = false; // Zustand für ReedSchalter
switch (zustand)
{
case warten:
if (!digitalRead(Taster)) // wenn der Taster gedrückt wird...
{
zaehler = 0; // Zähler wird 0 gesetzt
zustand = wartenUnten; // nächster Zustand
}
else if (digitalRead(EndschalterUnten)) // Wenn nicht an der Startposition, d.h wenn der Stecker gezogen wurde während der Bewegung dann fahre ich damit an die Referenzposition
{
digitalWrite(relaisNachUnten, LOW);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
}
else // Wenn der Taster gedrückt ist...Mach alles aus und warte...
{
digitalWrite(relaisNachOben, HIGH);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachUnten, HIGH);
}
break;
case wartenUnten:
if (!zaehler) // Wenn der Zähler 0 ist
{
Serial.println(F("Arm geht nach oben"));
zustand = ArmNachOben; // nächster Zustand
}
else if (!digitalRead(ReedSchalter)) // Wenn der Zähler ungleich 0 ist und der ReedSchalter auslöst // KOMMT ES HIER ZU DER ZEITLICHEN VERSCHIEBUNG? WENN DER REED-SCHALTER EIN ZEITES MAL AUSLÖST, DANN wird lastmillis = millis; HIER MUSS DER FEHLER SEIN!
{
lastmillis = millis();
reedUnten = true; // wird reedUnten wahr
}
if (millis() - lastmillis >= 20000 && reedUnten) // wenn die Anfangspause vergangen ist und reedUnten wahr ist // IN DER ZEIT KANN lastmillis() NÄMLICH WIEDER 0 WERDEN!
{
zustand = ArmNachOben; // nächster Zustand
reedUnten = false; // gespeicherten Zustand für ReedSchalter zurücksetzen
}
break;
case ArmNachOben:
digitalWrite(relaisNachOben, LOW); // Bewegung nach oben
delay (500); // Software- Verzögerung
digitalWrite(relaisNachUnten, HIGH);
zustand = ArmOben; // nächster Zustand
break;
case ArmOben:
if (!digitalRead(EndschalterOben)) // Wenn der Endschalter oben gedrückt wird
{
Serial.println(F("Arm ist oben"));
digitalWrite(relaisNachOben, HIGH);
delay(500);
digitalWrite(relaisNachUnten, HIGH);
lastmillis = millis();
zustand = wartenOben; // nächster Zustand
}
break;
case wartenOben:
if (millis() - lastmillis >= wartezeitUmschalten) // regelt die Zeit, die der Arm oben stehen bleibt
{
zustand = ArmNachUnten;
}
break;
case ArmNachUnten:
Serial.println(F("Arm geht nach unten"));
digitalWrite(relaisNachUnten, LOW);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
zustand = ArmUnten; // nächster Zustand
break;
case ArmUnten:
if (!digitalRead(EndschalterUnten)) // Wenn der EndschalterUnten gedrückt wird
{
Serial.println(F("Arm unten"));
digitalWrite(relaisNachUnten, HIGH);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
zaehler++; // Schleifenzaehler- Variable wird eins größer
if (zaehler > 3) // wenn zaehler über 3 dann wechsel in
{
zustand = warten; // Zustand Warten
}
else // wenn nicht
{
lastmillis = millis();
zustand = wartenUnten; // nach wartenUnten
}
}
break;
}
}
Kann mir jemand verraten wie ich die Zeilennummer herausfinden kann, in der die Verzögerung steht, kann man sich die Zeilennummern irgendwie anzeigen lassen?
Ich poste hier jetzt einfach nochmal die Zeile, in der die Verzögerung steht:
else if (!digitalRead(ReedSchalter)) // Wenn der Zähler ungleich 0 ist und der ReedSchalter auslöst // KOMMT ES HIER ZU DER ZEITLICHEN VERSCHIEBUNG? WENN DER REED-SCHALTER EIN ZEITES MAL AUSLÖST (BEIM RUNTERFAHREN DES ARMES), DANN WIRD lastmillis = millis; ( EIN ZWEITES MAL!). HIER MUSS DER FEHLER SEIN!
{
lastmillis = millis();
reedUnten = true; // wird reedUnten wahr
}
if (millis() - lastmillis >= 20000 && reedUnten) // wenn die Anfangspause vergangen ist und reedUnten wahr ist // IN DER ZWISCHENZEIT KANN lastmillis() NÄMLICH WIEDER 0 WERDEN!
{
zustand = ArmNachOben; // nächster Zustand
reedUnten = false; // gespeicherten Zustand für ReedSchalter zurücksetzen
}
Meine Vermutung ist folgende: Wenn der Arm beim Hochfahren den Reed- Schalter auslöst, wird der reedUnten wahr und lastmillis = millis(). Beim Runterfahren des Armes löst wird der Reed- Schalter aber ein zweites Mal ausgelöst. Dann wird lastmillis = millis() ( ein zweites Mal) und es kommt zu einer weiteren Verzögerung.
Ich will jedoch, dass die Anfangspause schon abläuft wenn der Reed- Schalter das erste Mal auslöst.
Gibt es eine Möglichkeit das zu realisieren? Könnte man zum Beispiel im Sketch formulieren: Wenn reedUnten seinen Zustand gewechselt hat, dann wird lastmillis = millis()? Der reedUnten wechselt seinen Zustand ja nicht wenn der Reed- Schalter ein zweites Mal auslöst.
Du meinst vermutlich
else if (!digitalRead(ReedSchalter) && !reedUnten)
Aber "This topic has been solved" von weiterer Hilfe wird abgeraten
Ja genau das meine ich! Danke! Jetzt ist das Thema gelöst.
Danke für Eure Hilfe!
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.
Liebe communitiy,
Hier sind abschließend ein paar Fotos und ein Video des fertigen Projektes.
P.S.: Bilder von meinen anderen Projekten findet ihr hier: Leon Fiand (@leon_fiand) • Instagram photos and videos
Danke an Alle, die mir bei dem Projekt geholfen haben! Es ist herrlich wie hilfsbereit Ihr, diese community, seid! Vielen Dank dafür!
Herzliche Grüße Leonardo
Hier sind abschließend noch einmal die endgültigen Sketches, mit denen die Installation läuft:
- Sketch des Senders (die linke Figur, die nach dem Drücken des Tasters mit der Bewegung beginnt):
// 30 ms sind zu knapp für die Software Verzögerung für die gegenseitig verriegelten Schütze, mit 500 geht es, vielleicht geht es auch mit weniger ich sollte es jedoch einfach so stehen lassen!
// Die Bewegung des Armes erfolgt erst nach 30000 ms nach dem Auslösen des Reed- Schalters s
// Mit einem Drücken des Tasters zwischen den Durchgängen passiert nichts, das ist aber auch gut so.
// Die Bewegung des Armes stoppt am oberen Punkt für 4000ms, so wie es sein soll!
// Pin - Definitionen
const uint8_t relaisNachOben = 8;
const uint8_t relaisNachUnten = 9;
const uint8_t Relais3 = 10; // unbenutzt
const uint8_t Relais4 = 11; // unbenutzt
const uint8_t Taster = 6; // manuelle Ausloesung
const uint8_t ReedSchalter = 7; // Magnetauslöser
const uint8_t EndschalterUnten = 12;
const uint8_t EndschalterOben = 13;
const uint32_t wartezeitUmschalten = 4000; // regelt die Zeit, die der Arm oben stehen bleibt
void setup()
{
// Schnittstelle für den seriellen Monitor
Serial.begin(9600);
// Pin's vorbereiten
pinMode(relaisNachOben, OUTPUT);
pinMode(relaisNachUnten, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
//Ausgangszustand herstellen
digitalWrite(relaisNachOben, HIGH);
digitalWrite(relaisNachUnten, HIGH);
digitalWrite(Relais3, HIGH);
digitalWrite(Relais4, HIGH);
pinMode(ReedSchalter, INPUT_PULLUP);
pinMode(EndschalterOben, INPUT_PULLUP);
pinMode(EndschalterUnten, INPUT_PULLUP);
pinMode(Taster, INPUT_PULLUP);
}
void loop()
{
Verarbeitung();
}
void Verarbeitung()
{
enum {warten, wartenUnten, ArmNachOben, ArmOben, wartenOben, ArmNachUnten, ArmUnten};
static uint8_t zustand = warten; // Anfangszustand ist Warten
static uint8_t zaehler = 0; // Variable für Schleifenzähler
static uint32_t lastmillis = 0; // Variable Zeitmerker
static bool reedUnten = false; // Zustand für ReedSchalter
switch (zustand)
{
case warten:
if (!digitalRead(Taster)) // wenn der Taster gedrückt wird...
{
zaehler = 0; // Zähler wird 0 gesetzt
zustand = wartenUnten; // nächster Zustand
}
else if (digitalRead(EndschalterUnten)) // Wenn nicht an der Startposition, d.h wenn der Stecker gezogen wurde während der Bewegung dann fahre ich damit an die Referenzposition
{
digitalWrite(relaisNachUnten, LOW);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
}
else // Wenn der Taster gedrückt ist...Mach alles aus und warte...
{
digitalWrite(relaisNachOben, HIGH);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachUnten, HIGH);
}
break;
case wartenUnten:
if (!zaehler) // Wenn der Zähler 0 ist
{
Serial.println(F("Arm geht nach oben"));
zustand = ArmNachOben; // nächster Zustand
}
else if (!digitalRead(ReedSchalter) && !reedUnten) // Wenn der Zähler ungleich 0 ist, der Reed- Schalter auslöst und und reed Unten false ist
{
lastmillis = millis();
reedUnten = true; // wird reedUnten wahr
}
if (millis() - lastmillis >= 20000 && reedUnten) // wenn die Anfangspause vergangen ist und reedUnten wahr ist
{
zustand = ArmNachOben; // nächster Zustand
reedUnten = false; // gespeicherten Zustand für ReedSchalter zurücksetzen
}
break;
case ArmNachOben:
digitalWrite(relaisNachOben, LOW); // Bewegung nach oben
delay (500); // Software- Verzögerung
digitalWrite(relaisNachUnten, HIGH);
zustand = ArmOben; // nächster Zustand
break;
case ArmOben:
if (!digitalRead(EndschalterOben)) // Wenn der Endschalter oben gedrückt wird
{
Serial.println(F("Arm ist oben"));
digitalWrite(relaisNachOben, HIGH);
delay(500);
digitalWrite(relaisNachUnten, HIGH);
lastmillis = millis();
zustand = wartenOben; // nächster Zustand
}
break;
case wartenOben:
if (millis() - lastmillis >= wartezeitUmschalten) // regelt die Zeit, die der Arm oben stehen bleibt
{
zustand = ArmNachUnten;
}
break;
case ArmNachUnten:
Serial.println(F("Arm geht nach unten"));
digitalWrite(relaisNachUnten, LOW);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
zustand = ArmUnten; // nächster Zustand
break;
case ArmUnten:
if (!digitalRead(EndschalterUnten)) // Wenn der EndschalterUnten gedrückt wird
{
Serial.println(F("Arm unten"));
digitalWrite(relaisNachUnten, HIGH);
delay(500); // Software- Verzögerung
digitalWrite(relaisNachOben, HIGH);
zaehler++; // Schleifenzaehler- Variable wird eins größer
if (zaehler > 3) // wenn zaehler über 3 dann wechsel in
{
zustand = warten; // Zustand Warten
}
else // wenn nicht
{
lastmillis = millis();
zustand = wartenUnten; // nach wartenUnten
}
}
break;
}
}
- Sketch des Empfängers ( die rechte Figur):
//State Machine // Bewegungsmelder ist jetzt ein Reed- Schalter 30ms sind zu kurz für die Software- Verzögerung! Mit 500ms geht es!
// Pin - Definitionen
const int Relais1 = 8;
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
}