Trotz Millis reagiert die Fernbedienung nicht mehr

Hallo zusammen,

Ich habe ein kleines Problem mit den lieben Millis…
Aber bitte zerreisst mich nicht gleich, ein Programmierer ist ein Lehrberuf und das bin ich nun mal nicht. Dies ist reines Hobby, das ich versuche zu verstehen.

Zum Aufbau:
ich verwende 2 Ultraschall-Sensoren. Diese werden ausgelesen, und sollen den Pin (led_bewegung) auf High setzen wenn einer der Sensoren einen Wert unter XX ausgibt -> funktioniert

Wenn jetzt über eine Fernbedienung die LED (led_rot) hinzugeschaltet wird und eine Bewegung über einen der beiden Sensoren gemeldet wird dann soll ein Relais für XX Sekunden schliessen. Dies hatte ich anfangs mit dem Delay gebastelt, und jetzt mit Millis -> funktioniert.

Was jedoch nicht klappt ist dass ich das Relais auch wieder sofort (bei Fehlalarm z.b.) mit der Fernbedienung ausschalten kann. Die Fernbedienung reagiert nicht mehr wenn das Relais zu ist.

Wo kann mein Denkfehler liegen?

// Sensor: JSN-SR04T 
// Platine: AJ-SR04M 
// Maximum Distance ist 600 cm
 
#include "NewPing.h"
#include <RCSwitch.h>
 
 
#define TRIGGER_PIN_1  10  //Sende Pin von Sensor1
#define ECHO_PIN_1     10  //Empfänger Pin von Sensor1
#define TRIGGER_PIN_2  11  //Sende Pin von Sensor2
#define ECHO_PIN_2     11  //Empfänger Pin von Sensor2
#define MAX_DISTANCE 400  // DerMaximale Messbereich

const int led_bewegung = 8;  //  Rote LED Bewegungserkennung (Signal für das Relais)
const int led_gruen = 5;
const int led_rot = 3;
const int relais_licht = 4;
unsigned long currentMillis = 0;
const long interval = 10000;

RCSwitch mySwitch = RCSwitch();

NewPing sonar1(TRIGGER_PIN_1, ECHO_PIN_1, MAX_DISTANCE);  // Weist sonar1 dem 1. Sensor zu
NewPing sonar2(TRIGGER_PIN_2, ECHO_PIN_2, MAX_DISTANCE);  // Weist sonar2 dem 2. Sensor zu
 
float distance1;
float distance2;
 
void setup() {
  Serial.begin (9600);
  mySwitch.enableReceive(0);  // Empfänger ist an Interrupt-Pin "0" - Das ist am UNO der Pin2
  pinMode(led_bewegung,OUTPUT);  //definiert den Pin led_bewegung als Ausgang)
  pinMode(led_gruen, OUTPUT);
  pinMode(led_rot, OUTPUT);
  pinMode(relais_licht, OUTPUT);
}
 
