Personenzählung mit zwei Lichtschranken

Guten Tag zusammen,

Auf Basis eines Projektes, möchte ich eine Personenzählung mit zwei Lichtschranken realisieren.
Kurze Infos:

Gebäude, mit einem Ein- und Ausgang
Zwei Lichtschranken hintereinander

Wenn LS1 erkannt wird und im Anschluss LS2 erkannt wird, soll der Zähler hoch zählen. Bei umgekehrten Fall demnach runter zählen. Sprich es sollen beide Lichtschranken in einer Reihenfolge erkannt werden (wenn zuerst x dann y erkannt wird, passiert z).
Eine Personenzählung bekomme ich soweit hin, allerdings nur wenn beide Lichtschranken gleichzeitig betätigt werden.

Zudem habe ich ein Problem mit meinen millis(). Ich schaffe es nicht, das jede Lichtschranke seperat zählt, sondern beide Variabeln immer den gleichen Wert annehmen.

Kann mir da jemand helfen?

Liebe Grüße :smiley:

bool Lichtschranke1;
bool Lichtschranke2;
bool Lichtschrankenstatus1;
bool Lichtschrankenstatus2;
int Besucher = 0;
unsigned long LS1 = 0;
unsigned long LS2 = 0;
long reset = 0;

void setup() 
{
Serial.begin(9600);
}

