Hallo zusammen,
ich habe mittlerweile schon ein paar Foren durchgearbeitet, aber bisher
keinen richtigen Lösungsansatz gefunden. Ich hoffe ihr könnt mir
weiterhelfen.
Zur Zeit versuche ich mich daran einen Drehzahlmesser mit Arduino zu
programmieren. Hierbei lese ich momentan ein durch einem
Frequenzgenerator generiertes Sinussignal ein (später wird dieser von
einem Prüfstand abgegriffen und durch eine gebaute Platine aufbereitet,
sodass es dann einem Sinussignal ähnelt). Die maximale Frequenz, welche
ich messen will beträgt 100Hz.
Mein Programmablauf sieht bisher vor, das Signal über analogRead()
einzulesen und die Daten in einem Array zu speichern. Dies geschieht
alle 0,125ms, durch einen 8kHz Timer. So kann ich stetig einen
gleitenden Mittelwert bilden, um etwaige "Ausreißer" einzufangen.
Anschließend starte ich eine StateMachine und vergleiche meine letzten
beiden Mittelwerte, um zu sehen ob mein Signal aktuell steigt oder
fällt. Dementsprechend suche ich mir nun mein Maximum/Minimum und danach
mein Minimum/Maximum. Sobald ich diese Werte habe erreichne ich mir
meine Amplitude der letzten Periode und definiere mir eine
"Schaltschwelle" in der Mitte. Soweit funktioniert das Programm bisher.
In den nächsten Schritten meiner StateMachine warte ich bis mein Signal
oberhalb der Schaltschwelle liegt und aktiviere mir einen Zähler der die
Ticks zählt, bis der Wert unterhalb der Schaltschwelle fällt. Fällt das
eingelesene Signal unterhalb dieser Schaltschwelle, so starte ich hier
einen zweiten Zähler, welcher mir nun wieder meine Ticks zählt. Am Ende
zähle ich die Anzahl der Ticks (multipliziert mit der Timerzeit)
zusammen (Wert in ms) und rechne dann:
rpm = 60000/Zeit(ms)
Diese Rechnung soll nach jedem Schaltschwellen-Übergang absolviert
werden, um meine Drehzahl alle halbe Periode aktuell zu halten.
Mein Problem liegt nun darin, dass meine Schaltschwellen nicht
zuversichtlich erkannt werden, da mein Programmcode bis zu 20Hz
funktioniert, jedoch bei einer höheren Frequenz meine Schaltschwellen
nicht mehr erkennt. Hat hier dazu jemand einen Tipp und kann mir
weiterhelfen? Vielen Dank schon einmal im Voraus!
Probier mal dies:
http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp7
Ein Arduino Uno mißt Frequenz, Periode und Drehzahl und gibt sie per USB
aus. Die Funktion wird über die Spannung an A0 ausgewählt, was aber auch
beliebig geändert werden kann.
Das klingt alles sehr kompliziert.
Warum kann man das Signal nicht einfach auf einen Schmitt-Trigger geben
(ist in die digitalen Eingänge schon eingebaut) und das Ganze an einen
Interrupt für steigende (oder fallende) Flanke hängen.
Der Interrupt kann dann aus der aktuellen Zeit und der Zeit des
vorangegangenen Interrupts die Umlaufzeit also auch die Drehzahl
berechnen.
DIESE Werte kann man dann im Hauptprogramm glätten.
Schaltungsaufwand entsteht nur, wenn man die Spannung des Signals noch
auf 0V bis 5V bringen muß.
Oder gleich von einem internen Timer die Zeit messen lassen - das sollte
wohl das beste ergebnnis liefern da dort keine Softwarereaktion vonnöten
sein wird.
m.n. schrieb:> Probier mal dies:> http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp7> Ein Arduino Uno mißt Frequenz, Periode und Drehzahl und gibt sie per USB> aus. Die Funktion wird über die Spannung an A0 ausgewählt, was aber auch> beliebig geändert werden kann.
Hi,
Danke für den Tipp, aber ich möchte meinen Arduino nicht dauerhaft mit
einem PC verbunden haben, sondern als alleinstehenden "Messstand"
verwenden. Ausgabe soll bei mir direkt vom Arduino an ein kleines LCD
erfolgen.
Georg Bisseling schrieb:> Warum kann man das Signal nicht einfach auf einen Schmitt-Trigger geben> (ist in die digitalen Eingänge schon eingebaut) und das Ganze an einen> Interrupt für steigende (oder fallende) Flanke hängen.
Hallo,
mein Problem ist, dass das eingelesene Signal nicht immer identisch ist.
Je nach Messung welche erfolgt, leigt das Signal beispielsweise zwischen
2.5V und 3.2V oder zwischen V und V. Und das sind jetzt nur 2 mögliche
Signale. Ich habe also keine gemeinsame Schaltschwelle.
Das ganze mit einem Schmitt-Trigger zu versuchen war auch mein erster
Lösungsansatz ;)
Daniel schrieb:> zwischen> 2.5V und 3.2V oder zwischen V und V
zwischen 2.5V und 3.2 V oder zwischen 1.6V und 2.2V. Gerade habe ich
noch einen Fall gefunden, wo das Signal nur zwischen 100mV und 500mV
liegt
Markus H. schrieb:> Oder gleich von einem internen Timer die Zeit messen lassen - das sollte> wohl das beste ergebnnis liefern da dort keine Softwarereaktion vonnöten> sein wird.
Hi,
ja das mit dem internen Timer habe ich auch bereits probiert (Ich nehme
an du meinst damit die Funktion millis()? ). Nur da wurde mir von einem
Kollegen geraten dies bleiben zu lassen, da mein Programm in der reinen
loop ja so schnell wie möglich durchrennen will. Und somit, wenn gerade
mal eine bspw. if-Bedingung nicht erfüllt wird, mein Programm schneller
durchlaufen wird. Somit hat man keine konkreten Zeitsamples.... Deswegen
sollte ich das eben auch mit dem 8kHz-Timer machen, welcher meines
Erachtens auch genauer ist oder? :)
EDIT:
Falls ihr euch den Code angeschaut und gefragt habt warum ich in state 6
bzw state 7 meinen PIN 8 auf HIGH/LOW lege:
ich habe das ganze mal an einem Oszilloskop sichtbar gemacht. Also
Eingangssignal und das Signal an PIN 8, daher kann ich eben sagen, dass
nicht jede Flanke sicher detektiert wird...
Wie wäre es mit Filterung des Gleichanteils mittels eines Kondensators,
Binarisierung mittels eines Komparators der auf den Nulldurchgang
vergleicht und dann das 0/5V Signal mit dem Arduino erfassen
Markus H. schrieb:> Wie wäre es mit Filterung des Gleichanteils mittels eines> Kondensators,> Binarisierung mittels eines Komparators der auf den Nulldurchgang> vergleicht und dann das 0/5V Signal mit dem Arduino erfassen
Das wäre eine Idee. Wie genau setzte ich das mit der
Gleichanteil-Filterung um?
Daniel schrieb:> aber ich möchte meinen Arduino nicht dauerhaft mit> einem PC verbunden haben, sondern als alleinstehenden "Messstand"> verwenden. Ausgabe soll bei mir direkt vom Arduino an ein kleines LCD> erfolgen.
Dann mach es doch! Oder ist es zu schwer, an den Arduino ein LCD
anzuschließen?
Daniel schrieb:> Hierbei lese ich momentan ein durch einem> Frequenzgenerator generiertes Sinussignal ein (später wird dieser von> einem Prüfstand abgegriffen und durch eine gebaute Platine aufbereitet,> sodass es dann einem Sinussignal ähnelt).
Wer baut diese Platine? Die Frequenz ist definiert als die Anzahl
Perioden eines periodischen Signals pro Sekunde.
Warum wird aus dem Signal ein Sinus geformt? Üblicherweise nimmt man den
Nulldurchgang eines periodischen Signals um die Frequenz zu berechnen.
Also sollte die Platine den Gleichanteil des Signals eliminieren
(Kondensator) und dann einen Impuls pro Nulldurchgang generieren.
Diesen Impuls erfasst du mit dem Arduino und misst die Zeit, die
zwischen den Impulsen vergeht mit dem Timer.
Der Kehrwert dieser Zeit geteilt durch 2 (Eine Periode hat zwei
Nulldurchgänge) ist deine Frequenz.
m.n. schrieb:> Daniel schrieb:>> aber ich möchte meinen Arduino nicht dauerhaft mit>> einem PC verbunden haben, sondern als alleinstehenden "Messstand">> verwenden. Ausgabe soll bei mir direkt vom Arduino an ein kleines LCD>> erfolgen.>> Dann mach es doch! Oder ist es zu schwer, an den Arduino ein LCD> anzuschließen?
Ich habe es bereits realisiert mit der LCD Anzeige. Muss mich auch
gleich entschuldigen, denn ich bin in deinem Link irgendwie verrutscht
und habe mir etwas anderes angesehen.
Udo Schmitt schrieb:> Daniel schrieb:>> Hierbei lese ich momentan ein durch einem>> Frequenzgenerator generiertes Sinussignal ein (später wird dieser von>> einem Prüfstand abgegriffen und durch eine gebaute Platine aufbereitet,>> sodass es dann einem Sinussignal ähnelt).>> Wer baut diese Platine? Die Frequenz ist definiert als die Anzahl> Perioden eines periodischen Signals pro Sekunde.> Warum wird aus dem Signal ein Sinus geformt? Üblicherweise nimmt man den> Nulldurchgang eines periodischen Signals um die Frequenz zu berechnen.> Also sollte die Platine den Gleichanteil des Signals eliminieren> (Kondensator) und dann einen Impuls pro Nulldurchgang generieren.> Diesen Impuls erfasst du mit dem Arduino und misst die Zeit, die> zwischen den Impulsen vergeht mit dem Timer.> Der Kehrwert dieser Zeit geteilt durch 2 (Eine Periode hat zwei> Nulldurchgänge) ist deine Frequenz.
Diese Platine baue ich selbst. Ich kann dir auch mal einen Screenshot
der Platine über LTspice zeigen. Soll so funktionieren:
- Einlesen von 2 Signalen
- Subtrahierer generiert ein Sinusähnliches Signal
- Addierer um das Signal anzuheben
- Verstärker für große Amplituden (bessere Detektion)
- Abgriff zum Arduino
Markus H. schrieb:> Also ohne Gewehr (-: So etwa>> Signal----||-----|-\> | \> | > ----- uC> | /> GND---|+/>> Eventuell fehlt noch ein hochohmiger Widerstand vom Komparatoreingang> nach GND>> Aber bekanntermaßen geht Probieren über Studieren
ok vielen dank. ich werde es gleich einmal simulieren :)
Daniel schrieb:> Vielen Dank nochmals an alle, besonders an Markus H.> Hat alles geklappt! :)
Danke, Gerne - Ich glaube das drucke ich mir gleich aus und rahme es ein
(-:
Dann ist das Studium doch nicht ganz für die Katz