void loop() {
  digitalWrite(led_gruen, HIGH);
  distance1 = sonar1.ping_cm();
  distance2 = sonar2.ping_cm();

if (mySwitch.available()) // Wenn ein Code Empfangen wird...
  {
  int value = mySwitch.getReceivedValue(); // Empfangene Daten werden unter der Variable "value" gespeichert.
  if (value == 0) // Wenn die Empfangenen Daten "0" sind, wird "Unbekannter Code" angezeigt.
    {
      Serial.println("Unbekannter Code");
    } else 
    {     // Wenn der Empfangene Code brauchbar ist, wird er hier an den Serial Monitor gesendet.
      Serial.print("Empfangen: ");
      Serial.println( value );
        if (value == 24433)   //Taste A=24433
        {   
        digitalWrite(led_rot, HIGH); //dann soll die LED leuchten
        } 
        if (value == 24434)   //Taste C=24434 (Taste D=24440 = nicht belegt (Taste B zeigt nichts an!?)) 
        {   
        digitalWrite(led_rot, LOW); //dann soll die LED nicht mehr leuchten 
        digitalWrite(relais_licht, LOW); //Relais soll wieder öffnen
        }
  }
    mySwitch.resetAvailable(); // Hier wird der Empfänger "resettet"
  }

  

  //Sensor1
  
  // Send results to Serial Monitor
  Serial.print("Distance1 = ");
  if (distance1 >= 400 || distance1 <= 2) {
    Serial.print("Out of range");
  } else {
    Serial.print(distance1);
    Serial.print(" cm   ");
    delay(100);
  }

  
  //Sensor2
   
  // Send results to Serial Monitor
  Serial.print("Distance2 = ");
  if (distance2 >= 400 || distance2 <= 2) {
    Serial.print("Out of range");
  } else {
    Serial.print(distance2);
    Serial.print(" cm");
    delay(100);
  }

{  Serial.println(" ");
}
  
if((distance1 <=50) || (distance2 <=50)) {
    digitalWrite(led_bewegung, HIGH); //led_bewegung leuchtet
   } else{
    digitalWrite(led_bewegung, LOW);  //led_bewegung erlischt
    }
   if((digitalRead(led_rot) == HIGH) && (digitalRead(led_bewegung) == HIGH)){
    digitalWrite(relais_licht, HIGH);
    currentMillis=millis();} //aktuelle Zeit speichern
    if(millis()-currentMillis>interval)
    {
      digitalWrite(relais_licht, LOW);
} 
}

Wo kann mein Denkfehler liegen?

Hmmm ....

currentMillis=millis();} //aktuelle Zeit speichern

Solche Zeilen sind für mich unlesbar!
Dann ergreife ich schreiend die Flucht.

Also:
Kann dir nicht helfen!

Außer:
Nutze die Formatierungsmöglichkeiten der IDE

lugu:
Ich habe ein kleines Problem mit den lieben Millis…

Was jedoch nicht klappt ist dass ich das Relais auch wieder sofort (bei Fehlalarm z.b.) mit der Fernbedienung ausschalten kann. Die Fernbedienung reagiert nicht mehr wenn das Relais zu ist.

Wo kann mein Denkfehler liegen?

Dir fehlt eher der Plan zur Analyse.

Schau doch mal, ob und was Du tatsächlich als value hast, wenn Du auf die taste drückst:

Ach machste ja - nur an ner Stelle die ich nicht für voll genommen habe.

Ich schau noch drüber....

Schau doch mal, ob und was Du tatsächlich als value hast, wenn Du auf die taste drücks

Ja, im Monitor wird bei jedem Tastendruck der Code angezeigt.
Nur nicht wenn der Pin (relais_licht) auf HIGH steht.
Dann läut im Monitor zwar noch die Entfernungsmessung, allerding kein Empfang der Fernbedienung mehr...

Dann ergreife ich schreiend die Flucht.

Tu Dir bitte nicht weh, es ist glatt da draussen... trotzdem danke :wink:

Ist doch klar:

    currentMillis=millis();} //aktuelle Zeit speichern
    if(millis()-currentMillis>interval)
    {
      digitalWrite(relais_licht, LOW);
    }

Wenn currentMillis immer erst auf millis() gesetzt wird, dann läuft das Intervall nie ab.

Außerdem ist es ganz übler Stil, Ausgänge auf ihren Zustand abzufragen - dazu merkt man sich den Zustand und verläßt sich nicht darauf, daß ein Ausgang bei digitalRead() nicht auf Eingang umgeschaltet wird.

Verusche mal Code zu schreiben oder zu finden, in dem die Startzeit einmal gespeichert wird, und nicht die aktuelle (current) Zeit.

DrDiettrich:
Ist doch klar:

Aber nicht an der Stelle.
DAS ist noch eine ganz andere Baustelle.
Es ist, das das Relais einfach nur nie LOW wird, wenn die Zeit abgefragt wird.

Der will das mit der RC ausmachen - und da hängt es.

@TO: Mal in Prosa. Du rechnest jetzt - jetzt und willst wohl eher jetzt - letztens rechnen.

Gruß Tommy

