Rechengeschwindigkeit Drehzahlerfassung

Hallo liebe Gemeinde,

ich bin Maschinenbau-Ing. und komme demnach aus einer komplett anderen Ecke und noch komplett neu im Microcontroller-Umfeld.
Daher verzeiht mir bitte die eine oder andere, möglicherweise dumme Frage.

Mir schwebt da ein längerfristiges Projekt vor, aber bevor ich mich voll in die Thematik hinein stürze und viel Zeit investiere,
möchte ich erst etwas Recherche betreiben.

Ich habe die letzten Wochen viel gelesen, aber auf folgende Frage fand ich keine Antwort:
(Meine Frage zielt nicht auf C-Code o.ä. ab)

Ich möchte die Drehzahl eines Verbrennungsmotors erfassen.
Dieser kann eine max. Drehzahl von 7000U/min erreichen.
Drehzahlerfassung soll über die bereits im Motor vorhandenen Sensor laufen (Hall-Sensor).
Auf der Kurbelwelle ist ein Zahnkranz mit 58Zähnen montiert, d.h. pro Umdrehung der Welle werden 58 Impulse ausgegeben.
--> Dies entspricht ca. 6770 Impulse pro Sekunde bei max. Motordrehzahl.

Frage:
Ist das Arduino (Uno) überhaupt in der Lage diese Rechengeschwindigkeit/-Leistung zu liefern ?

Man muss beachten, dass dies bisher nur die Erfassung der Impulse war.
Das Ziel wäre, mit diesem Input noch so einiges zu berechnen, z.B. Drehzahl-Gradienten etc. pp., d.h. werden noch Reserven benötigt.

Wenn das Arduino diese Leistung nicht liefern kann, kann ich mir entweder die Arbeit sparen oder auf eine leistungsstärkere Plattform aufsetzen.

Vielen Dank und Grüße!

Hallo,

das wären max. 6770Hz am Eingang. Kein Thema würde ich sagen. Also kann er locker. Die Frage wäre wieviel Rechenzeit bleibt übrig.
Mal grob gerechnet. Ein Impuls dauert demzufolge 0,147ms, was Luft lässt für ca. 147.000 Takte. Damit kann man viel machen, wenn man sparsam programmiert. Von großartigen Potenzrechnungen o.ä. sicherlich schnell aufgefressen. ? Zur Not könnte man noch die Impulse mit einem Eingangsfilter reduzieren, sodass nur jeder 2. oder im besten Fall nur jeder 58. Impuls durchkommt. Denk- oder Rechenfehler drin?

--> Dies entspricht ca. 6770 Impulse pro Sekunde bei max. Motordrehzahl.

Ein UNO hat 16 Millionen Takte pro Sekunde.
Um die Drehzahl zu messen und zu speichern benötigt der UNO keine 20 Takte, wenn du es klug anstellst.
Es bleiben also noch 1599980 Takte pro Sekunde für Berechnungen übrig.

Danke für die Antworten. Das sind schon mal gute Voraussetzungen.

Impulse auslassen bzw. wegfiltern möchte ich nicht, da der Drehzahlgradient dadurch an Genauigkeit verlieren würde.

Ich errechne bei max. Drehzahl eine theoretische Zahnzeit von ca. 15 Mikrosekunden.
Wie genau bzw. mit welcher Auflösung kann die Zahnzeit im besten Fall gemessen werden?
Ich habe bei meinen Recherchen irgendwo gelesen, dass z.B. die Funktion micros() dies nur auf 10 Mikrosekunden genau messen kann.
Ist das richtig?

Bitte beachten, die hier errechneten Werte sind jeweils immer auf max. Drehzahl bezogen.
Die relavante Betriebsdrehzahl des Motors befindet sich im Bereich 2000-6500U/min.

Danke.

Hallo,

laut meiner Rechnung beträgt der minimale zeitliche Abstand bei voller Drehzahl zwischen 2 Impulsen 147µs,
weil eine Impulsperiode 147µs dauert. :slight_smile:

micros() ist auf +/- 4µs genau.

Was willste denn alles berechnen?

Wie genau bzw. mit welcher Auflösung kann die Zahnzeit im besten Fall gemessen werden?

Es gibt verschiedene Verfahren!

Zähne Pro Sekunde zählen.

Zeit pro Zahn

Ich habe bei meinen Recherchen irgendwo gelesen, dass z.B. die Funktion micros() dies nur auf 10 Mikrosekunden genau messen kann.

Sind es nicht eher 4µS?
Das liegt an der Art der Verwendung von Timer0.
Aber du musst(ich sage "darfst") ja nicht die Arduino-Komfort-Methoden nutzen, und dich diesen Einschränkungen unterwerfen.

