Hallo Leute, ich hab mir einen Drehzahlmesser für meinen Atmega 8 gebastelt. Dieser nimmt die Drehzahl mit einem Sensor auf (3 Pulse/ Umdrehung) und gibt die aktuelle Drehzahl auf einem Display aus. Soweit kein Problem und funktioniert auch. Es wird bei der ersten Flanke der momentane Timerwert als Startwert gespeichert und von dem Timerwert bei der zweiten Flanke abgezogen etc.. siehe Anhang. Mein Problem jetzt ist, da ich immer nur zwischen zwei Flanken die Zeit messe und mir daraus die Drehzahl berechne, kann es sein, dass die Anzeige immer noch eine Drehzahl anzeigt obwohl der zu messende Motor bereits steht, da der Motor genau zwischen zwei Flanken stehen geblieben ist.... Das kann ich so aber leider nicht gebrauchen, wenn zwischen zwei Flanken z.B mehr als eine Sekunde liegt dann darf das Display ruhig "0 U/min" anzeigen( genauer brauche ich das gar nicht..). Hat jemand eine Idee wie man das in meinen Quelltext einbauen kann? -- Alternativ wäre auch ne Möglichkeit die Messung von Zeit abhängig zu machen. Es würde mir reichen, nur alle 0,5 Sekunden einen Mittelwert auf dem Display anzuzeigen. dann erkennt der MC ja auf jeden Fall wenn der Motor steht. Ich hab aber leider keine Idee wie man das macht... Wäre super wenn mir da jemand helfen könnte oder einen Beispielquelltext zur Hand hat. Aller besten Dank Christian K
Hallo Christian, geht recht einfach: - im Overflow testen ob mehr als x Überläufe (Flanke ist überfällig) dann Messung zurücksetzen, Flag für drehzahl "0" setzen - in main/while zusätzlich dieses Flag testen, wenn gesetzt Ausgabe mit Drehzahl=0 (Berechnung entfällt ja) gruß hans
Hallo, Stimmt das hört sich einfach an, ist ne gute Idee!! Wenn ich das richtig verstanden hab dann müste das so aussehen (ich kanns grad nicht testen bin auffe arbeit..): ---------------------------------------- ISR( TIMER1_OVF_vect ) { NrOverflows++; if(NrOverflows == 61) { Null_Anzeigen = 1 ; //Job Flag wird im Hauptprogramm verarbeitet } else { Null_Anzeigen = 0 ; } } ---------------------------------------- Ich hab das jetzt da eingebaut wo die ISR die Overflows zählt. Ist das so richtig? Danke und Gruß gerd PS: mich würde trotzdem noch interessieren wie man nen Drehzahlmesser programmiert, der immer alle Zeiteinheit einen Mittelwert ausgibt. Also wenn da noch jemand ne Idee hat, würde ich diese begeistert lesen; )
christian K schrieb: > PS: mich würde trotzdem noch interessieren wie man nen Drehzahlmesser > programmiert, der immer alle Zeiteinheit einen Mittelwert ausgibt. Also > wenn da noch jemand ne Idee hat, würde ich diese begeistert lesen; ) Na ja, was ist denn ein Mittelwert? Man hat mehrere Messungen, die summiert man auf und dividiert durch die Anzahl der Messungen. Was wird man daher für einen Mittelwert benötigen? Die letzten n Messungen, die man sich zb in einem Array zwischenspeichert. Nach jeder Messung speichert man den neuesten Wert im Array und verwirft den ältesten. Trick: kann man am einfachsten so machen, dass das Array reihum 'im Kreis' beschrieben wird, dann überschreibt der neueste Wert automatisch immer den ältesten).
christian K schrieb: > Ich hab das jetzt da eingebaut wo die ISR die Overflows zählt. > Ist das so richtig? Ist eine Möglichkeit. Aber warum nicht einfach die Anzahl der Overflows dort berücksichtigen, wo die Auswertung gemacht wird.
1 | void Drehzahl_berechnen(void) |
2 | {
|
3 | if( NrOverflows > 61 ) |
4 | drehzahl = 0.0; |
5 | |
6 | else { |
7 | Erg = (NrOverflows * 65536) + EndTime - StartTime; |
8 | |
9 | // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
|
10 | Erg = F_CPU / Erg; // f = 1 / t |
11 | |
12 | //aus der Frequenz berechnet sich die Drehzahl
|
13 | drehzahl = Erg * 20; // Drehzahl berechnen aus der Frequenz |
14 | //f*(20sec also 60sec/3Pulse pro Umdrehung)= U/min
|
15 | }
|
16 | }
|
@Karl heinz Buchegger Weil er die Berechnung nur macht wenn er 2 Flanken hatte. Daher das Zusatzflag "0", und dann braucht er auch nicht rechnen. gruß hans
Hallo Karl Heinz, Danke für die Antwort, so wie du es vorgeschlagen hast gehts natürlich noch einfacher und kompakter, gefällt mir; )) Besten Dank! Mein Problem bei der zweiten Version ist eigentlich nicht der Mittelwert selbst, sondern die Tatsache dass sich mein Programm immer nur bei anstehender Flanke aktualisiert. Wenn ich jetzt wenig Signale bekomme läuft das Programm auch nur langsam durch, bei vielen Signalen halt schneller.. Ich müsste also wissen wie ich ihn dazu bekomme sich z.b. nur alle 0,5 sek das Display aktualisiert wird. aber trotzdem weiterin alle Takte gezählt werden. aus den gezählten Takten wird dann entsprechend die Drehzahl mit einem Mittelwert über die 0,5sek berechnet.. danke und Gruß christian
hans schrieb: > @Karl heinz Buchegger > > Weil er die Berechnung nur macht wenn er 2 Flanken hatte. > Daher das Zusatzflag "0", und dann braucht er auch nicht > rechnen. Du hast recht, hab nicht aufgepasst. Aber im schnelle drüberschauen spricht doch auch nichts dagegen, main() noch ein bischen umzugestalten
1 | while(1) |
2 | {
|
3 | Drehzahl_berechnen(); |
4 | Messwerte_ausgeben(); |
5 | }
|
Ob der Prozessor jetzt in der main() Däumchen dreht, oder ständig rechnet sollte doch eigentlich egal sein. Für NrOverflows bräucht man dann allerdings noch eine Backupvariable. Ich denke aber, die bräuchte man sowieso. So ganz koscher kommt mir der jetzige Code in der Beziehung eh noch nicht vor. Wenn die startende Flanke zu schnell kommt, ist NrOverflows schon wieder 0, noch ehe die Drehzahlberechnung gelaufen ist.
so wie ich den Quellcode verstehe misst man immer die Zeit zwischen zwei Flanken. Erste Flanke start, zweite Flanke stop. Dritte Flanke start, vierte Flanke stop. Man misst also nur zwischen 1,2 und 3,4... Kann mans auch so programmieren, dass man nach jeder Flanke die Drehzahl berechnet, also 1,2 und 2,3 und 3,4...? Was müsste man im Code hierfür ändern?
Mücke schrieb: > Kann mans auch so programmieren, dass man nach jeder Flanke die Drehzahl > berechnet, also 1,2 und 2,3 und 3,4...? Sicher. Der Timer läuft ja sowieso weiter. > Was müsste man im Code hierfür ändern? jedesmal wenn der Input Capture anschlägt benötigt man * den Zählerstand an dem der Input Captuer zuletzt angeschlagen hat * den jetzigen Zählerstand der jetzige Zählerstand wird dann per Programm zum Zählerstand an dem der Input Capture zuletzt angeschlagen hat. Endstand = ICP Berechne Drehzahl aus Endstand uns Startstand Startstand = Endstand Jedesmal wenn diese Sequenz ausgeführt wird, wird aus dem vorherigen ICP Wert und dem jetzigen ICP Wert die Drehzahl berechnet.
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.