Da ist ja das Problem.
Lass ich den Sketch einfach laufen, dann tut er das was er soll (auch wenn er nicht "state of the art" ist).
Das Relais schaltet nach 10 Sekunden aus.
Sobald dann wieder der Sensor eine Bewegung unter 50cm meldet, beginnen die 10 Sekunden wieder von vorne. Ist auch so gewollt.
Jedoch möchte ich zusätzlich die Möglichkeit mit der RC Taste die 10 Sekunden in dem das Relais geschlossen ist zu unterbrechen.
Allerdings in den jeweiligen 10 Sekunden reagiert der Sketch nicht mehr auf den Tastendruck.

@all:
Nein die millis() / lastmillis sind es nicht.
Der Code an der Stelle ist momentan nicht zu beanstanden.
Bei DrDietrich ist das falsch interpretiert. Die schliessende Braces ist bei ihm noch drin.

Kommentare von mir - Code aus dem Post umformatiert:

  if ((digitalRead(led_rot) == HIGH) && (digitalRead(led_bewegung) == HIGH)) 
  {
    digitalWrite(relais_licht, HIGH); // Hier wird das relais geschaltet
    currentMillis = millis();               // und die Zeit gemerkt
  }
  if (millis() - currentMillis > interval) // Wenn die Zeit um ist
  {
    digitalWrite(relais_licht, LOW);  // Mach das relais aus
  }

lugu:
Jedoch möchte ich zusätzlich die Möglichkeit mit der RC Taste die 10 Sekunden in dem das Relais geschlossen ist zu unterbrechen.

Ja. Das ist verstanden seit dem ersten Post.
Ich versuch mal was anderes.
Kannst Du mal den relaispin ändern und das Relais von (4) nach (A0) stecken?
[edit]
UND NOCH DAZU!
das led_rot von 3 nach A1
[/edit]

Dann die PIN-Zuweisung dorthin.
Testen.

Und wenn es nicht geht, will ich ein Foto vom Aufbau.
Bitte nicht nur gelbe Kabel nehmen.
Und bitte nicht von der Seite.

Das Intervall wird beliebig verlängert solange die Bedingung (led_rot && led_bewegung) erfüllt ist. Mir ist das zu viel Spaghetti-Code :frowning:

DrDiettrich:
Das Intervall wird beliebig verlängert solange die Bedingung (led_rot && led_bewegung) erfüllt ist.

Deshalb will er ja, das die Fernbedienung BEIDES aus macht:

      if (value == 24434)   //Taste C=24434 (Taste D=24440 = nicht belegt (Taste B zeigt nichts an!?))
      {
        digitalWrite(led_rot, LOW); //dann soll die LED nicht mehr leuchten
        digitalWrite(relais_licht, LOW); //Relais soll wieder öffnen
      }

Da kommt er aber nicht mehr hin. Es kommt schon nicht mehr zur Ausgabe, das etwas von der Fernbedienung gesendet wurde. Nicht nur falsch oder unbrauchbar. Garnicht.

@TO Bitte berichtige mich wenn ich das falsch interpretiere.

Mir ist das zu viel Spaghetti-Code :frowning:

ja mir auch - ich hab gerade angefangen rauszuschmeissen, was an nicht gebrauchtem Serial.print drin ist...

Wie soll dann ein gestartetes Intervall abgebrochen werden?

DrDiettrich:
Wie soll dann ein gestartetes Intervall abgebrochen werden?

??? Ich versteh die Frage nicht.
Das Intervall wird nicht mehr gebraucht.

Start:
1: Frage Fernbedienung ab
1.1 Bei A: LED_rot ein ODER(!) Bei C: (LED_rot aus UND Relais aus) 

2: Wenn die LED ein ist UND einer der Sensoren eine Distanz erkannt hat: 
2.1: Mach das relais HIGH
2.2: Merke die Zeit

3: Wenn Zeit abgelaufen
3.1. Relais aus

Fange an von vorn.

Wenn Relais ein - geht 1 nicht mehr
3 geht immer

