Lichtschranke zählt Leute nicht richtig

Hallo liebe Gemeinde,
habe hier eine etwas komplexere Frage.

Das Setup ist folgendes: zwei Lichtschranken an einem Arduino Nano über eine Spannungsmessung angeschlossen. Immer wenn die Lichtschranke unterbrochen ist ist der Spannungspegel hoch.
Auch eine Ampel ist angeschlossen.
Die Lichtschranke soll Personen in einem Raum zählen, die eine Lichtschranke zählt am Eingang die Leute die reingehen, die zweite die Leute am Ausgang.

Das Problem ist, die Lichtschranke zählt falsch, da die Personen am Eingang quasi anders reingehen aus am Ausgang rausgehen.
Das Rausgehen ist nämlich geordnet, da zählt die Schranke richtig.
Am Eingang kommen aber die Leute etwas ungeordneter rein, mal zu zweit, dann eng hintereinander etc... Die Lichtschranke zählt hier einfach immer zu viel und das bekomme ich nicht in den Griff.

Das Zählen passiert in einer Schleife, siehe unten, die Schranke wartet nach jedem Zählen und das ist glaube ich das Problem, dass die beiden Schranken in einer Schleife zählen und nicht unabhängig. Mir fällt aber nichts ein wie ich das anders lösen kann, da ich das nicht hintereinander abarbeiten möchte.

Ich hab schon an der Zeit rumgespielt, das macht es allerdings nicht wirklich besser.
Eine andere Idee war quasi am Eingang immer nur "eins" zu zählen und am Ausgang pro Unterbrechung "drei" abzuziehen, um den Messfehler , das hat aber auch nicht wirklich funktioniert.

Nun weiß ich langsam nicht mehr weiter und dachte ich frage mal hier, ob vielleicht hier noch jemand eine andere Idee hat.

Den Code habe ich mal hier unten eingefügt.

Ich hoffe das Problem ist einigermaßen Verständlich, ansonsten einfach fragen, dann probier ichs nochmal zu erläutern...

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); //I2C Display 16x2 [SDA>A4 SCL>A5]

//Variablendeklaration
int rot = 2; //Relaistrigger für Ampel rot an D2
int gelb = 3 ; //Relaistrigger für Ampel gelb an D3
int gruen = 4; //Relaistrigger für Ampel gruen an D4
int LS1 = 0; //Analogeingang für Lichtschranke Eingang A0
int LS2 = 1; //Analogeingang für Lichtschranke Ausgang A1
int count; //Zählvariable
int trigger = 1000; // Analoger Triggerwert, bei dem die LS ausgelöst werden soll [=Empfindlichkeit/Schwellenwert]
int GWlow = 50; //Personengrenzwerte [Ampelschalte] bis gelb
int GWhigh = 75; //Obergrenze Personen - Ampel rot
int passthrough = 1000; //Zeit zum durchgehen durch die Lichtschranke in ms
int handschalter= 8; //Anschluss Schalter für Modus-Wahl Automatic oder Hand
int manuellrg= 9; //Anschluss für Wählschalter manuelles Grün oder Rot

void setup()
{
  lcd.init(); //Im Setup wird der LCD gestartet
  lcd.backlight(); //Hintergrundbeleuchtung einschalten.
  pinMode(rot, OUTPUT); //Ampelausgänge zum Relais
  pinMode(gelb, OUTPUT); //Ampelausgänge zum Relais
  pinMode(gruen, OUTPUT); //Ampelausgänge zum Relais
  digitalWrite(rot, HIGH); //Ampel StartUp
  digitalWrite(gelb, HIGH); //Ampel StartUp
  digitalWrite(gruen, HIGH); //Ampel StartUp
  lcd.setCursor(0, 0);// //StartUp "Sequenz" Display
  lcd.print("LG ");
  lcd.setCursor(0, 1);//
  lcd.print("Wilkommen...");
  delay(1000); //Kunstpause
  Serial.begin(9600); //Serieller Monitor aktiv
  pinMode(handschalter,INPUT); //Schalter Modus
  pinMode(manuellrg,INPUT);//Schalter manuelle Farbe
  //StartUp abgeschlossen

  //Vorbereitung Display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Modus: AUTOMATIC");
  lcd.setCursor(0, 1);
  lcd.print("Besucher:");

}

