Infrarot Reflexlichtschranke tcrt5000 --> Interrupts zählen

Hi zusammen,

ich möchte gerne die Anzahl der Unterbrechungen einer Infrarot-Reflexlichtschranke (Typ tcrt5000) zählen.
Diese soll vor einer Art Propeller platziert werden und ermitteln, wie oft sich der Propeller gedreht hat.

Hier ist mal mein Code-Ansatz (ich verwende einen Arduino Nano):

#define sensorPIN  2 
int sensorState;
int IRvalueD = 0;
volatile unsigned long  interruptCounter = 0;

void setup ()
{
  Serial.begin (9600);
  pinMode (sensorPIN, INPUT);
  attachInterrupt (digitalPinToInterrupt(2), SensorInterrupt, RISING);
}

void loop()
{
  // read the state of the sensor
  sensorState = digitalRead (sensorPIN);
  Serial.println (interruptCounter);
  delay(100);
}

void SensorInterrupt ()
{
    interruptCounter++;
}

Nach Aufspielen des Sketches bekomme ich aber komische Werte raus.

Ertwartet hätte ich folgendes Verhalten:

Wenn ich die Lichtschranke mit dem Finger unterbreche zählt interruptCounter um eins hoch (die LED an der Lichtschranke leuchtet beim Unterbrechen grün, d.h. die Lichtschranke erkennt es auf jeden Fall schon mal richtig).

Wenn ich den Finger dann wieder wegnehme wird nichts gezählt, weil ich ja als Parameter der attachInterrupt-Funktion "RISING" habe.

Wenn ich dann wieder bedämpfe, zählts wieder ein hoch, usw.

Aber leider verhält sich die Sache in der Realität so:

Am Anfang 0
Ich unterbreche die Lichtschranke mit dem Finger --> interruptCounter zählt direkt auf 7 hoch
Ich nehme den Finger wieder weg --> interruptCounter zählt auf 15 hoch
usw.

Die Werteänderungen sind auch völlig willkürlich, hab ich das Gefühl.

Und nun bin ich an dem Punkt, an dem ich eben nicht weiterkomme.
Wäre nett, wenn mich jemand kurz an die Hand nehmen könnte, der Wille ist da, aber das Hirn will nicht ;-(

Beste Grüße
Daniel

Eine Variable > 1 Byte musst Du unter Interrupt-Ausschalten auslesen.
Suche nach cli() und sei()

Gruß Tommy

Hi Tommy,

ich dachte, dass in der ISR, die ich über

attachInterrupt (digitalPinToInterrupt(2), SensorInterrupt, RISING);

definiere Interrupts bereits global abgeschaltet werden?

Jedenfalls habe ich folgendes probiert

void SensorInterrupt ()
{
  cli(); // habs auch mit noInterrupts() probiert
  interruptCounter++;
  sei(); // bzw. eben interrupts();
}

Aber der Zähler spielt immer noch verrückt...
Ich komm wieder mal nicht drauf...

Ich habs jetzt so gelöst (also quasi den Input debounced):

#define sensorPIN   2 
int sensorState;
int IRvalueD = 0;
volatile unsigned long  interruptCounter = 0;
volatile unsigned long   prevMillis = 0;
int entprellzeit=100; // An dem Wert muss ich noch ein bisschen feinjustieren, aber 100 ist schon sehr gut.

void setup ()
{
  Serial.begin (9600);
  pinMode (sensorPIN, INPUT);
  attachInterrupt (digitalPinToInterrupt(2), SensorInterrupt, RISING);
}

void loop()
{
  sensorState = digitalRead (sensorPIN);
  Serial.println (interruptCounter);
  delay(100);
}

void SensorInterrupt ()
{
   if (millis () - prevMillis > entprellzeit) {
      interruptCounter++;
      prevMillis = millis ();
  } 
}

Schönen Sonntag euch!

Wie schnell wird sich denn dein 'Popeller' drehen? bei 100ms Entprellzeit wirst Du da später keine größeren Drehzahlen erkennen können. Die Frage ist auch, ob deine Reflexlichtschranke da so geeignet ist. Wenn das hier deine LS ist, hat das Bauteil einen analogen Ausgang und erzeugt kein ordentliches Digitalsignal. Das eignet sich micht als Interruptinput.

Hallo,

also wenn Du von 100ms Entprellzeit ausgehst dann die Frage , warum willst Du das mit Interrupt machen. Das macht doch nur bei schnellen Vorgängen Sinn. Wenn das eine so kleine Frequenz ist macht es ehr Sinn die Zeit zwischen zwei Flanken zu messen.

Heinz

MicroBahner:
Wie schnell wird sich denn dein 'Popeller' drehen? bei 100ms Entprellzeit wirst Du da später keine größeren Drehzahlen erkennen können. Die Frage ist auch, ob deine Reflexlichtschranke da so geeignet ist. Wenn das hier deine LS ist, hat das Bauteil einen analogen Ausgang und erzeugt kein ordentliches Digitalsignal. Das eignet sich micht als Interruptinput.

Du liegst mit deiner Vermutung völlig richtig...es ist genau diese Lichtschranke und ich hab mittlerweile auch schon festfestellt, dass die Entprellzeit ab einer gewissen Drehzahl Probleme bereiten wird.
Aber: Das Digitalsignal macht gar keinen solch schlechten Eindruck, zumindest wenn ich nach der LED gehe, die am Sensor immer dann leuchtet, wenn das Signal gesendet wird. Das Rädchen dass ich damit überwache hat maximal ca. 5 -6 Umdrehungen pro Sekunde. Wenn ich die LED währed des laufenden Betriebs so betrachte, flackert die ziemlich schnell und relativ im Takt mit dem Rädchen
Oder denkst du, es wäre besser mit dem Analogsignal zu arbeiten?
Bzgl. der Entprellzeit:
Mein aktueller Ansatz wäre, die Entprellzeit mit zunehmendem Interruptsignal dynamisch anzupassen, so dass ich bei voller Geschwindigkeit quasi fast gar nicht mehr entprelle...

Was mir zu diesem Thema so einfällt.

basementmedia:
ich möchte gerne die Anzahl der Unterbrechungen einer Infrarot-Reflexlichtschranke (Typ tcrt5000) zählen.

Genau genommen zählst Du nicht die Unterbrechungen, sondern die unterschiedlichen Oberflächen, da Du wohl nicht durch den Propeller durch mißt. Ein vom Propeller unterbrochener Lichtstrahl, der auf der einen Seite losgeschickt und auf der anderen Seite enpfangen wird, verspräche bessere Ergebnisse.

Das "Prellen" könnte von sich ändernden Oberflächen herrühren. Diese zu messen halte ich für ungeschickt.

Ich selbst verwende Reflexlichtschranken, die nicht von einem Spiegel reflektiert werden nur, wenn die reflektierende Fläche glänzend ist und nicht verschmutzt.

basementmedia:
Oder denkst du, es wäre besser mit dem Analogsignal zu arbeiten?

Ich kann mir nicht vorstellen, daß das zu besseren Ergebnissen führt.

Eine adaptive Entprellung ist eine interessante Idee, erscheint mir aber eher als Verschleiern eines grundsätzlichen Problems.

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