Forum: Mikrocontroller und Digitale Elektronik Drehzahlmesser mit ATmega 16


von Zoffi (Gast)


Lesenswert?

Hallo,

ich will mir einen Drehzahlmesser für mein Auto bauen.
Also ich hab mir das so vorgestellt:
Sobald eine Zündung erfolgt wird per Interrupt der Timer ausgelöst und
beginnt zu zählen. Kommt wieder eine Zündung stopt der Timer und der
µC
kann dann die Drehzahl ausrechnen und auf einem Display ausgeben.
Aber jetzt kommt der schwierigere Teil: Die Rechnung!
Von Zündzeitpunkt zu Zündzeitpunkt bedeutet eine Umdrehung. Der Timer
erfasst die Zeitzyklen die der Motor für eine Umdrehung braucht.
Demnach komme ich auf diese Formel wenn ich das Ergebnis in 1/min
haben
will.

60/[Zyklen*(1/CPU Takt/1024)]

Der Term in der () entspricht dem Prescaler der auf 1/1024 eingestellt
ist.
Wie führe ich diese Rechnung aus? Es handelt sich dabei um einen 16Bit
Timer.
Wie kann ich ein Registerpaar (16Bit) mit einer Zahl multiplizieren
oder dividieren?

Ich programmiere in Assembler!

P.S. Ich habe aus versehen den Beitrag zuvor unter Codesammlung
reingestellt, sorry.

von Florian Pfanner (Gast)


Lesenswert?

Schau mal bei www.atmel.com vorbei. Dort gibts zu den AVR-Controllern
Application-Notes. In einem ist auch das Multiplizieren in Assembler
beschrieben.

Gruß, Florian

von Zoffi (Gast)


Angehängte Dateien:

Lesenswert?

Danke für den Tipp,

ich habs gefunden leider ist eine der beiden asm Dateien total
durcheinander gewürfelt!(siehe Anhang)
Woran liegt das kann einer das auf die Reihe bekommen?

von Chris (Gast)


Lesenswert?

Hallo,

folgende Application Note:

"AVR200: Multiply and Divide Routines (19 pages, updated 10/98)
This Application Note lists subroutines for multiplication and Division
of 8 and 16-bit signed and unsigned numbers. "

Am besten die Beispiele nacheinander im Simulator ausprobieren und
damit experimentieren. Da gibt es geschwindigkeitsoptimierte und
Codegrößeoptimierte Versionen.

Gruß

von Werner A. (Gast)


Lesenswert?

Das die "durcheinander" gewürfelt sind, hängt damit zusammen, das sie
wahrscheinlich unter Unix geschrieben wurden. Da sind die zeichen für
Zeilenende und Zeilenumbruch anders (oder so ähnlich).
Auf jeden Fall musst du die Dateien eigenlich nur in einem anderen
Editor öffnen. Dann sollte alles wieder stimmen.

Werner

von Florian Pfanner (Gast)


Angehängte Dateien:

Lesenswert?

Hab se mal formatiert.

Gruß, Florian

von Zoffi (Gast)


Lesenswert?

@Werner

Du hast Recht! Wenn ich die Datei mit dem WordPad öffne sieht das ganze
schon viel aufgeräumter aus. :-)

Was ich noch nicht verstehe: Was bedeutet diese "+" hier ->
16/16=16+16 oder 8/8=8+8
Bei der Multiplikation steht das so dar -> 8x8=16 oder 16x16=32

Wie sieht das ganze denn aus wenn ich 32Bit dividieren bzw.
multiplizieren will?

von Zoffi (Gast)


Lesenswert?

Wieso ich mit 32Bit rechnen will liegt daran:

Ich habe die Formel mal umgeschrieben und da ja der CPU Takt konstant
ist komme ich bei 16MHz Takt auf diese neue "einfachere" Formel

937500/Zyklen des Timers=RPM

von TobyTetzi (Gast)


Lesenswert?

Hallo,

bist Du schon weitergeekommen mit deiner Drehzahlmessung?

Würde mich auch intressieren, da ich Momentan mit einem Mega 8 die
Drehzahl meines Modellhelis erfasse.

Allerdings will ich die "Zahlen" auf eine etwas üngewöhnliche wiese
anzeigen.

Gruß Toby

von David (Gast)


Lesenswert?

Hi, kannst du nicht einfach die Spannung messen die die Lichtmaschine
erzeugt??
So hatte ich mir das ganze nämlich schon mal vorgestellt.

mfg
David

von Hagen (Gast)


Lesenswert?

