Zwei Lichtschranken - Weiterschaltbedingung möglich?

Hallo,
ich habe eine Projekt am laufen, in dem ich zwei Lichtschranken habe die schauen sollen ob jemand durch die Tür geht. Da ich nur wissen will ob jemand in das Zimmer reingeht möchte ich gerne, dass das programm nur dann ausgeführt wird, wenn zuerst die rechte Lichtschranke unterbrochen wird und danach die zweite. Falls zuerst die linke unterbrochen wird und dann die rechte soll nichts passieren.

Mein versuch war zunächst mal einfach zwei if statements:

if(photoWertR < 700){                      
    if(photoWertL < 500){    
      Pushover po = Pushover("XXXX","XXXXX", UNSAFE);
      po.setDevice("XXXX");
      po.setMessage("Jemand ist im Zimmer");
      po.setSound("Alien alarm");
      Serial.println(po.send());
      
      //Die angeschlossene LED soll angeschaltet werden
      digitalWrite(LEDPin, HIGH);
      while(analogRead(fresPinR) < 700){
        Serial.println("Jemand steht in der Tür");
      }
      
     }
     }else{
      digitalWrite(LEDPin, LOW);
    }
  }

Hat natürlich nicht geklappt, da er nicht unterscheiden kann welche der beiden zuerst abgedeckt ist. (Die Photoresistoren sind so nah einander, dass sie beim durchgehen beide gleichzeitig abgedeckt sind. Der eine nur früher als der andere und das möchte ich feststellen welcher zuerst und dann daraufhin ein Programm ausführen oder eben nicht.)

Kann mir jemand helfen mit was für einem befehl oder trick ich das machen kann? ^^ Danke schonmal im voraus!

Du könntest beim Durchschreiten der Lichtschranken jeweils die aktuelle Zeit abspeichern und dann überprüfen, welches die kleinere von beiden ist. Das sollte dann das Erkennen der Richtung möglich machen.

Lesetipp: millis() - Arduino-Referenz

Daran hatte ich auch schon gedacht, aber mir ist nicht klar, wie ich das abfrage. Also wie weise ich die eine Zeit dem ersten resistor zu und wie die andere zeit dem anderen?

Ein Resistor ist ein Widerstand, dem kannst Du keinen Wert zuweisen.
Fremdworte bitte nur nutzen, wenn Du weißt, was sie bedeuten.
Du meinst eher eine Variable.

uint32_t zeit = millis();

Gruß Tommy

Lichtschranke besteht aus einem Laser und einem fotowiderstand...sehe das problem nicht

Nein, das ist kontraproduktiv.
Ich würde das als Statemachine bauen mit Abbruchbedingung.
Keinerlei Zeiten - nur switches.
Ok. Vielleicht eine Zeit als TimeOut.

Dan ist das Eigenbau mit Fotozelle.

Switch case? hab da auch drüber nachgedacht, aber ebenfalls nicht gewusst, wie ich da zu einer lösung kommen kann. Wie kann ich da denn sagen, er soll den case als erstes ausführen bevor er den anderen ausführt?

Ja.

Das geht immer von oben nach unten

Ich denke dass alle Informationen vorliegen - Du musst es nur noch zusammensetzen

uint32_t zeitL;
uint32_t zeitR;

if(photoWertR < 700)
  zeitR = millis();                      
if(photoWertL < 500)
  zeitL = millis();

if (zeitR < zeitL) {
  // Programm ausführen
}
else {
  // nix tun (oder was anderes - z.B. LED wieder ausschalten
} 

Natürlich das Ganze jetzt noch ordentlich verriegeln - beim nächsten Durchlauf von loop() willst Du ja nicht sofort wieder Zeiten nehmen... und damit wären wir dann bei der Zustandsmaschine: Schreib Dir in einfachen Worten auf, was nacheinander passieren muss, damit Deine Aktion "Alarm" ausgelöst werden soll. Vielleicht so:

  • Warten
  • links ausgelöst --> zurück auf Warten
  • rechts ausgelöst -> warten mit Timeout auf links ausgelöst
  • warten auf links
  • Timeout läuft und links ausgelöst --> Aktion
  • Timeout abgelaufen --> Warten
  • Aktion --> Warten

Wenn Du das vollständig und widerspruchsfrei aufgeschrieben hast, tippt sich der Code dazu fast von allein.