doglike:
--> Dies entspricht ca. 6770 Impulse pro Sekunde bei max. Motordrehzahl.

Frage:
Ist das Arduino (Uno) überhaupt in der Lage diese Rechengeschwindigkeit/-Leistung zu liefern ?

6770 Impulse pro Sekunde zu zählen sind kein großes Thema.

Das kannst Du sogar noch mit Interrupt-Behandlungsroutinen locker machen, in denen Du die steigenden oder fallenden Flanken zählst.

Beim zehnfachen würde es mit der Anzahl "Interrupts pro Sekunde" dann kritisch werden.

Aber es gibt auch eine zweite Möglichkeit: Du kannst an jedem Arduino-Board mindestens einen Pin mit einem Counter als "Zähler" programmieren.
Beim "UNO" Board wäre das der digitale Pin5.

Dann kannst Du an dem so programmierten Pin Zählraten für Impulse bis in den Megahertzbereich erreichen, und da die Zählung komplett in Hardware erfolgt, steht Dir trotzdem noch 100% der Rechenleistung für das eigentliche Programm zur Verfügung.

steht Dir trotzdem noch 100% der Rechenleistung für das eigentliche Programm zur Verfügung.

Nicht ganz 100%
Eher so 99,9999%
Der Zähler will gestreichelt werden, damit er das, was man will, im Hintergrund erledigt.

Hallo,

kleine Korrektur mit meiner aktueller Denkweise. Bis in den Megahertzbereich zählen und 100% freie Rechenzeit geht nicht. Weil je höher der Eingangszähltakt umso öfters hängt der µC im Zählinterrupt "fest". loop käme dann nur noch schleppend voran. Was meinst du?

Wenn man wirklich hohe Frequenzen zählen will gibt auch noch Hardware Timer. Dann werden die Impulse erfasst ohne dass man ständig Interrupts auslöst. Dafür gibt es auch fertige Libraries. Wobei man verstehen sollte was die im Hintergrund machen. Sonst kann man sie leicht falsch verwenden.

Hallo,

ich denke wir reden alle vom Hardware Timer mit Input-Capture Mode um diese Impulse zu erfassen?
Mit Pinabfrage und micros wäre eh zu ungenau. Weil wann kommt die loop vorbei.
Nur zählt ein Hardware Timer nur mit konfigurierten Interrupt am Eingang.
Hardware Timer ohne Interrupt? Ich wüßte ehrlich gesagt nicht wie.
Ich weiß nur das man bei hohen Frequenzen noch Tor-Schaltungen verwendet und die Zeit zwischen den Impulsen misst statt stur die Anzahl aller Impulse.

ich denke wir reden alle vom Hardware Timer mit Input-Capture Mode um diese Impulse zu erfassen?

Hach....

Selbst das dulle pulseIn() könnte hier reichen.

Aber bisher weiß ich ja noch gar nicht wie genau und aktuell die Daten sein müssen.
Was alles berechnet werden soll.

Und so, kann und will ich mich nicht auf ein Verfahren festlegen.

Doc_Arduino:
ich denke wir reden alle vom Hardware Timer mit Input-Capture Mode um diese Impulse zu erfassen?

Nein. Mit Input Capture misst man die Länge eines Impulses. Für Drehzahl-Erfassung reicht es einfach einen Timer extern zu takten. Dann hat man einen Timer für die Impuls-Erfassung und einen für die Torzeit (oder evtl. auch nur millis()).

Ich weiß nur das man bei hohen Frequenzen noch Tor-Schaltungen verwendet und die Zeit zwischen den Impulsen misst statt stur die Anzahl aller Impulse.

Bei einer Messung mit Torzeit miss man die Anzahl der Impulse während der Zeit. Das ist gut für relativ hohe Frequenzen. Bei sehr niedrigen Frequenzen misst man besser die Puls-Länge weil sonst die Torzeit viel zu hoch ist. Das ist hier aber nicht Fall.

Hallo,

stimmt, habt recht, muss man zugeben dürfen. :slight_smile:

Also prinzipiell ist sein Anliegen möglich. Das "wie" kommt auf die Details an.

Guten Abend zusammen,

wow, mit soviel Feedback hätte ich nicht gerechnet. Ihr habt meine eigentliche Frage ziemlich genau beantwortet, nämlich dass der Arduino diese Rechenlast wohl ohne größere Anstrengungen packt. Das reicht erst einmal.

Recht herzlichen Dank !

Die genaue Umsetzung in Schaltung und Code ist für mich eher der 3./4. oder 5. Schritt. Ich befinde mich aktuell noch in der Konzeptphase, wo ich erst noch klären muss, ob dieses und jenes überhaupt so funktioniert, wie ich mir das denke. Rechenleistung war einer dieser offenen Fragen.