>as ich noch nicht verstehe: Was bedeutet diese "+"
>hier -> 16/16=16+16 oder 8/8=8+8

Du teilst ja 16 Bit Dividend durch den 16 Bit Divisor und erhältst
jetzt ZWEI Werte a 8 Bit. Einmal 8 bit den Quotienten und einmal 8 Bit
den Remainder = Rest der Division.

Also A / D = q*D+r, d -> Quotient, r -> Rest sind die beiden 8 Bit
Werte, oder eben

16 Bit Divident / 16 bit Divisor = 8 Bit Quotient + 8 Bit Remainder,
16 / 16 = 8 + 8.

Gruß Hagen

von Dom (Gast)


Lesenswert?

Ich habe vor kurzem was ähnliches realisiert. Drehzahl / Frequenz
Anzeige z.B. für Motoren oder einfach als Frequenzzähler.
Das ganze wird auf fünf 7-Segmentanzeigen angezeigt.

Ich verwende den AT90S2313 und bin mit dem Projekt in C eingesteiegen
(Codevision).

Je nachdem ob man per Software oder Hardeware die BCD Codes zu
/-Segment dekodiert, schafft die schaltung bei 10,24 Mhz bis zu 80000
Impule pro Sekunde. Dann fängt die gemultiplexte Anzeige an zu
flackern, aber es lässt sich sicher noch was optimieren.

Bei Interesse kann ich den Code ja mal hier posten...

Gruß, Dominik

von Chris (Gast)


Lesenswert?

@Dom

Würde mich sehr für deinen Code interessieren.
Noch interessanter wäre aber für mich die Hardware-Seite.
Wo am Auto hast du das Drehzahlsignal genommen und wie hast
du das Signal fürn AVR konvertiert?


mfg Chris!

von TobyTetzi (Gast)


Lesenswert?

Hallo,

mich würde der Code auch sehr Intressieren.

Gruß Toby

von Zoffi (Gast)


Lesenswert?

Also bis jetzt hatte ich noch nicht die Zeit, aber ich werde im Laufe
der Woche die Sache mal angehen.
Eine zweite Möglichkeit ist die Zündungen (Umdrehungen) innerhalb einer
Sekunde zu zählen und diese dann mal 60 multiplizieren. Dann käme man
auch auf die RPM.
Ich werde mal ein bischen rumprobieren. Wenn ich dann was Brauchbares
hab kann ich das auch hier reinstellen.

