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.
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
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?
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ß
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
@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?
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
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
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
>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
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
@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!
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.
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
@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.
@ 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.
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.
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
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.
Hallo Zoffi Ein 4-Taktmotor macht pro Zylinder nur alle 2 Umdrehungen eine Zündung Gruss Camrino
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
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!
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
@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.
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
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.
Also hier nochmal der direkte Link zur ASM Datei http://www.mikrocontroller.net/attachment.php/39087/Bcd32b.asm
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
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?
@Dom So weit habe ich es verstanden, aber was meinst du mit dem letzten Satz? Das du einfach immer 0x30 addiert hast?
@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
@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
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
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?).
Hmmm, ich weiss nicht wo der Fehler liegt. Etwa bei der BCD Konvertierung? :-(
Hallo Zoffi Die kleinste Drehzahländerung für zu einem anderen Ergebnis was vielleicht zum flackern führt? Gruss Cambrino
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.
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.
Hallo, sorry hatte vergessen die Mailbenachrichtigung einzuschalten.
@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.
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.
...der Anhang zum obigen Beitrag - hier ist er. Ich habe das LCD bei mir an Port A angeschlossen und den Code entsprechend angepasst. Tobias.
Die LCD Routine ist für 4MHz geschrieben, funktioniert aber auch bei 16MHz ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.