Weil die Frage ein paar mal aufkam:
Ich möchte so genau wie möglich die Zahnzeiten messen, d.h. wie lange hat es gedauert, bis der Zahn durchlaufen ist und wie lange hat es gedauert, bis die Lücke durchlaufen ist. Und das für alle Zähne - nonstop.

Allgemein, wenn man diese Informationen bei einem Verbrennungs-(Hubkolben)-Motor hat, kann man sehr viele Informationen daraus ableiten.

Ich würde über Detaillösungen dann separate Threads eröffnen, wenn ich soweit bin :slight_smile:

Eine Frage fällt mir nun doch noch ein :slight_smile:

Wie sieht es mit der Rechenleistung des Arduino Nano aus?
Dieses hat ja nur die halbe Taktrate von 8Mhz.
Nach den vorangehenden Posts denke ich, sollte es, was die Rechenleistung angeht, dafür wohl auch kein Problem darstellen. Es könnte allerdings sein, dass das Nano gar nicht die für mich benötigten Input-Pin-Anzahl hat, daher ist das eher eine generelle Frage.

doglike:
Wie sieht es mit der Rechenleistung des Arduino Nano aus?
Dieses hat ja nur die halbe Taktrate von 8Mhz.

Nein. Nanos laufen alle (soweit ich bisher gesehen habe) mit 16 MHz.
Bei den Pro Minis hast du die Wahl zwischen 5V/16MHz oder 3.3V/8MHz.

Ich würde einen HW-Interrupt-Eingang nehmen und diesen vom Hallgeber am Zahnkranz takten lassen.
In der zugehörigen ISR einfach die aktuellen mikros() ermitteln, vom letzten Wert abziehen und merken.
Ggf. noch irgendwelche Maximal-, Minimal- oder Mittelwerten berechnen und merken. (Nicht zu Viel Zeit in der ISR herumrechnen !
Damit kannst du dann zeitunkritisch in der standard loop oder sonstwie deine weiteren Berechnungen anstellen.

Ich möchte so genau wie möglich die Zahnzeiten messen, d.h. wie lange hat es gedauert, bis der Zahn durchlaufen ist und wie lange hat es gedauert, bis die Lücke durchlaufen ist

Du bekommst doch "pro Zahn" einen Impuls - oder ?
Wenn du den Durchmesser des Zahnrades, die Anzahl der Zähne und seinen Modul-Typ kennst, kannst du doch mathematisch die Breite eine Zahnes / der Lücke aus dem Winkel und jeweiligem Umfang errechnen.
Die Werte kannst du dann in Konstanten ablegen und jeweils damit be-/umrechnen.

Bliebe nur noch die Frage: An welcher Pos. von Zahn/Lücke meldet der Sensor den Puls (ansteigende oder fallende Flanke) ?
Das müsste man dann z.B. mit einem Stroboskop ermitteln und ebenfalls als "Versatz" (in Prozent/Promille) als const merken.

Alles weitere sind eigentlich nur Grundrechenarten. :slight_smile:

Naja...
Die Eingangsfrage war: "Ich möchte die Drehzahl eines Verbrennungsmotors erfassen."
Und jetzt soll jeder Zahn einzeln gestreichelt werden.

Ich finde: Das ist eine radikale Änderung der Anforderungen.


Meist fehlt ein Zahn, oder ein Zahn ist länger, als Maschinenlesbare OT Markierung

..... vielleicht hat sich eine (vermeintliche) Idee festgesetzt ....

Man bedenke: Bei einem Hubkolbenverbrenner bestehen nennenswerte Fliehkräfte im System, so dass sich hier sicherlich nicht schlagartig (von Zahn auf Zahn) Drehzahlen, Beschleunigungen oder sonstwas ändert.
Zudem ist es ein sich festes mechanisches System, wo sich z.B. die OT-Marierung für die (elektroische) Zündlage eher nicht ändert.
Sollte dem doch so sein, hat der Motor mit an Sicherheit grenzender Wahrscheinlichkeit einen kapitalen Totalschaden nach Kolbenfresser, Pleuelabriss mit Durchschlag o. ä.

Das Messen der Drehzahl über einen 58er-Zahnkranz ist hier eher schon Übergenau - muss doch eine Mindestdrehzahl gehalten werden, damit der Motor nicht abstirbt.
Bei ABS wird das auch so gemacht - da muss aber schon auf kleinste Raddrehungen, bzw. abrupte Blockierung reagiert werden.

Vielleicht klärt uns doglike noch mal im Detail auf, was Bezweckt wird ?!