Vielen dank für deine Mühe, werde es morgen mal probieren und melde mich, falls ich doch nicht weiter komme. Wünsche eine gute Nacht!

Ja.

ich komme aus einer beliebigen richtung:

auslöser 1 gesetzt - auslöser 2 gesetzt - auslöser 1 nicht gesetzt - auslöser 2 nicht gesetzt == von 1 nach 2
auslöser 1 gesetzt - auslöser 1 nicht gesetzt == 1 nach 1 -> nichts passiert
auslöser 2 gesetzt - auslöser 1 gesetzt - auslöser 2 nicht gesetzt - auslöser 1 nicht gesetzt == von 2 nach 1
auslöser 2 gesetzt - auslöser 2 nicht gesetzt == 2 nach 2 -> nichts passiert
auslöser 1 gesetzt - auslöser 1 nicht gesetzt -> nichts passiert
auslöser 2 gesetzt - auslöser 2 nicht gesetzt -> nichts passiert
auslöser 1 gesetzt - auslöser 2 gesetzt - auslöser 2 nicht gesetzt -> Gehe zurück auf auslöser 1 gesetzt
auslöser 2 gesetzt - auslöser 1 gesetzt - auslöser 1 nicht gesetzt -> Gehe zurück auf auslöser 2 gesetzt

Habe ich auch mal gemacht.
Ich komme gänzlich ohne Zeiten aus.
Da beide Schranken abgedeckt sind, ist das sogar recht einfach.
Im Code ist ein delay() auskommentiert.
Wenn Du das auf dem Steckbrett machst, mach es rein, dann merkst Du das prellen der Schalter bzw. das stecken der Kontakte nicht so sehr.

Kurze Erklärung:
Ich frage die Pins ab, und merke mir den Zustand. Dann rufe ich die Funktion zur Feststellung der Richtung auf.
Nur wenn sich der Zustand ändert, wird wieder der Zustand gewerkt und das geht wieder von vorn.

Ich hoffe nichts vergessen zu haben.

// Forensketch - Laufrichtung feststellen
// https://forum.arduino.cc/t/zwei-lichtschranken-weiterschaltbedingung-moglich/925089

bool rechtsPin = false;
bool linksPin = false;
const byte photoRechts = 2;
const byte photoLinks = 3;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(photoRechts, INPUT_PULLUP);
  pinMode(photoLinks, INPUT_PULLUP);
}

void loop()
{
  // delay(100);
  if (!digitalRead(photoRechts))
  {
    if (!rechtsPin)
    {
      rechtsPin = true;
      bewegung();
    }
  }
  else
  {
    if (rechtsPin)
    {
      rechtsPin = false;
      bewegung();
    }
  }
  if (!digitalRead(photoLinks))
  {
    if (!linksPin)
    {
      linksPin = true;
      bewegung();
    }
  }
  else
  {
    if (linksPin)
    {
      linksPin = false;
      bewegung();
    }
  }
}

void bewegung()
{
  enum {warten, rechts, links, ausgang, falsch};
  static byte vorwaerts = warten;
  switch (vorwaerts)
  {
    case warten:
      if (rechtsPin)  {vorwaerts = rechts;  Serial.println(F("komme von rechts"));}  // Eintritt von rechts nach links
      if (linksPin)   {vorwaerts = falsch;  Serial.println(F("komme von links"));}   // Eintritt von links nach rechts
      break;
    case rechts:
      if (!rechtsPin) {vorwaerts = warten;  Serial.println(F("gehe nach warten"));}  // geht wieder zurück
      if (linksPin)   {vorwaerts = links;   Serial.println(F("gehe nach links"));}   // geht nach links
      break;
    case links:
      if (!rechtsPin) {vorwaerts = ausgang; Serial.println(F("gehe zum ausgang"));}  // geht nach links
      if (!linksPin)  {vorwaerts = rechts;  Serial.println(F("gehe nach rechts"));}  // geht wieder nach rechts
      break;
    case ausgang:
      if (rechtsPin)  {vorwaerts = links;   Serial.println(F("gehe zurück nach links"));}
      if (!linksPin)     // bin am Ende
      {
        vorwaerts = warten;
        // Hier kann eine Aktion rein
        Serial.println(F("bin durch"));
      }
      break;
    case falsch:
      if (!rechtsPin && !linksPin) {vorwaerts = warten; Serial.println(F("falsche Richtung beendet"));} // geht wieder nach warten
      break;
  }
}