Wobei nicht klar ist - siehe oben bei mir - ob der Auslöser das relais oder die LED_rot ist.

So wie ich das sehe, macht dein Code was er soll. Ich vermute ein Hardwareproblem. Eventuell senkt das Relais die Spannung zu sehr ab, dass es für den Empfang nicht mehr reicht.
Wie sieht denn die Schaltung aus?
gruß lorenz

Der Code versucht garnicht, ein laufendes Intervall abzubrechen. Dazu müßte relais_licht oder currentMillis irgendwie geändert werden.

Vermutlich fehlt noch ein Flag, damit das Intervall nur einmal abläuft. Dann kann man dieses Flag zurücksetzen um das laufende Intervall abzubrechen.

DrDiettrich:
Der Code versucht garnicht, ein laufendes Intervall abzubrechen. Dazu müßte relais_licht oder currentMillis irgendwie geändert werden.

Was willst Du denn abbrechen?

Er empfängt den Code der Fernbedienung und setzt LED_rot

      Serial.print("Empfangen: ");
      Serial.println( value );
      if (value == 24433)   //Taste A=24433
      {
        digitalWrite(led_rot, HIGH); //dann soll die LED leuchten
      }

Wenn die LED_rot gesetzt ist UND die Distanz unterschritten wurde, wird das Relais HIGH und die Zeit gesetzt.

  if ((digitalRead(led_rot) == HIGH) && (digitalRead(led_bewegung) == HIGH))
  {
    digitalWrite(relais_licht, HIGH);
    currentMillis = millis();
  }

Jetzt zwei Varianten:
a) - funktioniert:

  if (millis() - currentMillis > interval)
  {
    digitalWrite(relais_licht, LOW);
  }

Logisch, wenn Rleais LOW ist das egal, ob das nochmal LOW und nochmal LOW und ....

b) funnktioniert nicht. Es kommt schon gar nicht zur Ausgabe eines empfangen FB-Code:
Serial.print("Empfangen: ");
Serial.println( value );
Da kommt erst wieder was raus, Wenn das Relais LOW ist.

Darum habe ich ja #9.
Solange der TO sich aber nicht mehr dazu äussert ist das stochern im Nebel.

Im Prinzip sieht der Code jetzt korrekt aus. Bleibt das Problem, daß die FB nicht funktioniert, wenn das Relais aktiv ist. Funktioniert der Code denn mit abgeklemmtem Relais?

DrDiettrich:
Im Prinzip sieht der Code jetzt korrekt aus.

Der Code sieht nicht anders aus als gestern auch.
Siehe dazu #8

So, nach weiteren Stunden der Fehlersuche bin ich schlauer.
Ich hatte den Code wie Post 8 umgeschrieben, was keine Veränderung brachte.
Dann die Pinbelegung wie im Post 9. Auch hier keine Veränderung.
Der Hinweis in Post 14 war entscheiden: Lorenz bestätigte dass mein Sketch eigentlich funktionnieren sollte. Dafür schon mal danke. Es freut mich echt dass ich das so hinbekommen habe. Das "schönschreiben" werde ich auch noch auf die Reihe kriegen... Geduld.

So wie ich das sehe, macht dein Code was er soll. Ich vermute ein Hardwareproblem

Im Prinzip sieht der Code jetzt korrekt aus. Bleibt das Problem, daß die FB nicht funktioniert, wenn das Relais aktiv ist. Funktioniert der Code denn mit abgeklemmtem Relais?

Der Hinweis zum Hardwareproblem mit der Bitte nach einen Foto von meinem Aufbau (Post 9) liessen es bei mir im Hirn Klick machen.
Ich habe das Relais auf dem Steckbord gleich neben dem 433Mhz Empfänger. Dann habe ich das Relais gegen eine LED getauscht und oh Wunder, klappt!!!
Relais wieder eingesteckt und mal den Monitor genau verfolgt. Was soll ich sagen, das Magnetfeld des Relais hat den Empfänger Schachmatt gesetzt.

Danke an alle Beteiligten.
Guy