Sensor auslesen und printen | für jeden Impuls einmal hochzählen

Guten Abend,

hier nochmal kurz und knapp das Problem.
Ich habe einen Lichtschrankensensor und möchte hier die Impulse auslesen.
Für jedes Mal, wenn ich die Schranke unterbreche, soll n um 1 hochzählen.
Erst, wenn die Schranke für einen Moment nicht unterbrochen war und wieder unterbrochen wird, soll n auf 2 hochzählen.
Das ganze soll in einem Intervall von 5 Sekunden hochgezählt werden und danach wieder auf 0 gehen.
Ich bin leider blutiger Anfänger.

Wenn ich jetzt also 5 Mal in 4 Sekunden die Schranke unterbreche, soll n = 5 sein. Ich möchte es ausschalten, dass n weitergezählt wird, wenn ich den Finger weiterhin davor halte. Dass praktisch das Finger wegnehmen notwendig ist um beim erneuten Reizen weiterzuzählen.

Mein ArmateurCode im Folgenden. Ich hoffe, ihr könnt mir auf die Sprünge helfen. :slight_smile:

Schönen Abend und schöne Vorweihnachtstage wünsche ich euch. :slight_smile:

int i;
int n = 0;            // n Anzahl der Impulse
int Z;                // Z INPUT des Sensors 0 oder 1

void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
}

void loop() {{  
  Z = digitalRead(A0); // LOW oder HIGH
  
  if ( Z != HIGH)
    {    
    n++;

      if ( n > 10)
      {
        n = 10;
      }
    }
      else 
        {
          n = n-1;
        
          if (n < 0)
          {
            n = 0;
          } 
        }

}
Serial.println(n);
}

Hallo,

dein Problem mit dem Hochzählen würde ich über eine Kontrollvariable verwirklichen, welche das hochzählen erst erlaubt, wenn der Wert zwischenzeitig 0 war.

Hier ein Codebeispiel für einen Button:

const int btn = 10;

boolean wasNull = 1;
int count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(btn, INPUT);

}

void loop() {
  if(digitalRead(btn) == 1 && wasNull == 1){
    count++;
    Serial.println(count);
    wasNull = 0;
  }

  if(digitalRead(btn) == 0){
    wasNull = 1;  
  }

}

Hi

Du musst doch nur auswerten, ob die Lichtschranke bereits für 5 Sekunden NICHT unterbrochen wurde - daraufhin die Anzeige auf Null setzen (oder erst bei der nächsten Unterbrechung mit 1 anfangen).
Hochzählen bei Flankenwechsel Low->High, Wartezeit starten bei Flankenwechsel High->Low.

Würde Beides mit einem Interrupt erschlagen wollen.

Da elektronische Schalter, ist kein Prellen vorhanden also auch kein Endprellen nötig, sonst würde durch den Interrupt ziemlich schnell gezählt werden :wink:

MfG

versuch mal ob der folgende Sketch das macht was du dir vorstellst.

const byte lsPin = 10;//Lichtschranke an Pin 10
const uint16_t interval = 5000;// Interval 5 sek.
bool lsState,lsState_alt;
uint8_t z;// Zähler
uint32_t start;

void setup() {
  Serial.begin(115200);
  Serial.println("Setup Impulszähler");
  pinMode (lsPin, INPUT_PULLUP);
}

void loop() {
  lsState = digitalRead(lsPin);
  if (!lsState && lsState != lsState_alt)
      {z++;
       Serial.println(z);}
  lsState_alt = lsState;
  if (millis() - start > interval)
     {z = 0;
      start = millis();}
}

Hi,

sorry ich kam erst vor ein paar Tagen braungebrannt aus Ägypten zurück. Ich hoffe ihr seid gut reingerutscht!

Ich habe das von ardubu ausprobiert. Es macht genau das, was ich brauchte. Vielen Dank dafür!! :slight_smile:

Ich versuch mal eben zu checken, was genau du gemacht hast, probiere weiter und berichte. Sicher werd ich nochmals etwas brauchen.

Eventuell könnte mir jemand kurz in Worten diesen Baustein :" if (!lsState && lsState != lsState_alt)" erklären?

Danke euch!! :slight_smile:

Eventuell könnte mir jemand kurz in Worten diesen Baustein :" if (!lsState && lsState != lsState_alt)" erklären?

wenn lsState ==0 ist und lsState ungleich lsState_alt ist, ist die Bedingung erfüllt.