PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahlberechnung



oZe
28.08.2008, 15:30
Hallo Jungs!
Ich habe ein kleines Problem und zwar steh ich grade auf dem Schlauch wie ich die Drehzahl eines Verbrennungsmotors errechnen kann. Ich habe das Zündsignal über einen Transistor an den Interrupt Eingang (Int0) meines Tiny2313 gehangen.
Ich habe mir jetzt überlegt die ms zwischen 2 Zündungen zu messen. Dazu würd ich einfach den Timer bei der ersten Zündung starten und bei der 2. Zündung stoppen. Jetzt hab ich aber das Problem, das ich den Timer nicht auf 1ms pro konfiguriert bekomme. Hat da jemand einen Tip für mich?

Jaecko
28.08.2008, 15:59
Hab bei meinem Drehzahlmesser auch zuerst die Zeit zwischen 2 Pulsen gemessen. Rausgekommen is nur Müll.
Habs dann so gemacht, dass ich dann ne halbe Sekunde lang einfach die Anzahl der Impulse mess.
Dann einfach mit nem Faktor multiplizieren und man hat die Drehzahl in U/min.
Wenn an der Stelle für jede Zündung ein Signal kommt, d.h. bei nem 4-Takter, 4-Zylinder pro Umdrehung 2 Pulse, dann wäre der Faktor einfach 60.
Hat den Vorteil, dass auch gleich ne Mittelwertbildung über ne halbe Sekunde mit drin ist.

oZe
28.08.2008, 23:59
Hmm das hatte ich auch zu erst überlegt. Die Zeitmessung zwischen 2 Pulsen wäre aber genauer denke ich. Naja ich werds dann wohl doch so machen das ich jeweils ne halbe sekunde messe und dann schaun wir weiter.

Sauerbruch
29.08.2008, 08:32
Also ich kann nur berichten, dass die Zeitmess-Variante vom Grunsdsatz her durchaus funktioniert. Ich habe damit eine Drehzahlmessung und -regelung für eine Winde für (ziemlich große) Modellsegelflugzeuge realisiert, die einwandfrei funktioniert.

Allerdings muss man den Timer gar nicht auf "gerade" Werte konfigurieren. Du kannst ihn beim 1. Interrupt starten und beim nächsten stoppen. Wenn Du weisst, wieviele ms (oder µs) ein Taktzyklus ist, musst Du nur noch den aktuellen Timer-Stand mit diesem Wert multiplizieren und hast die Umdrehungszeit. Das hat auch noch den Vorteil, dass nicht die Anzahl von Takten mit berücksichtigt werden muss, die zwischen dem Interrupt und dem Einspringen in die ISR vergehen. Das sind zwar nicht viele, aber auf die Dauer kann sich das schon bemerkbar machen.

Und der Timer sollte halt bei der langsamsten noch zu detektierenden Drehzahl nicht überlaufen - klar =P~

wkrug
29.08.2008, 08:33
Die Zeitmessung zwischen 2 Pulsen wäre aber genauer denke ich
Das kommt auf die zu messende Drehzahl an.
Mit der festen Torzeit 1/2 Sekunde ist die minimal zu messende Drehzahl 120U/min - bei einem Impuls pro Umdrehung.
Das alleine wäre noch nicht tragisch, allerdings bekommt man dabei auch eine Auflösung von 120 U/min.
Die Impulsabstand Methode geht bei niedrigen Drehzahlen sehr viel genauer. Wenn man allerdings mehrere Geber pro Umdrehung einsetzt müssen die schon sehr genau plaziert werden, da ja nach jedem Impuls eine Drehzahlermittlung gefahren wird ( werden kann ).

Gerade bei höheren Drehzahlen kommt aber bei der Impulsabstand Messmethode eine nicht zu Unterschätzende Belastung auf den Controller zu, da ja bei jedem Drehzahlimpuls eine Interruptroutine aufgerufen werden muß.
Diese Routine sollte möglichst schnell laufen und deshalb in Assembler geschrieben werden.
Die eigentliche Berechnung kann dann ja in der Hauptroutine erfolgen.
Ich konnte dabei schon einen Messumfang von bis zu 800000 U/min bei einem mit 8MHz getakteten ATMEGA 8 erreichen.

