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?
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
... läuft maximal 1x ohne Warnung über ...
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)