Drehzahlmesser mit Gabellichtschrankenmodul

Hallo,
wollte mit folgendem Code, einem Arduino pro mini und einem Gabellichtschrankenmodul die Drehzahl eines Motors mit Propeller (geschätzt 3000 U/min) ermitteln. Erhalte aber im seriellen Monitor nur den Wert "0" als Ausgabe.
Wenn ich den Propeller von Hand durch die Lichtschranke bewege funktioniert das Programm scheinbar.
Meine Frage: ist da ein Fehler im Programm? Es sollte ermittelt werden wieviel Ticks innerhalb einer definierten Zeitspanne ankommen (einfach nur Zählen).
Oder kann es sein, das so ein Lichtschrankenmodul zu träge ist?
Würde dann vielleicht ein Fotoresistor besser funktionieren?

#include <Arduino.h>
#include <Wire.h>

byte Sensor_InputPin = 2; //Interruptpin 0

volatile unsigned long Impulse;
const byte Impulse_je_Umdrehung = 2; //Anzahl der Propellerflügel
const unsigned long Mess_Interval = 1000; //Messinterval = 1 Sekunde
unsigned int Drehzahl = 0;
unsigned long Umdrehungen = 0, Letzte_Stopzeit;

void setup()
{
    Serial.begin(9600);
    Letzte_Stopzeit = millis();
    attachInterrupt(0, Impuls_Zaehler, FALLING);
}

void loop()
{
    if (millis() - Letzte_Stopzeit > Mess_Interval)
    {
      detachInterrupt(0);
      Umdrehungen = Impulse / Impulse_je_Umdrehung;
      Drehzahl = Umdrehungen / (Mess_Interval / 1000) * 60;
      Umdrehungen = 0;
      Impulse = 0;
      Letzte_Stopzeit = millis();
      Serial.println("; " + String(Drehzahl) + " U/min");
      attachInterrupt(0, Impuls_Zaehler, FALLING);
      
    }

}

Gruß
Gerald

Hi

Was hast Du für eine Lichtschranke?
Link?
Ein LDR (Foto-Widerstand) ist um Welten träger, als ein Photo-Transistor (Der normal in einer Lichtschranke zu finden ist).

Dein Sketch ist so nicht kompilierbar - zumindest sollte mir die ISR fehlen.
Wenn die ISR (Impulszaehler() ) den Wert Impulse hoch zählt, sehe ich nicht, warum Das nicht klappen sollte.
Bis auf die grottige Auflösung von 60 r/min (Zählwert pro Sekunde Mal 60 um auf pro Minute zu kommen), soltle Das klappen.

Wer findet mehr?

MfG

Moin,

Ich zähle 3 Lüfter mit Infrarot, jeweils 1Minute lang und sende dann den Wert in eine Datenbank. Danach wieder von vorne. Ohne Interrupts. Dann habe ich mir die Schleifendurchgänge angeschaut. Vom Speed her locker. Läuft auf einem ESP8266.
Ich hatte ein Problem mit dem Sensor. Da kam ich erst mit dem Oszi am Rohspannungswert dahinter.

Das nur mal so als Tipp zwischendurch vom Handy aus.

Lieben Gruß,
Chris

Seltsam, dachte den ganzen Code kopiert zu haben. Sorry. Hier der Rest:

void Impuls_Zaehler()
{
  Impulse++;
  // Serial.println("; " + String(Impulse));
}

Wie gesagt beim langsamen Drehen werden die Impulse richtig gezählt.
Das Modul ist so eins: Gabellichtschranken-Modul Opto-Interrupter mit ITR9608 und LM393 Photodiode 9608 | eBay

Hi

Benutzt Du AO oder DO?
Wie nennt sich der Chip auf dem Platinchen?

MfG

