Forum: Mikrocontroller und Digitale Elektronik Drehzahlmessung mit Arduino


von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

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!

von m.n. (Gast)


Lesenswert?

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.

von Georg B. (diereinegier)


Lesenswert?

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ß.

: Bearbeitet durch User
von Markus H. (haniham) Benutzerseite


Lesenswert?

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.

von Daniel (Gast)


Lesenswert?

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.

von Daniel (Gast)


Lesenswert?

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 ;)

von Daniel (Gast)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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? :)

von Daniel (Gast)


Lesenswert?

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...

von Markus H. (haniham) Benutzerseite


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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?

von m.n. (Gast)


Lesenswert?

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?

von Udo S. (urschmitt)


Lesenswert?

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.

: Bearbeitet durch User
von Daniel (Gast)


Lesenswert?

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.

von Markus H. (haniham) Benutzerseite


Lesenswert?

Also ohne Gewehr (-: So etwa
1
Signal----||-----|-\
2
                 |  \
3
                 |   > ----- uC
4
                 |  /
5
           GND---|+/

Eventuell fehlt noch ein hochohmiger Widerstand vom Komparatoreingang 
nach GND

Aber bekanntermaßen geht Probieren über Studieren

: Bearbeitet durch User
von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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 :)

von Daniel (Gast)


Lesenswert?

Vielen Dank nochmals an alle, besonders an Markus H.
Hat alles geklappt! :)

von Markus H. (haniham) Benutzerseite


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.