Für den günstigsen Ansatz halte ich die Verwendung beider Messmethoden mit automatischer Umschaltung.
Man lässt also beide Messmethoden gleichzeitig laufen, und verwendet für die Berechnung die, die für die gerade anliegende Drehzahl den geringsten Fehler produziert.

Bei mir geschieht die Umschaltung bei ca. 12500U/min.
Das muss aber für jeden Teilerfaktor und jede Controller Quarzfrequenz neu berechnet werden.

Für so eine Aufgabenstellung würde ich aber lieber einen Leistungsfähigeren Controller verwenden, z.B. einen ATMEGA 8, da der mehr Timer hat uns somit die Impulszählung in die Hardware verlegt werden kann, ein weiterer Timer als Zeitreferenz dienen kann ( Torzeitgenerator ) und der dritte Timer als Zähler für die Impulsabstand Methode verwendet wird.

Programmtechnisch am einfachsten zu realisieren ist natürlich die Impulszählung mit fester Torzeit.

oZe
29.08.2008, 14:59
Hat das jemand ein Beispiel da wie ich den Timer am besten konfiguriere? Ich steh da nach wie vor ein bischen auf dem Schlauch. Ich will ja die Zeit zwischen 2 Impulsen messen. Dazu muss ich also den Timer als Zeitgeber nutzen. Wenn mein Timer jetzt aber z.b. nicht immer genau nach sagen wir 1/2 Sekunde überläuft wie kann ich dann die Zeit berechnen?
Ich habe einen Drehzahlbereich zwischen 500 und 8000 rpm der gemessen werden soll. Was wäre da eine sinnvolle konfiguration?

wkrug
29.08.2008, 16:19
Hat das jemand ein Beispiel da wie ich den Timer am besten konfiguriere? Ich steh da nach wie vor ein bischen auf dem Schlauch. Ich will ja die Zeit zwischen 2 Impulsen messen. Dazu muss ich also den Timer als Zeitgeber nutzen. Wenn mein Timer jetzt aber z.b. nicht immer genau nach sagen wir 1/2 Sekunde überläuft wie kann ich dann die Zeit berechnen?
Das ist eigentlich gar nicht so kompliziert.
Du benutzt z.B. für den 16Bit Timer einen Prescaler von 8 bei einer Quarzfrequenz von 8MHz.
Also liegt am Timer eine Frequenz von 1MHz an.
Ein Count hat somit eine Periodendauer von 1/1MHz = 1µS.
Einem Zählerstand von 500.000 würde somit einer Zeitdauer von 0,5 sek entsprechen.
Da aber auch ein 16Bit Timer maximal 2^16 = 65536 Takte zählen kann musst Du in der Timer Overflow Routine einen zusätzlichen Zähler mit hochzählen. Dieser Zähler * 65536 + dem aktuellen Zählerstand des 16 Bit Counters kann man dann die Zeit zwischen 2 Impulsen deines Drehzahlsensors umrechnen und daraus die Drehzahl berechnen.

Das hört sich im Prinzip etwas kompliziert an, mit ein wenig Überlegen ist das dann aber eigentlich nicht wirklich ein Problem.

oZe
30.08.2008, 03:11
Das hatte ich mir so auch schon überlegt. Dann könnte ich den Timer auch einfach auf 1ms konfigurieren und in der ISR einfach eine Variable hochzählen. Daraus lässt sich natürlich die drehzahl dann errechnen. Ich hatte nur gedacht, das es eventuell möglich wäre den Timer so langsam zu konfiguriere, dass er nicht überläuft. Somit würde man sich den umweg über den 2. Zähler sparen was ein wenig Zeitunkritischer wäre aber ich werde es dann wohl doch so realisieren wenns anders nicht geht.
Ich schilder mal kurz meinen geplanen ablauf:

Der erste Impuls am Eingang kommt an und der Timer läuft los und läuft jede ms über. Somit wird meine Zählervariable hochgezählt in der ISR. Wenn der 2. Impuls kommt stopt der Timer und ich lese aus wie hoch meine Zählervariable steht. Als beispiel nehme ich mal einfach 70. Jetzt weiß ich, dass zwischen 2 umdrehungen 70ms liegen. Ich rechne dann also 60000/70 = ~857 rpm.
Jetzt muss ich noch den Timer wieder auf 0 setzen (denke ich jedenfalls mal) und es kann weiter gehen.
In meiner Rechnung vernachlässige ich maximal eine Millisekunde, da ich den letztn Timerwert nicht mehr mit berücksichtige. Das ist für meine Anwendung aber nich wirklich kritisch. Viel wichtiger ist jetzt zu wissen ob ein gravierender Messfehler auftritt aufgrund der vielen Interrupts die der Timer auslöst.
Außerdem weiß ich nicht, was passiert wenn der Controller gerade meine Drehzahl errechnet und dann ein Interrupt von Eingang ausgelöst wird. Angenommen das Programm springt gerade in den Teil, in dem die Drehzahl berechnet wird (in meinem bsp. 60000/70) und in dem moment kommt wieder ein Zündsignal. Wird dann aus der ISR des Timers rausgesprungen und in die ISR des Eingangs gesprungen oder wird erst die Timer ISR komplett ausgeführt?

wkrug
30.08.2008, 08:21
Der erste Impuls am Eingang kommt an und der Timer läuft los und läuft jede ms über. Somit wird meine Zählervariable hochgezählt in der ISR. Wenn der 2. Impuls kommt stopt der Timer und ich lese aus wie hoch meine Zählervariable steht. Als beispiel nehme ich mal einfach 70. Jetzt weiß ich, dass zwischen 2 umdrehungen 70ms liegen. Ich rechne dann also 60000/70 = ~857 rpm.
Das mit dem aug 0 stellen muß so nicht sein.
Leg doch nach der Drehzahlberechnung die aktuellen Zählerstände in einer Variable z.B. Oldvalue ab.
Beim nächsten Drehzahlimpuls ziehst Du dann vom aktuellen Zählerstand diese Oldvalue Variable ab und erhältst als Ergebnis wieder deinen Zählerstand, der der Zeit zwischen 2 Impulsen entspricht. Den neuen aktuellen Wert legst Du dann widerum in der Variable Oldvalue, für die nächste Berechnung, ab.
Der Vorteil der Methode ist, das man bei jedem Geberimpuls eine Aussage über die Drehzahl machen kann und nicht nur bei jedem 2ten.
Wenn die Variablen als unsigned definiert werden, sollte es auch keine Probleme bei einem Zähler Überlauf geben, der ja zwangsläufig irgendwann stattfindet.
Allerdings darf natürlich die Zeit zwischen 2 impulsen niemals so lange werden, das der Zähler sich einmal komplett überholt.
Ich hab das so gelöst, das im Hintergrund ein Timer mitläuft, der bei jedem Interrupt Impuls hochgezählt wird. Wenn dieser Zähler eine bestimmte Grenze erreicht wird ein Flag gesetzt und in der Drehzahlberechnung das nächste Ergebnis als null dargestellt.
Ich glaube auch, wenn Du nur die Impuls Abstand Methode wählst, das Du mit dem ICP Pin ( Input Capture Pin ) genauere Ergebnisse kriegt.
Da es hier um mehrere Timer geht, hatte ich auch den ATMEGA 8 vorgeschlagen.

oZe
30.08.2008, 14:03
Mit Sicherheit ein sehr guter ansatz! Jetzt muss ich einfach mal anfangen zu testen denke ich. Ich danke euch und speziell wkrug für die nette Hilfe!