von Dom (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
im Anhang ist ein RAR-Archiv mit Eagle-Schematic und C-Code.

Ich habe es bisher nur mit E-Motoren getestet und einfach ne
Lichtschranke mit nem Foto-Transistor benutzt, der dann die Impulse
erzeugt hat.

Allerdings wurde die Hardware für Zündimpulse usw. schon oft hier
diskutiert...

Könnte mir vorstellen einfach ne Leitung um ein Anlasser kabel zu
wickeln und dann das ganze zu verarbeiten. Wird ja nicht das große
Problem sein.

Noch was zum Code: Man kann natürlich beliebig muzltiplizieren und
dividieren wie man will. Momentan beträgt die Messzeit 1s, da ich es
nur mit recht langsamen Motoren getestet habe.

Gruß, Dominik

von Peter D. (peda)


Lesenswert?

@Dominik,

"Je nachdem ob man per Software oder Hardeware die BCD Codes zu
/-Segment dekodiert...Dann fängt die gemultiplexte Anzeige an zu
flackern"

Verstehe ich nicht, wo wird denn dabei Zeit verbraten ?
Ein LPM dauert doch gerade mal 3 Zyklen.

Mach doch die Dekodierung mit im Hauptprogramm, dann kannst Du im
Multiplex-Timerinterrupt die Codes direkt ausgeben.
Damit kannst Du bequem mit 100kHz multiplexen.
Kein Flimmern hast du aber schon bei 1kHz, das sind dann bei 5 Anzeigen
200Hz Wiederholfrequenz.


Peter

P.S.:
Mein Windows-XP guckt nur blöd, wenn ich ihn mit RAR füttere und bei
EAGLE wirds wohl genau so sein.
Kannst Du vielleicht ZIP und PDF, dann kann sichs jeder ohne
Spezialprogramme ansehen.

von Dom (Gast)


Angehängte Dateien:

Lesenswert?

@ Peter:
Ich habe mit 80kHz die Eingangsfrequenz der Schaltung gemeit, also bei
80000 Interrupts pro Sekunde fängt die Anzeige an zu flackern. Die
Dekodierung ist bereits im Hauptprogramm, dort wird auch gemultiplext.
Und da machen sich auch die 3 Zyklen bemerkbar, wenn man's decodiert.
Wenn mans komplett in ASM macht wird man das ganze auch wohl um einiges
schneller hinbekommen, aber das war bei der Schaltung keines weg's
mein Ziel.
Wie gesagt, bin gerade mit C angefangen habe µC's bisher nur etwas in
ASM programmiert. Sonst halt nur Windows-Programmierung mit Delphi und
php.

Gruß, Dominik

P.S.: RAR ist für mich genau so Standard wie Zip. Außerdem sind wir
hier im Elektronik - Forum. Da gehe ich davon aus, dass die meisten
wenigstens die Demo von Eagle installiert haben. Darüber möchte ich
hier aber gar nicht diskutieren, also siehe Anhang.

von Peter D. (peda)


Lesenswert?

Im Hauptprogramm zu multiplexen ist natürlich der absolut ungünstigste
Ansatz. Da hat dann ja jede Programmänderung direkten Einfluß.

Ich mache das Multiplexen grundsätzlich immer im Timerinterrupt. Dann
braucht man nie wieder dran zu denken und kann im Hauptprogramm machen
wozu man lustig ist.

Wenn die Frequenz zu hoch ist, solltest Du besser einen Timer als
Counter nehmen (z.B. T0). Damit hast Du dann viel weniger Interrupts.
Bei 10Mhz Quarztakt kannst Du dann bis 5MHz messen (ohne Vorteiler).


Peter

P.S.:
Ich hab schonmal was von RAR gehört, aber Windows-XP eben nicht.
ZIPen können dagegen alle, sogar UNIX Rechner (SUN).
Ich arbeite mit Protel, andere Leute mit Orcad usw.
Das jeder Eagle haben muß, ist daher nur ein Gerücht.

von Dom (Gast)


Lesenswert?

Wird das Programm größer ist es natürlich günstiger das Multiplexen über
einen Timer zu realisieren. Wenn der µC allerdings nichts anderes
erledigen soll spielt das doch keine Rolle.

Aber das mit dem Timer als Zähler werde ich wohl noch mal ausprobieren.
Da mein zweck der Schaltung eher zur Frequenzmessung anstatt der
Drehzahlmessung dienen soll.

Gruß, Dominik

von Zoffi (Gast)


Lesenswert?

Hallo,

ich hab jetzt mal die Methode "1/2Sekunden lang Zündungen zählen"
ausprobiert. Leider habe ich noch das Problem die errechnete 16Bit Zahl
an das Display auszugeben. Wenn ich dem Display die 16Bit schicke kommt
natürlich nicht die Zahl in Dezimal raus sondern irgendein komisches
Zeichen. Wie kann ich die Zahl den so umformen das jede Ziffer in 8Bit
an das Display gesendet wird?
Also wenn ich zum beispiel diese Zahl errechnet habe:
0b0001100101100100 = 6500(Dezimal)
dann muss ich die 6,5,0,0 jeweils als (8Bit) Dualzahl an das LCD
schicken.

von Cambrino (Gast)


Lesenswert?

Hallo Zoffi

Ein 4-Taktmotor macht pro Zylinder nur alle 2 Umdrehungen eine Zündung

Gruss
Camrino

von TobyTetzi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein kleines Programm für einen Mega 8.
Hier geht es auch um Drehzahlmessung, allerdings
mache ich mit der Errechneten Drehzahl etwas anderes.

Schau Dir das Bild einfach mal an.

Um die Drehzahl anzuzeigen, müßtest Du nur eine 16 Bit Zahl,
1000 durch eine 16 Bit Zahl aus dem Timer, (ms/Umdr.) teilen.
Dann das ganze mal 60 und Du hast die Drehzahl.

(Allerdings bei jeder Umdrehung einen Interrupt mit eienem Hallgeber)
Bei einem 4 Takter muß man dann das Ergebniss mal 2 nehmen,
da man nur jede 2te Umdrehung eine Zündung(Interrupt) hat.

Zumindest meine ich das, kann es aber noch nicht selbst Programmieren.


Gruß Toby

von TobyTetzi (Gast)


Angehängte Dateien:

Lesenswert?

...und weils so schön ist....


noch ein Bild.

Gruß Toby

von Christof Krüger (Gast)


Lesenswert?

Das sieht ja sehr nett aus, TobyTetzi! Sieht man das auch in natura gut?
oder nur auf Fotos?
Wenn man dafür sorgt, dass keiner gegenläuft, dann ist das allemal
Partytauglich!

von TobyTetzi (Gast)


Lesenswert?

Hallo,

in Natura sieht es noch besser aus.

Aber ich plane, damit noch mehr.

Ein kleines Problem hab ich noch bei bestimmten Drehzahlen,
da es sich um Kommazahlen der Umdrehungszeit handeln kann,
flackert es ab und zu.

Gruß Toby

von Zoffi (Gast)


Lesenswert?

@Cambrino

Ja du hast recht, aber ich greif das Signal an der Zündspule ab und da
der Moter 4 Takte bei 4 Zylindern durchläuft, findet jede Umdrehung
eine Zündung statt.

von TobyTetzi (Gast)


Lesenswert?

Hallo,

wenn das so ist, könntest du ja schon Teile meines Programmes nutzen.

Aber nur, wenn Du mir bei Erfolg sagst, wie ich bei mir die Drehzahl
anzeigen kann!

Gruß Toby

von Zoffi (Gast)


Lesenswert?

Also ich hab noch ein Problem ich muss die 16Bit Zahl nach ASCII
konvertieren, um es auf dem Display auszugeben. Ich habe im Forum schon
was gefunden aber hier handelt es sich um 32Bit:
http://www.mikrocontroller.net/forum/read-4-594.html
Vielleicht kann das einer mal für 16Bit umschreiben.

von Zoffi (Gast)


Lesenswert?

Also hier nochmal der direkte Link zur ASM Datei
http://www.mikrocontroller.net/attachment.php/39087/Bcd32b.asm

von Dom (Gast)


Lesenswert?

Du brauchst nur Routinen um ne binäre Zahl in BDC - Digits umzuwandeln.

Die kann man sich ganz einfach selber schrieben, wenn man es nicht
schafft hier danach zu suchen.

Beipsiel für eine 16Bit Zahl (x):

Von der x so oft 10000 abziehen, bis die zahl < 0 ist. Die Anzahl wie
oft du die 10000 abziehst ist die Zehntausender stelle + 1 (also einen
abziehen). Dann zu X wieder 10000 addieren, so dass die Zahl wieder > 0
ist.
Dann von X so oft 1000 abziehen, bis die Zahl wieder < 0 ist. Und so
weiter und so weiter......
Das ganze mit 100 und 10, der Rest zum Schluss (nachdem man zum
negativen Ergebnis wieder 10 addiert) ist die Einerstelle.

Ich habe glaube ich einfach immer 0x30 zu meinen Digits addiert und sie
dann zum LCD geschickt.

Gruß, Dom

von Dom (Gast)


Lesenswert?

Achja, @TobyTetzi:

das sieht ja mal richtig cool aus. =)
Kannst du mal ein bisschen mehr zur Hardware schreiben? Wie schnel
lsdreht sich das ganze, wie läuft das Progamm ab, wieviele LED's, wie
bekommst du die Energie auf den rotierenden Teil?