void loop() 
{
Lichtschranke1 = digitalRead(8);
Lichtschranke2 = digitalRead(9);
if (Lichtschranke1 == LOW && Lichtschrankenstatus1 == LOW)
{
  Lichtschrankenstatus1=HIGH;
  LS1 = millis();
  Serial.print("LS1=");
  Serial.println(LS1);
}
  if (Lichtschranke2 == LOW && Lichtschrankenstatus2 == LOW)
  {
   Lichtschrankenstatus2 = HIGH;
   LS2 = millis();
   Serial.print("LS2=");
   Serial.println(LS2);
  }
    if (Lichtschrankenstatus1==1 && Lichtschranke2==LOW && (millis()-LS1>millis()-LS2))
    {
          Besucher++;
    Serial.print("Besucher=");
    Serial.println(Besucher);
    Serial.print("Lichtschranke1=");
    Serial.println(Lichtschrankenstatus1);
    Serial.print("Lichtschranke2=");
    Serial.println(Lichtschrankenstatus2);
    delay(100);


    }
    Lichtschrankenstatus1 = LOW;
    Lichtschrankenstatus2 = LOW;
    LS1 = reset;
    LS2 = reset;
}```

Das hatten wir doch schon mal fast baugleich…

Kurze Frage:
Können sich im Bereich zwischen den LS Personen begegnen? Also kann Person 1 LS1 beim Eintritt auslösen und Person 2 beim Austritt LS 2 vor dem Durchlauf von Person 1?
Die Frage hatte ich auch schon mal gestellt…

Hallo
ich denke mal du brauchst einen Timer
Pseudocode:
wenn (Lichtschranke1 oder Lichtschranke2) starte Timer
wenn (Lichtschranke1 UND Timer) → Person kommt rein
wenn (Lichtschranke2 UND Timer) → Person geht raus

Nein es kann sich niemand begegnen.

dann folge mal meinem zweiten link oben, da ist ein Ansatz zum zählen drin; vielleicht hilft es ja.
Wobei der Code da nur das grundsätzliche zählen darstellen soll und so nicht lauffähig ist.

Ich hab den mal gebaut. Mit Kontrollausgaben auf dem SerMon.
PIN anpassen und testen, was passiert.
Wenn die LS mehrfach auslösen, dann lässt sich das auch ändern mit ner kleinen Bouncetime. Aber das erst, wenn ich was von Dir gehört habe…

// ungetestet!
const int sens1PIN = 2; // Eingang
const int sens2PIN = 3; // Ausgang
bool sens1Stat = false;
bool sens2Stat = false;
int Plusbesucher = 0;
int Minusbesucher = 0;
int Besucher = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(sens1PIN, INPUT);
  pinMode(sens2PIN, INPUT);
}


void loop()
{
  if (digitalRead(sens1PIN) == HIGH) // Durchlaufe Eingang
  {
    if (sens1Stat == false)          // vorher war keiner in der LS
    {
      Serial.println(F("Eingang erkannt"))
      sens1Stat = true;              // merke, das einer drin ist
      if (Minusbesucher)             // mehr als 0 schon durch den Ausgang?
      {
        Serial.println(F("zaehle runter"));
        Besucher--;                  // dann zähle Besucher runter
        Minusbesucher--;             // Ausgangszähler runter
        Serial.println(Besucher);
      }
      else
      {
        Serial.println(F("zaehle hoch"));
        Plusbesucher++;              // Wenn keiner durch den Ausgngszähler, dann merken
      }
    }
  }
  else
  {
    sens1Stat = false;              // Und wenn die LS wieder frei, dann Status freigebn
  }

  if (!sens2PIN)
  {
    if (sens2Stat == false)
    {
      Serial.println(F("Ausgang erkannt"))
      sens2Stat = true;
      if (Plusbesucher)
      {
        Serial.println(F("zaehle hoch"));
        Besucher++;
        Plusbesucher--;
        Serial.println(Besucher);
      }
      else
      {
        Serial.println(F("zaehle runter"));
        Minusbesucher++;
      }
    }
  }
  else
  {
    sens2Stat = false;
  }
}

Habe dein Programm mal getestet. Laut SerMon gibt der ein Zähl Hoch Befehl aus nachdem die erste LS wieder verlassen wurde und mehr passiert dort nicht.

Ja.
Da ist die zweite LS genauso zu machen wie die erste. Aus:

  if (!sens2PIN)

wird:
if (sens2PIN == HIGH) Danke Heinz…

if (digitalRead(sens2PIN) == HIGH)

Hallo

sorry sehe ich etwas anders :wink:

das Einlesen von sensor 2 fehlt da an der Stelle

if (digitalRead(sens2PIN) == HIGH) // Durchlaufe Eingang

Heinz

Super, danke es hat geklappt. Muss nur noch einbauen, dass nicht unter 0 gezählt wird. Negative Personenzahlen in Läden fände ich etwas komisch :joy:

const int sens1PIN = 2; // Eingang
const int sens2PIN = 3; // Ausgang
bool sens1Stat = false;
bool sens2Stat = false;
int Plusbesucher = 0;
int Minusbesucher = 0;
int Besucher = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(sens1PIN, INPUT);
  pinMode(sens2PIN, INPUT);
}
void loop()
{
  if (digitalRead(sens1PIN) == HIGH) // Durchlaufe Eingang
  {
    if (sens1Stat == false)          // vorher war keiner in der LS
    {
      Serial.println(F("Eingang erkannt"));
      sens1Stat = true;              // merke, das einer drin ist
      if (Minusbesucher)             // mehr als 0 schon durch den Ausgang?
      {
        Serial.println(F("zaehle runter"));
        Besucher--;                  // dann zähle Besucher runter
        Minusbesucher--;             // Ausgangszähler runter
      }
      else
      {
        Serial.println(F("zaehle hoch"));
        Plusbesucher++;              // Wenn keiner durch den Ausgngszähler, dann merken
      }
      Ausgabe_Besucher();
    }
  }
  else
  {
    sens1Stat = false;              // Und wenn die LS wieder frei, dann Status freigebn
  }

  if (digitalRead(sens2PIN) == HIGH)
  {
    if (sens2Stat == false)
    {
      Serial.println(F("Ausgang erkannt"));
      sens2Stat = true;
      if (Plusbesucher)
      {
        Serial.println(F("zaehle hoch"));
        Besucher++;
        Plusbesucher--;
      }
      else
      {
        Serial.println(F("zaehle runter"));
        Minusbesucher++;
      }
      Ausgabe_Besucher();
    }
  }
  else
  {
    sens2Stat = false;
  }
}

void Ausgabe_Besucher()
{
  Serial.println();
  Serial.println(F("Es befinden sich: "));
  Serial.print(Plusbesucher);
  Serial.println(F(" im Zugang"));
  Serial.print(Besucher);
  Serial.print(F(" im Haus - von denen "));
  Serial.print(Minusbesucher);
  Serial.println(F(" im Abgang"));
  if (Minusbesucher>Besucher)
  {Serial.print(F("ALARM! "));
  Serial.print(Minusbesucher-Besucher);
  Serial.println(F(" uebers Fenster reingekommen!"));}
  Serial.println();
}

Ja, aber das kann ja in der Realität nicht passieren, weil nur rausgehen kann, wer vorher reingegangen ist. :wink:
Es kann natürlich jemand beim Fenster eingestiegen sein, und geht dann bei der Türe raus. :grinning: