Lichtschranken Stückzähler mit minütlicher Ausgabe an ESP32

Hallo,

ich brauche etwas Hilfe: Ich habe an einem ESP32 ein RTC-DS3231 und eine IR-Reflektorlichtschranke ähnlich der TCRT5000 nur mit 3 Pins. (messwert = 0 heißt Objekt ist da)
Ziel ist es Flaschen, die an einem Band vorbeilaufen zu zählen und die Stückzahl, welche pro Minute vorbei gegangen ist, auszugeben (erstmal nur per Serial). Das ganze soll dann später per SPIFFS gespeichern und per Webserver downloadbar sein. SPIFFS und Webserver laufen schon. RTC ebenfalls.

Allerdings bekomme ich die Schleife zum Zählen der Flaschen nicht hin:

  1. Eine Flasche “triggert” die Schleife mehrfach. Daher habe ich die zweite Do-While Schleife eingefügt, aber das funktioniert nicht.

  2. Auch die Schleife mit der Ausgabe pro Minute klappt nicht richtig. Ich komme erst aus der Schleife, wenn der Sensor “triggert”. Es kann aber auch sein, dass 1-2 h nichts passiert. Auch da will ich eine minütliche Ausgabe mit 0 Flaschen haben…

Irgendwie bin ich da auf dem Holzweg… Hab ich die falschen Schleifen genutzt? Wäre cool, wenn mich einer in die richtige Richtung leitet :slight_smile:

#include "WiFi.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
#include <Wire.h>  
#include "RTClib.h"       

RTC_DS3231 rtc;

int messwert;
int t1;
int t2;
int t3;
int i;
String zeit;
const char* ssid = "XXXXX";
const char* password =  "XXXXX";


AsyncWebServer server(80);
  
void setup(){
  Serial.begin(115200);
  pinMode(2,INPUT);
  if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
  }
        if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
  }
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
  
  server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/file.html", "text/html", true);
  });
   
  server.on("/interpret", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/file.html", "text/html", false);
  });
    if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  server.begin();
} 
  
void loop(){
    DateTime now = rtc.now();
    Serial.print(now.day(), DEC);
    Serial.print('.');
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
     
t1 = millis();
do {
   
messwert=digitalRead(2);
delay(50);
  if (messwert == 0) {
  i = i + 1;
Serial.println("Flasche erkannt");
    do {
    messwert=digitalRead(2);
   }while (messwert == 1);
  }
t2 = millis();
t3 = t2-t1;
}while (t3 < 60000);

Serial.println("Stückzahl in der letzten Minute: ");
Serial.print(i);
Serial.println(" ");
i=0;
}

Du musst erkennen, wann die Flasche kommt, (low), und dann warten, bis wieder die Falsche weg ist (high). Dann erst zählen.

Deine Schleifen sind blockierend. Mit loop hast du bereits eine Schleife.

Stichwort Flankenerkennung, Tastererkennung, endlichet Automat, ...

Zur Flankenerkennung (engl.: state change detection) gäbe es ein Beispiel in der Arduino-IDE:

Datei / Beispiele / 02.Digital / StateChangeDetection