PS: SerialPrint hat in einer ISR NICHTS verloren
Nicht nur, weil SerialPrint intern ebenfalls auf Interrupts aufbauen wird (und in einer ISR Diese gesperrt sind bzw. durch den Aufruf wohl 'frühzeitig' wieder aktiv werden) - Du verzögerst damit den loop()-Durchlauf unvorhersehbar.
Normal setzt eine ISR nur ein Flag.
Ohne das SerialPrint, also nur mit dem Impulse++; macht die ISR, was Sie soll und ist schnittig kurz.

Warum die Lichtschranke aber nicht will, weiß ich noch nicht.

Hallo,

der Chip heißt LM393 (wenn ich das richtig erkennen konnte).

Die Serielle Verbindung in der ISR ist ja auskommentiert, die hatte ich nur um zu prüfen ob Impulse erfasst werden.

Ich benutze den Analogausgang des Moduls. Der Digitale bringt mehr Impulse als wirklich da sind (gefühllt wie prellen). Ein umstecken führte auch zum gleichen Ergebnis (Drehzahl = 0)

Diese Module werden meist als berührungslose Endschalter eingesetzt und sind möglicherweise für schnelles abtasten nicht geeignet.

Gruß
Gerald

Hi

LM393 wäre zumindest ein Komparator, Der aus einem analogem Signal ein Digitales macht.
Es kann sein, daß Dein Rotor die Lichtschranke 'zu wenig' unterbricht und das Signal nicht 'weit genug gedrückt/gezogen' wird.
An dem AO-Pin müsstest Du aber eine Art Sinus-Signal per Oszi sehen können.
Ungeprüft: Wenn der AO-Pin die direkte Verbindung zum Photo-Transistor ist, könnte man Diesen 'vorspannen', wodurch auch der enthaltene Komparator einen anderen Spannungspegel 'sieht' und so ggf. sicherer schaltet.

Hmm - Vll. hat der Arduino schon einen eigenen Komparator eingebaut:Post, Link zum DaBla
Leider fehlt Da auch wieder die eigentliche Lösung.
Klar kann man den ganzen Kram über die Register des ATmega einstellen, aber Welche und Was da rein gehört, verschweigt der damalige Fragesteller.

Heute schaue ich mir Das aber nicht mehr an.

MfG

Ließ dir mal meinen Thread durch. Da sind auch Screenshots vom Oszi dabei. Flankenerkennung / Flankenfilterung - Deutsch - Arduino Forum

Hallo,

danke für die Antworten. Mir war erst einmal wichtig, dass sich jemand den Code anschaut. Ich werde jetzt Hardware-seitig ein wenig experimentieren. Drehzahl hochfahrbar machen, andere Gabellichtschranken oder auch mal mit Reflexlichtschranke.
Melde mich dann wieder.

Gruß
Gerald

volatile unsigned long Impulse;

"Impulse" muss atomic ausgelesen werden!

Hallo,

Hab mal zu "atomic" recherchiert und bin auf atomic.h gestoßen (leider alles englisch). Aber wie und wo ich meinen code anpassen muss erschließt sich mir leider nicht.

Gruß
Gerald

#include <util/atomic.h>

void loop()
{
    if (millis() - Letzte_Stopzeit > Mess_Interval)
    {
      detachInterrupt(0);
      unsigned long sichereImpulse; // stabiles Zwischenlager für Impuls Zähler
      ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
      {
        sichereImpulse = Impulse;
      }
      Umdrehungen = sichereImpulse / Impulse_je_Umdrehung;
      Drehzahl = Umdrehungen / (Mess_Interval / 1000) * 60;
      Umdrehungen = 0;
      Impulse = 0;
      Letzte_Stopzeit = millis();
      Serial.println("; " + String(Drehzahl) + " U/min");
      attachInterrupt(0, Impuls_Zaehler, FALLING);
      
    }

}

Den Rest habe ich nicht geprüft, sondern blind übernommen.

