Hallo! Ich möchte einen Motor regeln (n=0..2000/min) und erhalte vom Tachogenerator entsprechend ein Signal mit f=0..2000Hz. Programmiert ist noch nix, nur Vorüberlegung: Tachogenerator an den ICP (ATMega644) und dann im ICP-Interrupt die Differenz zwischen den Timestamps errechnen = Dauer -> Drehzahl. Unterhalb einer Schwellendrehzahl (~4-5 1/min) ist die Dauer zwischen den Tachoimpulsen nun aber länger als der 16bit Timer überstreicht, weshalb die Differenz unsinnige Werte annimmt. Diese würde ich gerne ausblenden bzw. auf die max. Periodendauer setzen, da ich diesen tiefen Drehzahlbereich nicht regeln will. Die Beispiele, die ich hier im Forum schon entdeckt habe, gehen alle in die Richtung, durch den Overflow-Interrupt den Zähler auf mehr als 16bit aufzubohren, wobei ich diese zusätzliche Auflösung, wie gesagt, nicht benötige. Mein Ansatz: In der ICP-ISR den Timer auf 0 zurücksetzen und bei gesetztem Timer Overflow das Ergebnis verwerfen. Vorteil: Differenzberechnung entfällt, ICP-Wert ist die Periodendauer Nachteil: Timer lässt sich nicht mehr für andere Zwecke mitverwenden Mein Bauchgefühl: Funktioniert, ist aber unsauber wg. obigem Nachteil Mein Wunsch: Brett vor'm Kopf wegnehmen und damit zur Denkanregung einen leichten Schlag auf den Hinterkopf bekommen Ich danke schonmal für den einen oder anderen Denkanstoß :-)
> Unterhalb einer Schwellendrehzahl (~4-5 1/min) ist die Dauer zwischen > den Tachoimpulsen nun aber länger als der 16bit Timer überstreicht, Das hängt vom Prescaler des Timers ab.
Grundsätzlich ist das alles kein Problem, man muss sich nur vorher über die Nötige Auflösung klar werden die man benötigt/anstrebt. Am Einfachsten ist natürlich die Periodendauermessung und dann über 10 Perioden den Mittelwert bilden. Wenn du deinen Timer noch für andere Sachen benutzen willst, tu das, der µC kann die Periodendauermessung ganz easy nebenher laufen lassen. Zu Beginn deiner Messung setzt du einen Overflow-zähler auf 0. Dann speicherst du den aktuellen Zählerstand. Beim Input Capture speicherst du dann den neuen Zählerwert. Anschließend errechnest du aus der Periodendauer die Frequenz. Die Timerüberläufe zählst du im Timeroverflow mit. Insgesamte Timerincremente = (Overflowzähler * 2^16) +(Alter Wert-Neuer Wert) Achtung, Alter Wert - Neuer Wert kann auch negativ werden, daher besser einen Cast auf (int) durchführen. Ingo
Krapao schrieb: > Das hängt vom Prescaler des Timers ab. Der wird m.E. aber eher durch die Auflösung der oberen Drehzahlen vorgegeben. Außerdem will ich die ganz niedrigen Drehzahlen <5 1/min auch nicht messen.
Ach so, zusätzlich startest du einen zweiten Timer (einfach Variable mit einem Wert laden und decremntieren), mit du deine Mindestfrequenz festlegst. Dieser wird bei jedem Input-Capture neu gestartet. Wenn in einer festen Zeit X kein IC auftaucht (die Variabvle wird runtergezählt und wenn sie 0 ist weißt du, dass die Zeit um ist), wird die Messung beendet und die Frequenz ist < als deine Mindestfrequenz. Muss übrigens heißen: Insgesamte Timerincremente = (Overflowzähler * 2^16) +(Neuer Wert- Alter Wert) Ingo
> Der wird m.E. aber eher durch die Auflösung der oberen Drehzahlen > vorgegeben. Außerdem will ich die ganz niedrigen Drehzahlen <5 1/min > auch nicht messen. Ich wollte dich nicht kritisieren, sondern einen Denkanstoß geben: Man kann den Prescaler passend zur Massaufgabe setzen - und innerhalb des Programms auch ändern, wenn sich die Messaufgabe ändert. Wenn du mit einer Änderung der Specs von (n=0..2000/min) auf (n=5..2000/min) alle Probleme umschiffen kannst, mach es.
Krapao schrieb: > Wenn du mit einer Änderung der Specs von (n=0..2000/min) auf > (n=5..2000/min) alle Probleme umschiffen kannst, mach es. Ok, vielleicht habe ich mich bei den Specs unsauber ausgedrückt. Gibt es eine einfache Möglichkeit, bei durchlaufendem Timer zu erkennen, dass ein Überlauf von Timer_Alt -> Timer_neu stattgefunden hat? Das Timer Overflow Flag hilft mir erstmal ja nur, wenn ich den Timer jedesmal zurücksetze.
> Das Timer Overflow Flag hilft mir erstmal ja nur, wenn ich den Timer > jedesmal zurücksetze. Üblich ist es, dass man die Anzahl der Overflows in einer ISR mit zählt. Bei einem durchlaufenden Timer kannst du dir aus "Anzahl der Overflows * Timerbreite (Shiften statt Multiplizieren!) + akt. Timerstand" ständig einen eindeutigen Timestamp errechnen. Dabei aufpassen, dass du Anzahl der Overflows und akt. Timerstand atomar (=> Artikel Interrupt) liest.
Krapao schrieb: > Bei einem durchlaufenden Timer kannst du dir aus "Anzahl der Overflows > * Timerbreite (Shiften statt Multiplizieren!) + akt. Timerstand" ständig > einen eindeutigen Timestamp errechnen. Dabei aufpassen, dass du Anzahl > der Overflows und akt. Timerstand atomar (=> Artikel Interrupt) > liest. Damit erweitere ich aber bloss den Timer. Damit löse nicht ich die ursprüngliche Problemstellung, dass mich eine Periodendauer, die größer ist, als die max. Spannweite von 16bit, nicht interessiert und verworfen werden kann.
Das ist keine Problemstellung sondern ein Verfahren. Wenn das Verfahren bei deinem Projekt funktioniert benutze es. Du kennst die Nachteile und die Vorteile. Und wenn du bei deinem Verfahren Timeroverflows vermeiden willst, dann Beitrag "Re: Drehzahlmessen mit Input Capture" Dein "Brett vorm Kopf" ist die Denke "Differenz unsinnige Werte annimmt". Genau deswegen benutzen andere Leute die Overflows. Wenn du mit Overflows umgehen kannst oder die Nachteile des overflow-freien Verfahrens nicht tragbar sind, weil du z.B. den durchlaufenden Timer noch für anderes brauchst, dann Beitrag "Re: Drehzahlmessen mit Input Capture"
Micha schrieb: > Damit erweitere ich aber bloss den Timer. > Damit löse nicht ich die ursprüngliche Problemstellung, dass mich eine > Periodendauer, die größer ist, als die max. Spannweite von 16bit, nicht > interessiert und verworfen werden kann. Hallo? Ingo L. schrieb: > Ach so, zusätzlich startest du einen zweiten Timer (einfach Variable mit > einem Wert laden und decremntieren), mit du deine Mindestfrequenz > festlegst. Dieser wird bei jedem Input-Capture neu gestartet. Wenn in > einer festen Zeit X kein IC auftaucht (die Variabvle wird runtergezählt > und wenn sie 0 ist weißt du, dass die Zeit um ist), wird die Messung > beendet und die Frequenz ist < als deine Mindestfrequenz. Einfach mal lesen Ingo
Micha schrieb: > Das Timer > Overflow Flag hilft mir erstmal ja nur, wenn ich den Timer jedesmal > zurücksetze. Ist echt ein dickes Brett ;) Musst ja nicht die Overflows zählen, wenn dich das nicht interessiert. Du musst bloss merken, DASS ein Overflow stattfand. Also wenn dein Tachosignal kommt, checkst du erst ob Overflow passierte, falls ja ist der Timerwert Schrott, Timer = 0, Overflow = 0, fertig. Falls kein Overflow war, ist deine aktuelle Timerzeit brauchbar, rechne...
Johannes G. schrieb: > Ist echt ein dickes Brett ;) Kiefer, druckkesselimprägniert :) Deinen Ansatz verfolge ich gerade anhand der Sägezahnbilder aus dem AVR-Datenblatt, allerdings komme ich wohl nicht umher, mehr als einen Overflow zu zählen wenn ich die gesamten 16bit Timerbreite nutzen möchte. 0 Overflow -> Zulässig, da innerhalb 16bit 1 Overflow & Neu > Alt -> Verwerfen, da 16bit überlauf 1 Overflow & Neu < Alt -> Zulässig, da innerhalb 16bit 2 Overflows -> Verwerfen, da 16bit Überlauf Overflows werden in der zugehörigen ISR inkrementiert und in der ICP-ISR zurückgesetzt. Dachte nur, vielleicht gibt es eine Lösung, die ohne zusätzliche Overflow-ISR oder ohne zusätzlichen Timer auskommt.
> Dachte nur, vielleicht gibt es eine Lösung, die ohne > zusätzliche Overflow-ISR oder ohne zusätzlichen Timer auskommt. Du braucht keinen zusätzlichen Timer! Du kannst den ICP Interrupt und den Overflow Interrupt bei dem gleichen Timer enablen.
Man könnte auch den Timer weiter laufen lassen, und statt dem overflow interrupt einen output compare Interrupt nutzen. Also einfach eines der OCR Register passend (z.B. timerstand +60000) setzen. Wenn das passende Interrupt-Flag gesetzt ist, war die Zeit zu lang. Ein Overflow beim Timer zwischen den 2 ICP Events ist noch keine Problem, wenn man die Rechnung mit word Variablen, also 16 Bit unsigned macht. Der Cast nach Int ist als genau falsch. Das Ergebnis ist auch immer Positiv - sind doch keine Neutrinos.
Hier ist noch ein anderer Ansatz: Triggere mit dem Indexpuls eine IRQ und zähle da drin eine Variable um 1 hoch. Ein Timerinterupt liest jede Sekunde die Variable, speichert sie als Messergebnis und setzt sie danach zurück. Gibt auch noch bei 0 U/sec richtige Ergebnisse.
Ulrich schrieb: > Man könnte auch den Timer weiter laufen lassen, und statt dem overflow > interrupt einen output compare Interrupt nutzen. Also einfach eines der > OCR Register passend (z.B. timerstand +60000) setzen. Wenn das passende > Interrupt-Flag gesetzt ist, war die Zeit zu lang. Da kann ich aber auch das Overflow-Flag auswerten und verwerfe die einfach Ergebnisse, die einen Überlauf hatten. Vielleicht gar keine so schlechte Idee: Gibt bei niedrigen Drehzahlen dann ggf. eine schlechtere Zeitauflösung, aber verschmerzbar, da ich den Bereich nur beim Anfahren und Anhalten durchlaufe. Werd ich versuchsweise mal implementieren. > Ein Overflow beim Timer zwischen den 2 ICP Events ist noch keine > Problem, wenn man die Rechnung mit word Variablen, also 16 Bit unsigned > macht. Der Cast nach Int ist als genau falsch. Das Ergebnis ist auch > immer Positiv - sind doch keine Neutrinos. Ich rechne bei sowas immer nur mit 16bit unsigned. Krapao schrieb: > Du braucht keinen zusätzlichen Timer! Du kannst den ICP Interrupt und > den Overflow Interrupt bei dem gleichen Timer enablen. Ja, ich weiß. Auf den Overflow Interrupt wollte ich als ewiger Minimalist halt verzichten.
Bitte auch die Interrupt Priorität und die Latenz berücksichtigen. Wenn der ICP im Interrupt auf 0 gesetzt wird kannst du einige Schritte verlieren wenn der µC noch andere Interrupts bearbeiten muss. nb: Der Motor macht 60 Impulse Pro Umdrehung? Sonst sind es nur 33,3Hz....
Tim schrieb: > Bitte auch die Interrupt Priorität und die Latenz berücksichtigen. > Wenn der ICP im Interrupt auf 0 gesetzt wird kannst du einige Schritte > verlieren wenn der µC noch andere Interrupts bearbeiten muss. Deshalb wollte ich auch eine Lösung finden, auf der ich den Timer durchlaufen lassen kann. > nb: Der Motor macht 60 Impulse Pro Umdrehung? > Sonst sind es nur 33,3Hz.... Welche Motoren meinst Du mit "Sonst sind es nur 33,3Hz"? Meiner hier - Herkunft unbekannt, Universalmotor mit schätzungsweise ~300W - macht über den Tachogenerator ~60 Impulse/Umdrehung.
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.