von Zoffi (Gast)


Lesenswert?

@Dom

So weit habe ich es verstanden, aber was meinst du mit dem letzten
Satz? Das du einfach immer 0x30 addiert hast?

von Joern Gerhard (Gast)


Lesenswert?

@Toby: da hast du aber etwas richtig cooles geschaffen! :-) Gefällt mir!
Die schönste Anzeige dieser Art die mir bisher untergekommen ist!!!
Glückwunsch!
cu joern

von Stromi (Gast)


Lesenswert?

@tobi.
das sieht ja geil aus. ich habe mal sowas mit propellerclock und einem
pic gemacht. habe, wie in der seite beschrieben, eine videokopfscheibe
umgebaut. geht aber nur gut wenn der strombedarf klein ist. und total
unwuchtig, jedenfalls meins...
kannst du mal detail's mailen. ist very intressting...


ich weiß nicht ob jeder propellerclock kennt. hier der link:
http://www.bobblick.com/techref/projects/propclock/propclock.html

mfg

von TobyTetzi (Gast)


Lesenswert?

Hi Stromi,

was möchtest du wissen?

Es ist ein Mega8, 20 LEDs von Ebay, ein Hallgeber.
Ein Taster (sollte zur Bildumschaltung dienen - binn aber zu dumm
zum Programieren).

Angetrieben von einem 650 Mabuchimotor wird ein APC 16x4 Propeller,
auf dem alles drauf sitzt.

Drehzahlen hatte ich bis jetzt max. 2500 U/min.
Ich weiß nicht, ob mehr gehen, aus Angst den Accu zu verlieren.

