Hallo
Ich möchte einen Drehzahlmesser bauen, unter Verwendung des 8515. Ich
habe bereits den 16-Bit Timer aktiviert, der die Zeit zwischen zwei
Zündimpulsen misst. Jetzt stehe ich jedoch bei einem Problem an, wie
wandle ich diese Zeiteinheit in eine proportionale Drehzahl um, die ich
dann ausgeben kann. Wie Ihr sicher wisst entspricht RPM = 1/s .
MfG
Knut
moin, ein timer zählt im prozessortakt, und dieser hängt vom verwendeten
quarz und einer eventuellen internen Teilung ab, also wenn der timer bis
100 hochzählt dann 100 x Dauer eines Prozessortaktes.
das mal so als Anstoß
hm, auch auf die Gefahr hin das ich das wieder falsch verstehe,
du hast die Zeit zwischen zwei funken also weißt du auch wie lange 2 bzw
1 kw-Umdrehung(2takter) dauern,
so,und nun ist das doch nur noch rechnerei auf die richtige Basis sprich
minuten, z.b. zeitdauer 2 sekunde, das mancht bei 4 takter eine
umdrehung je 1 s, mal 60 und dann hast du 60 Upm.
und diese berechnung müsste man dann in bestimmten zeitabständen
wiederholen, aber was vieleicht noch besser ist, bezüglich konflikte mit
rechenzeit oder sowas, einfach die zeit für ein paar mehr zündimpulse
zählen und dann erst berechnen.
Wenn genug Speicher übrig ist und keine hohe Auflösung benötigt wird,
dann würde ich die Umwandlung Zeit -> Frequenz einfach mit einer Tabelle
(Lookup-Table) machen.
Salut,
@Knut: Nun, eigentlich ist "RPM" bereits eine Einheit und steht (die der
Name schon sagt) für 2pi/60s.
Das heißt, Kreisfrequenz [omega]=2pi/s einfach mal als [f]=1Hz
formuliert:
f = CLK / T ; CLK ^= präskalierter Timertakt; T ^= gemessene Zeit für 1
Umdrehung
also per Minute:
f_RPM = (60 * CLK) / T ; (60 * CLK) = const.
Also bräuchtest Du nur noch eine Division.
"Bräuchtest" deswegen, weil Deinem Verfahren leider ein Designfehler
innewohnt. Schonmal überlegt, was passiert, wenn die Motorwelle
stillsteht? Für eine Frequenzmessung solltest Du deshalb eine feste
Torzeit verwenden. Das heißt: Drehzahlausgang des Motors an T0 oder T1
legen und den jeweiligen Timer als Event-Counter verwenden. Dann kannst
Du per Zeitschleife (oder mittels freiem Timer) die Torzeit lang warten
und anschließend den proportionalen(!) Wert auslesen. Alles, was dann
noch fehlt ist eine Multiplikation. Wenn Du die Torzeit clever wählst
(exakte Länge evtl. per Timer Match messen), genügt es vielleicht, den
Timer-Wert etwas herum zu shiften. :)
Hoffe, das hilft. Viel Spaß beim Basteln!
Mark H. -- http://markh.de/avr/
Mit einem externen Interrupt (z.B. int0) die Impulse zählen, parallel
einen Timer eine konstante Zeit laufen lassen und nach Ablauf Zähler
auslesen und löschen.
Gruß, Jürgen
Danke Mark & Jürgen, auf diese Weise habe ich es mir gar noch nicht
überlegt, ich werde nun eine geeignete Zeit durchlaufen lassen und
während dieser jeden Zündimpuls zählen. Somit kriege ich eine
Proportionalzahl ohne Dividieren zu müssen -> genial!
Wenn ich 0.3s lang warte, habe ich Ideale Voraussetzungen, das wären
1/200min damit 1/100rpm bei einem Viertakter.
So sollte ich es hinkriegen.
Hallöchen!
Da ich auch gerade dabei bin, einen Boardcomputer mit nem 8515 zu bauen,
könnte es interessant sein, die Überlegungen auszutauschen. Wie oben
schon festgestellt: Es gibt 2 Möglichkeiten, eine Frequenz zu messen.
(Im Grunde genommen sind die Motordrehzahlen nix anderes.) Die eine
Möglichkeit ist es, den Zeitabstand zwischen zwei Impulsen zu messen und
das dann umzurechnen, die andere Möglichkeit besteht darin, die Anzahl
der Impulse in einer festgelegten Zeit (=Torzeit) zu zählen. Beides hat
Vor und Nachteile.
Bei meinen Überlegungen habe ich festgestellt, daß die zweite
Möglichkeit, die Impulse während einer festen Torzeit zu messen, zwar
recht einfach, aber auch recht ungenau ist...
Mein Motor läuft im Standgas bei etwa 800 Umdrehungen pro Minute. Das
sind also 400 Zündungen je Zylinder. In der Sekunde sind das also
400/60=6,666 Impulse. Wenn ich jetzt nur 0,3 Sekunden warte, dann
bekomme ich meist nur 2, manchmal aber 3 Impulse innerhalb einer
Torzeit. Das heißt, meine Anzeige würde zwischen 800 und 1200 RPM
springen. Die Auflösung der Anzeige beträgt gerade mal 400 RPM!
Denn:
0,3 Sekunden Torzeit entspricht einer Frequenz von 3,33333 Hz. Pro
Minute sind das (3,33333*60) genau 200 Abtastungen. Bei einem 4-Takter
habe ich dann exakt 400 Umdrehungen pro Minute, da nur jede 2. Umdrehung
gezündet wird. Somit hat Knut einen Denkfehler in seiner Rechnung, denn
er hat bei 0,3s nicht 1/100rpm sondern 1/400rpm. (Oder liege ICH jetzt
komplett falsch?)
Um auf die Auflösung von 100rpm zu kommen (was MIR immer noch viel zu
ungenau ist), stelle folgende Überlegung an:
100rpm = 50 Zündungen pro Minute = 0,83333 Zündungen pro Sekunde = 1,2
Sekunden Zeit zwischen 2 Zündungen. Die Torzeit müßte also 1,2 Sekunden
betragen, um eine Auflösung von 100rpm zu bekommen.
Bei 800rpm habe ich in 1,2 Sekunden also genau 8 Impulse. Beträgt die
Drehzahl des Motors allerdings z.B. 830rpm wären das 8,3 Impulse in 1,2
Sekunden. Da ja aber logischer Weise nur ganze Impulse gezählt werden
können, habe ich meistens 8 Impulse, durch die Phasenverschiebung
zwischen Abtastung und Impulsen aber manchmal auch 9 Impulse. Meine
Anzeige springt also zwischen 800 und 900rpm ständig hin und her.
*** Fazit:
Meiner Meinung nach kann bei einer so niedrigen Frequenz lediglich eine
einzige sinnvolle Messmethode stattfinden: Messung der Zeit zwischen der
Impulse und anschließende Umrechnung. Den Code dazu in Assembler sollte
nicht so schwer hinzubekommen sein, zum Glück gibt es ja die
ASM32-Routinen, die sich umbasteln lassen :-)
Ich fange gleich mal mit den Überlegungen hierzu an: Ich wähle einen
Zähler, der alle 1,2ms um eins erhöht wird. Bei 100rpm habe ich dann
einen Zählerstand von exakt 1000. Ich brauche also nur die Formel
rpm=100000/Zählerstand
zu verwenden. fertig. Einwände? Denkfehler? Ich lasse mich gerne
Korrigieren! :-)
Da die Berechnung im AVR ja binär erfolgt müssen nach der Berechnung die
Zahlen nur noch zur Ausgabe umgewandelt werden
Den Code dazu (in Assembler) werde ich mir nachher mal überlegen. Sollte
ich es gebacken kriegen, werde ich ihn hier posten. :-)
ciao,
Andi
Du hast recht was die Genauigkeit angeht, das würde recht ungenau werden
mit der Torzeitvariante. Ich sehe eine Präzise Lösung auch nur mittels
Zeitmessung. Ich sehe nicht ganz wie du die Zahl 100'000 generieren
möchtest, dazu müsstest du ja 3 Register verwenden, ich hatte eine sehr
ähnliche Lösung im Kopf bevor ich den ersten Beitrag hier gepostet habe.
Evtl könnte man alle 2.4ms zählen und 50'000/Zählerstand rechnen, das
würde jedoch der Genauigkeit schaden.
Hallo Knut!
Ich bin gerade dabei in Assembler den Code zur Umrechnung zu schreiben
und bin fast fertig. Soviel schonmal vorweg: Du hast recht, ich benötige
für die Zahl "100000" 3 Bytes. Nachdem ich aber noch einige Überlegungen
gemacht habe, sind die genannten Werte nicht mehr ganz korrekt, aber die
Größenordnung kommt schon hin. Als Dividend nehme ich jetzt 3750000,
gezählt wird alle 32µs. Nur so wirds einigermaßen genau, auch noch in
den oberen Drehzahlen...
( Gib mir noch ne Stunde, dann gibts mehr. Auch den ersten Code... :-)
ciao,
Andi
Soooo!
Den ersten Abschnitt des Programmes hab ich jetzt fertig. Bisher
lediglich die Berechnung. Was noch fehlt ist die Zählersteuerung und
übriger Klimbim wie Ausgabe etc. Allerdings habe ich schon folgende
Überlegungen gemacht:
Man nehme den Timer1 des 8515 und konfiguriere ihn so, daß er bei jedem
256. Takt des Prozessortaktes einen hoch zählt. Der Takt des Prozessors
muß dabei auf 8MHz liegen. Daraus resultiert dann, daß alle 32µs der
Timer um einen erhöht wird.
In einer Schleife wird ein beliebiger Porteingang des uC überwacht.
Sofern an diesem Eingang der Zündimpuls erkannt wird, wird der
Zählerstand in die Register 16/17 übernommen und zurück gesetzt. Im
Hintergrund läuft der Zähler jetzt schön wieder hoch bis zum nächsten
Impuls. Bis dieser kommt, haben wir genug Zeit, die Berechnung zu
starten und noch andere Dinge zu tun. (Siehe Code im Anhang). Zum Ende
springen wir dann wieder in den Abschnitt der Zählersteuerung. ->
Endlos...
In die Zählersteuerung kann man jetzt noch ne Art Überlauferkennung
einbauen um zum Beispiel darauf zu reagieren, wenn die Umdreheungen
kleiner als 100rpm sind. Das könnte man dann als "Motor steht"
auswerten. Genauso kann man auch eine (einstellbare) Höchstdrehzahl
festlegen und warn-LEDs ansteuern. und was einem noch alles so einfällt.
Wie wäre es z.B. zusätzlich zur Anzeige per LCD (oder 7-Segment-LEDs)
mit einer LED-Balken-Anzeige?
Fragen? Was falsch? Verbesserungen oder Vorschläge? Immer her damit! :-)
ciao,
Andi