void loop()
{
//Handbetrieb  
while(digitalRead(handschalter)==HIGH)//Moduswahlschalter ist an
{
if(digitalRead(manuellrg)==HIGH){ //Manuelle Farbe ist rot
  digitalWrite(rot, LOW);
    digitalWrite(gelb, HIGH);
    digitalWrite(gruen, HIGH);
}
if(digitalRead(manuellrg)==LOW){ //Manuelle Farbe ist grün
   digitalWrite(rot, HIGH);
    digitalWrite(gelb, HIGH);
    digitalWrite(gruen, LOW);
}
lcd.setCursor(0, 0);
  lcd.print("Modus: HAND       "); //Anzeige des Modus
}
//Automaticbetrieb
  lcd.setCursor(0, 0); //Anzeige des Modus
  lcd.print("Modus: AUTOMATIC    ");
  lcd.setCursor(11, 1);
  lcd.print(count); //Zeigt die aktuelle Besucheranzahl auf Display an.
  Serial.print("Besucher: "); //damit die Ausgabe schön aussieht
Serial.println(count);//gibt die aktuelle Besucherzahl auf dem Seriellen Monitor aus.
  //Abtastung Lichtschranke
  if (analogRead(LS1) > trigger )//passiert Eingang
  {
    count++;
  }

  if ( analogRead(LS2) > trigger) //passiert Ausgang
  {
    count--;

  }
  delay(passthrough); //Warten damit nur einmal gezählt wird




  //Ampelschaltung
  if (count < GWlow) //Wenn Wert unter erstem Grenzwert -> Ampel grün
  {
    digitalWrite(rot, HIGH);
    digitalWrite(gelb, HIGH);
    digitalWrite(gruen, LOW);
  }
  else if ((count > GWlow) && (count < GWhigh)) //Wenn Wert zwischen dem ersten und zweiten Grenzwert -> Ampel gelb
  {
    digitalWrite(rot, HIGH);
    digitalWrite(gelb, LOW);
    digitalWrite(gruen, HIGH);

  }
  else if (count > GWhigh) //Wert hat den oberen Grenzwert überschritten (zu viele Personen) -> Ampel rot
  {
    digitalWrite(rot, LOW);
    digitalWrite(gelb, HIGH);
    digitalWrite(gruen, HIGH);
  }


}

Ich versuch mal als erstes meinen Blick auf den Code.

Als Erstes:
Wenn Du im Handbetrieb bist, zählst Du trotzdem. Das ist falsch - siehe #10

Als Nächstes: Wenn jemand die LS verlässt OHNE einzutreten - also am Eingang umdreht - oder gar am Ausgang umdreht - wird jedes mal gezählt ohne das physisch etwas passiert.
Das Konstrukt würde hier kranken, wenn Du nicht vereinzelt UND nur in eine Richtung den Bewegungsstrom zulässt.

Wir hatten hier im Zuge der ersten Corona-Dinge mal etwas ausarbeitet, wo sowohl IN als auch OUT mit 2 LS bedienten, das funktionierte wohl...

Das geht aber immer nur wenn Du nicht zulässt, das mehr als eine Person mitgezählt werden kann.
Wenn Du das vermeiden willst, ist das auch nicht mit 2 LS je Richtung zu lösen.

Kamera oben und köpfe zählen :joy:

Arduino. :mask:

Hi, danke erstmal für die schnelle Antwort.

An sich ist das nicht gewollt, allerdings wird das schlichtweg grad einfach nicht verwendet und müsste deshalb außenvor gelassen werden können...

Also im Prinzip MUSS jeder der die Eingangslichtschranke passiert auch die Ausgangslichtschranke passieren. Das passiert zwingend durch ein Einbahnstraßensystem (das ganze Teil ist übrigens in einer Mensa).
Es ist quasi garantier, dass jeder der am Eingang reingeht zwingend auch am Ausgang wieder rausgeht.

Hilft das?

Hast du da zufällig nen Link parat :sweat_smile:

Dankeschön

Hier war doch schon was mit Kamera mit intergierten ImageProcessor aber mit ESP32

Die Lichtschranken wurden gesponsert von ner Firma für die Schule, also ich muss quasi zwingend mit denen arbeiten...
Das ist der Hintergrund dahinter...

Den Eingang leicht umbauen nach Trichterprinzip ?

Das ist richtig.
Kann jemand, der die LS ausgelöst hat auch umdrehen?
Kann jemand der die LS ausgelöst hat dies auch ein zweites Mal tun?
Spätenstens jetzt sage ich ja.

Ne - Corona ist schon so lange, und die SuFu und ich sind nicht kompatibel :wink:

Nur rein von der Logik:
Wenn Du das mit 2LS machst und sichergestellt ist, das Einbahnstrasse: LS1 LS 2
Es können nicht mehr durch LS2 hindurch, als in LS1 gekommen sind.
Wenn Du jeden Durchgang mit 2LS baust UND dafür sorgst, das sich innerhalb des Bereiches sich nur einer befindet, gibt es folgende Möglichkeiten:
Person1: LS1 passiert
Person1: LS2 passiert
count++

Person1: LS1 passiert
Person2: LS1 passiert
Person1: LS2 passiert
count++
Person2: geht zurück
Nichts
Person3: LS1 passiert
Person4: LS1 passiert
Person3: geht zurück
Nichts
Person4: LS2 passiert
count++

Das ist reine Logik.
LS2 löst den Counter aus, das geht aber nur, wenn vorher LS1 bereits aufgezählt wurde.

So haben wir das damals auch gemacht.
Und am Ausgang dann genau anders rum.

Noch ein Nachtrag:
Meine Aussage, das im Handbetrieb aufgezählt ist falsch - da ist ja ein while drin, somit kommt er nicht raus wenn Handbetrieb.

Aber Du blockierst Dir den gesamten Rest.
Das solltest Du ändern...

Und noch ein Nachtrag:
Du hast Dir eine schöne Falle gebaut:

Während der Code sich dort im Kreis dreht, bekommst Du nicht mit, was auf den Sensoren passiert...
:slight_smile:
Willst erstmal nur mit 2 Sensoren testen, muss das umgeschrieben werden, das beide unabhängig sind.

Habe auch solchen Projekt gehabt als Pandemie anfing, musste zwei Empfänger pro Schranke machen. Drei funkgebundene Stationen: Eingang, Ausgang, Anzeige. Leider müsste das durch einen infraroten 2000€ teuren "Kopfzähler" am Eingang ersetzt werden. Denn Menschen neigen dazu in Gruppen zu bewegen und die Durchgänge dürfen nicht verengt werden.

Eine funktionierende Zählung mit einer oder 2 Lichtschranken setzt voraus daß die Personen einzeln in der Kontrollzone durchgehen.

Gesichtserkennung mittels eines Raspberrys oder ESP32 sehe ich möglich.

Grüße Uwe

Halloo,

erstmal danke für die Beiträge.

Der Eingang kann leider nicht verkleinert werden. Das funktioniert aufgrund der lokalen Gegebenheiten nicht!
Eine andere Hardware kommt nicht wirklich infrage...eben auch wegen diesem Sponsoring.

Das würde ich sehr gerne ändern, gibts da nen Stichwort oder Tipp dafür wie man diese beiden unabhängig voneinander machen könnte.

Ok, aber kann man die entstehenden Messfehler nicht irgendwie kompensieren, zumal der ja nur an einer Messstation auftritt?

Ja, nennt sich blinkWithoutDelay und ist in den Beispielen enthalten.
Aber Du hast noch ein ganz anderes Problem.

Du merkst ja nicht, ob in der Zeit die LS verlassen wurde.
Das heisst, bleibt jemand länger stehen/läuft langsamer, als Dein Timer abläuft, zählst Du zweimal.

Der Code müsste also erstmal umgeschrieben werden - und das dann ggfls. empirisch in zwei Zeitbereiche aufgeteilt:

  1. Bereich, ab wann erkannt wird das der Bereich umgeschalten hat
  2. Bereich, ab wann wieder neu gemessen werden soll.

Das geht.
Aber ich würde das erstmal nur mit einem Sensor machen.
Warum? Erkläre ich, wenn Du mit einem annähernd passenden Codevorschlag kommst :wink:

Ein 1,5m kleiner Mensch (oder gar kleiner, weil Kind) und ein 2m großer Mensch haben ihre Köpfe in unterschiedlichen Höhen. Wie bewerkstelligt der 2000€ teure Kopfzähler das?

War nicht mehr in meinem Zuständigkeitsbereich. Auseinander schrauben war es auch nicht erwünscht.

Durch Statistik.
Wenn Du weißt daß zb 20% zuviel gezählt wird kannst Du 20% subtrahieren.
Grüße Uwe

Halloo und sorry fürs Warten...

Das werde ich auf jeden Fall probieren, danke für den Hinweis, habe das Beispiel dazu schon gefunden

Ich verstehe was du meinst, das wäre eine Baustelle die ich angehen könnte,

Tatsächlich kenne ich den Messfehler (ca 35%), das werde ich mal probieren, wär natürlich das einfachste...

Danke auf jeden Fall an alle für ihre Beiträge, habt mir wirklich sehr geholfen, werde das dann mal demnächst versuchen umzusetzen und mich evtl. ggf. nochmal hier melden.

~Leander

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.