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