Bei weiterer Intresse, mail mal deine Email Adresse.

Ich habe da noch so einige ideen, aber kann diese mit meinem
Technischen Stand leider nicht realisieren.

Eigentlich habe ichhier ja auch nur Hilfe gesucht.

Gruß Toby

von Zoffi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab jetzt das Programm fertig. Aber leider funktioniert es nicht so
richtig, das Display "flackert" und er zählt die Impulse einfach
nicht.
Vielleicht kann jemand mal drüber schauen, Die LCD Routinen sind für
4MHz geschrieben und ihc betreibe ihn mit 16MHz. Ich glaub aber nicht
das es daran liegt(vielleicht doch?).

von Zoffi (Gast)


Lesenswert?

Hmmm,

ich weiss nicht wo der Fehler liegt. Etwa bei der BCD Konvertierung?
:-(

von Cambrino (Gast)


Lesenswert?

Hallo Zoffi

Die kleinste Drehzahländerung für zu einem anderen Ergebnis was
vielleicht zum flackern führt?

Gruss
Cambrino

von Zoffi (Gast)


Lesenswert?

Ich glaub es liegt daran das ich das Display nach jeder neuen Rechnung
lösche und dann die Werte ausgebe.
Was aber auch ein Problem ist, dass ich keine Zahlen sondern komische
Zeichen angezeigt bekomme und die sich auch nicht verändern. (Ich habe
dazu am Ende eine Endlosschleife eingebaut, um mal das was auf dem LCD
steht lesen zu können)
Also denke ich das der Fehler womöglich in der Konvertierung von BIN zu
BCD liegt.
Vielleicht kann sich einer diesen Abschnitt genauer anschauen.

von Thomas Oly (Gast)


Lesenswert?

Hallo,

ich habe auch noch einen Vorschlag der etwas keichter zu realisieren
ist. Man nimmt einen Frequenz/Spannungswandler LM2907 und gibt den
Spannungsausgang auf den A/D-Wandler so braucht man keine komplexen
Berechnungen programmieren.

von Thomas Oly (Gast)


Lesenswert?

Hallo,

sorry hatte vergessen die Mailbenachrichtigung einzuschalten.

von Tobias Schilgen (Gast)


Lesenswert?

@Zoffi:

hallo - bin gerade selber dabei, einen Frequenzzähler zu
implementieren und habe mir daher deinen Code mal angesehen.

er läuft bei mir auf einem ATMega32 mit 16 MHz.

ein erster Hinweis: die Verzögerungsschleifen für die LCD
Ansteuerung sind für 4 MHz bemessen - daher habe ich sie
auf 16 MHz angepasst.
Ausserdem habe ich den Aufruf LCD_Clear durch
LCD_CursorHome ersetzt - nun wird nicht mehr das ganze Display
gelöscht sondern nur der Cursor in die linke obere Ecke gesetzt,
so dass die nächste Ausgabe die alte überschreibt.

Die Ausgabe bleibt jedoch genauso, wie Du es beschrieben hast.

Die Binär zu BCD Wandlung habe ich nicht nachvollziehen
können und glaube, dass dort die Register ein wenig durcheinander
geflogen sind:
bei der Wandlung werden lediglich die Register
 R16, R17, R18, R19, R20, R28, R29, R30 und R31
verändert,

in der LCD-Ausgaberoutine werden jedoch die Register
R22 bis R26 ausgegeben - genau diese wurden zuvor
in der BCD-Wandlung nicht berührt... (???)

Tobias.

von Zoffi (Gast)


Lesenswert?

Ja, das mit dem "LCD_clear" hab ich auch schon abgeändert.
Ich werd mir die Register nochmal anschauen. Es wurde halt notdürftig
zusammen gefügt, dabei hab ich jetzt nicht so auf die Register
geachtet.

von Tobias Schilgen (Gast)


Angehängte Dateien:

Lesenswert?

...der Anhang zum obigen Beitrag - hier ist er. Ich
habe das LCD bei mir an Port A angeschlossen und den Code
entsprechend angepasst.

Tobias.

von Zoffi (Gast)


Lesenswert?

Die LCD Routine ist für 4MHz geschrieben, funktioniert aber auch bei
16MHz ;-)

von Zoffi (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt mal die LCD Routine auf 16MHz eingestellt und die Register
abgeändert.
Hast du es mal richtig ausprobiert? (Hardware)
Also bei mir zeigt er jetzt immer nur "302**" an. Wobei die "*"
undefinierbare Zeichen sind!

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.