Die Blockklammern, kann man auch weg lassen, da das hier nur eine einzelne Zuweisung/Anweisung betrifft.
Also z.B. so:

      ATOMIC_BLOCK(ATOMIC_RESTORESTATE) sichereImpulse = Impulse;

Naja....
Die Schönheit findet sich erst im Auge des Betrachters.

1 Like

Hallo,

danke für den Code. Hat leider keine Verbesserung gebracht.
Ein anderer Versuchsaufbau mit einer Schlitzscheibe (ersteinmal 2 Schlitze, später nur ein Schlitz mit auswuchten) an Stelle des Propellers war die Lösung.
Konnte fast 20.000 Umdrehungen messen. Wie genau weiß ich natürlich nicht aber für meine Zwecke (Ermittlung der Motorklasse 1000 U/V oder 3000 U/V z.B.) auf jeden Fall genau genug.

Gruß
Gerald

Hi

Nach detachInterrupt sollte der Atomic-Block doch nicht zwingend sein, oder?
Zumindest gibt Es in der Zeit, wo man ausliest, keinen Interrupt, Der Teile der Variablen überschreibt.

Grund, weshalb man den Kram 'am Stück' auslesen muß:
Denke Dir, Du hast 0x01FF als Zählerwert und 'fängst an, Das auszulesen'.
Du liest '01', also das High-Byte.
Nun schlägt der Interrupt zu, die ISR wird abgearbeitet und dort wird der Wert um 1 erhöht.
Die ISR wird beendet und gibt die Kontrolle an das Programm zurück.
Diese liest nun das LOW-Byte der Zahl aus - eine 0x00 (der Wert wurde von 0x01FF auf 0x200 hoch gezählt).
Dein Ergebnis ist nur 0x100, obwohl beide Werte, Die die Variable hatte, deutlich größer waren.
Das atomic verbietet in der Zeit des Auslesen Interrupts und somit Dinge, Die 'zwischen drin' passieren können.

MfG

PS: So ungenau ist der Arduino nun auch wieder nicht - zur Not häckel eine RTC dran und lasse Die den Sekundentakt vorgeben - dafür reicht auch eine 1307, wenn man Die aber auch für was Anderes nehmen möchte, besser eine 3231.

Schon, daß Es soweit läuft.

MfG²

Das atomic verbietet in der Zeit des Auslesen Interrupts und somit Dinge, Die 'zwischen drin' passieren können.

So ist es!

Übrigens, man könne an einem Timer/Counter Eingang auch einfach nur Ereignisse zählen...
Und alle Sekunde mal schauen, wieviele da durch gegangen sind.

Hi

Stimmt - Das könnte man rein in Hardware machen. (auf die Breite des Counter achten, läuft ebenfalls ohne Warnung über)
So ein µC ist schon was Tolles - der begrenzende Faktor sitzt meist knapp vor'm Monitor.

MfG

läuft ebenfalls ohne Warnung über

Nicht ganz...
Immerhin gibts ja noch das Overflow Flag (samt zugeordnetem Interrupt) im Timer

Hi

... läuft maximal 1x ohne Warnung über ... :wink:
Wobei man dann nicht mehr 'rein in Hardware' ist, wenn Du die entsprechende ISR nutzen möchtest (was ja nichts Schlechtes sein muß).
Bei dem Flag ist dann auch nur bekannt, daß es (mindestens) einen Überlauf gab (sofern der Arduino nicht intern den Interrupt abarbeitet, wenn man die ISR nicht benutzt - dann wäre das Flag aber auch schon wieder weg)

MfG

Hallo,

nun noch ein Bild der Anlage. Hab eine 5-stellige 7-Segmentanzeige eingebaut und ich denke die Drhzahl kommt in etwa hin.

Gruß
Gerald

WP_20181030_21_36_47_Pro[1].jpg

Good day.I seen your post how to interface RPI LCD in ESP8266 it was nice and could you help me how to interface that LCD in Arduino UNO