Forum: Compiler & IDEs Drehzahlbestimmung 100-10000 U/min mit einer Auflösung von 1 U/min


von Mike (Gast)


Lesenswert?

Hallo,

würde gerne mit einem ATmega32 Drehzahlen im Bereich von 100 - 10000 
U/min mit einer Auflösung von 1 U/min bestimmen.

Ich bekomme nur einen Puls pro Umdrehung.

Weiß nicht genau wie ich dies anstellen soll, bzw. ob es überhaupt 
möglich ist.

Wenn ich die Pulse pro Zeit messen, muss die Messzeit ja ziemlich groß 
sein, um die Auflösung hinzubekommen. 60 Sekunden, oder liege ich da 
falsch.

Gibt es einen sinnvolle Möglichkeit diese Aufgabe zu lösen?

Gruß
Mike

von hennes (Gast)


Lesenswert?

die zeit differenz zwischen zwei impulse sollte ausreichen um die 
aktuelle geschwindigkeit zu bestimmen.

von Mike (Gast)


Lesenswert?

Die Auflösung in kombination mit dem Wertebereich bereite mir gerade 
etwas Schwierigkeiten.

von Karl H. (kbuchegg)


Lesenswert?

Mike schrieb:
> Die Auflösung in kombination mit dem Wertebereich bereite mir gerade
> etwas Schwierigkeiten.

Inwiefern?

Bei 10000 U/Min hast du rund 166.66 Umdrehungen in 1 Sekunde. Das heist 
du kriegst 166 Pulse von deiner Markierung in 1 Sekunde. Oder aber 
anders ausgedrückt: Von einem Puls zum nächsten vergehen 0.006 Sekunden, 
oder 6 Millisekunden. Eine halbe Ewigkeit für einen µC.

Mittels Input Capture kannst du die Zeit zwischen 2 Pulsen noch viel 
genauer bestimmen. Durchsuch mal das Forum nach Frequenzmessung. Das ist 
im Grunde genau das gleiche, nur das das Ergebnis in Hz und nicht in 
U/Min angegeben wird. Im Grunde ist das aber völlig identisch, denn um 
bei deinem Beispiel zu bleiben: Bei 10000 U/Min tauchen deine Messpulse 
mit einer Frequenz von 166.6 Hz auf :-)

von Mike (Gast)


Lesenswert?

mhhh ... also ich habe es mit einem 16-bit-Timer umgesetzt. Ermittel 
damit den Couterwert zwischen 2 Pulsen ( neuer Wert - alter Wert). Nur 
ist ja die Auflösung nun anhängig von der Drehzahl. Die Forderung nach 
einer Auflösung von 1 U/min krieg ich irgendwie bei den niedrigen 
Drehzahlen ich hin.

von Mike (Gast)


Lesenswert?

nicht statt ich

von Karl H. (kbuchegg)


Lesenswert?

Mike schrieb:
> mhhh ... also ich habe es mit einem 16-bit-Timer umgesetzt.

Schön.

> Ermittel
> damit den Couterwert zwischen 2 Pulsen ( neuer Wert - alter Wert).

Auch super

> Nur
> ist ja die Auflösung nun anhängig von der Drehzahl.

Logisch

> Die Forderung nach
> einer Auflösung von 1 U/min krieg ich irgendwie bei den niedrigen
> Drehzahlen ich hin.

Warum nicht?
Rechne doch einmal vor, warum das nicht funktioniert.

von Mike (Gast)


Lesenswert?

OK, kommt gleich.

von Mike (Gast)


Lesenswert?

Timer @1Mhz

100 U/min -> T=0.6 -> Zählerwert zwischen 2 Pulsen: 600000
101 U/min -> T=0.594059 -> Zählerwert zwischen 2 Pulsen: 594059



10000 U/min -> T=0.6 -> Zählerwert zwischen 2 Pulsen: 6000
10001 U/min -> T=0.594059 -> Zählerwert zwischen 2 Pulsen: 5999


Mhh ... dann müsste es doch gehen, oder ist mein Ansatz falsch?

Bei den niedrigen Drehzahlen muss ich halt die Überläufe mitzählen.

von Karl H. (kbuchegg)


Lesenswert?

Mike schrieb:

> Bei den niedrigen Drehzahlen muss ich halt die Überläufe mitzählen.

:-)

Exakt.
Du kannst auch mal untersuchen, was passiert, wenn du bei einer kleinen 
Drehzahl den Vorteiler wechselst. Kein Mensch sagt, dass der konstant 
bleiben muss. Ich habs jetzt nicht durchgerechnet, ob du dann die 
geforderte Auflösung noch hinkriegst.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Das übliche Verfahren zur Messung kleiner Frequenzen, hier sind es ja 
1,66 ... 166 Hz, ist das "reziproke Zählen" (reciprocal counter), also 
die Messung der Periodendauer und anschließende Division zur Bestimmung 
des Kehrwertes. Die 1,66 Hz werden bei 1 MHz Zähltakt auf +/- 1 
Mikrosekunde genau bestimmt, das sind fast 6 Stellen Auflösung.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Du brauchst, um die gewünschte Auflösung zu erreichen, einen Timertakt
von mindestens 166,7Hz·10000=1,667MHz. Dann reicht aber, wie du schon
festgestellt hast, die Zählerbreite von 16 Bit nicht mehr aus, um auch
die langsamste Drehzahl zu messen. Mit einer 8-Bit-Variable, die die
Überläufe zählt, hast du praktisch einen 24-Bit-Zähler. Der ist dann
schon wieder so groß, dass du problemlos den Timertakt und damit die
Auflösung noch ein Stück erhöhen kannst. Theoretisch läuft der 24-Bit-
Timer erst bei 1,667Hz·2²⁴=28MHz über, was der ATmega32 hardwaretech-
nisch schon gar nicht mehr schafft.

Nimm also als Timertakt direkt den Quarztakt des ATmega32, der hoffent-
lich höher als 1MHz ist (je höher desto besser). Betreibe den 16-Bit-
Timer im Input-Capture-Modus und zähle zusätzlich im Overflow-Interrupt
eine 8-Bit-Variable hoch. Damit müsste dein Vorhaben gelingen, und du
bist schon auf dem richtigen Weg dorthin.

von Tropenhitze (Gast)


Lesenswert?

Stimmt doch alles garnicht :-)

Sicherlich möchtest Du bei höchster Drehzahl nicht 166 Ergebnisse/s zu 
sehen bekommen, sondern max. drei bis fünf, nicht wahr?

Zähle deshalb die eingetroffenen Drehzahlimpulse zusammen mit der 
Gesamtzeit (capture-Wert + Überlaufe) und starte die Auswertung, wenn 
die Mindestezeit (0,2s) abgelaufen ist und mindestens ein Impuls gezählt 
wurde. Bei hohen Drehzahlen bekommst Du fünf Ergebnisse/s und bei der 
kleinsten etwa 1,6.
Ein neues Ergebnis erscheint dann immer synchron zum letzten Drehimpuls.

Zur Verfeinerung kannst Du nach zwei Sekunden Warten ohne Eingangsimpuls 
eine '0' ausgeben, um den Stillstand der Drehung anzuzeigen.

von Mike (Gast)


Lesenswert?

Danke für die Tipps.

Ich habe jetzt in der Int-Service-Routine folgenden Code stehen:

1
uint16_t TCNT3_rpm1_save;
2
uint16_t TCNT3_rpm1_old;
3
uint32_t TCNT3_rpm1_diff;
4
uint8_t TCNT3_overflow_save1;
5
uint8_t TCNT3_overflow_old1;
6
7
uint16_t TCNT3_rpm2_save;
8
uint16_t TCNT3_rpm2_old;
9
uint32_t TCNT3_rpm2_diff;
10
uint8_t TCNT3_overflow_save2;
11
uint8_t TCNT3_overflow_old2;
12
13
uint8_t TCNT3_overflow = 0;
14
15
.
16
.
17
.
18
19
ISR(INT0_vect)
20
{
21
22
TCNT3_rpm2_save=TCNT3;
23
TCNT3_overflow_save2 = TCNT3_overflow;
24
25
TCNT3_rpm2_diff= ( TCNT3_overflow_save2 - TCNT3_overflow_old2 ) * 65535 + TCNT3_rpm2_save-TCNT3_rpm2_old;
26
27
TCNT3_rpm2_old=TCNT3_rpm2_save;
28
TCNT3_overflow_old2 = TCNT3_overflow_save2;
29
30
}


Nun nimmt die Berechnung in Verbindung mit den häufigen Aufrufen so viel 
Zeit in anspruch, dass der Rest des Programms ins stocken gerät.


Gibt es eine Möglichkeit dies besser zu machen?


Gruß

Mike

von Tropenhitze (Gast)


Lesenswert?

Häufige Aufrufe sehe ich nicht; die wirst Du auch nicht haben. 
Irgendeine große Berechnung sehe ich auch nicht.
Schreib 'mal die 65535 als hex-Zahl 0xFFFF; jetzt sieht man besser, dass 
wohl 0x10000 gemeint sind.

Bekommst Du denn schon ein plausibles Ergebnis?

Wenn alles 'sauber' läuft, wird die Drehzahlmessung vielleicht 1% 
Rechenleistung beanspruchen, sodass nichts stocken muß. Dabei gehe ich 
von 16MHz Taktfrequenz aus.

von Bernd O. (bitshifter)


Lesenswert?

Tropenhitze schrieb:
> Stimmt doch alles garnicht :-)
>
> Sicherlich möchtest Du bei höchster Drehzahl nicht 166 Ergebnisse/s zu
> sehen bekommen, sondern max. drei bis fünf, nicht wahr?
> Zähle deshalb die eingetroffenen Drehzahlimpulse zusammen mit der
> Gesamtzeit (capture-Wert + Überlaufe) und starte die Auswertung, wenn
> die Mindestezeit (0,2s) abgelaufen ist und mindestens ein Impuls gezählt
> wurde. Bei hohen Drehzahlen bekommst Du fünf Ergebnisse/s und bei der
> kleinsten etwa 1,6.
> Ein neues Ergebnis erscheint dann immer synchron zum letzten Drehimpuls.
Warum so aufwändig?
Die Erfassung ist doch ohnehin von der Anzeige getrennt. In der Anzeige 
greife ich mit die letzte Periodendauer ab und berechne die Drehzahl 
daraus. Und zwar genau dann, wann ich sie brauche - völlig unabhängig 
von der Drehzahl mit konstanter Updaterate am Display.

Wer ein schlechtes Gewissen wegen der vielen ermittelten aber 
nichtgenutzten Periodendauern hat, der kann ja gerne beispielsweise den 
gleitenden Mittelwert über die letzten x Periodendauern berechnen und 
damit die Genauigkeit verbessern.

Gruß,
Bernd

von Mike (Gast)


Lesenswert?

Die Drehzahlbestimmung funktioniert. Nur sobald ich die Daten auf einen 
SD-Karte speichere, werden falsche Werte angezeigt.

Zuerst dacht ich, der µC ist mit Drehzahlerfassung + speichern auf 
SD-Karte überfordert. Doch das Problem tritt auf, sobalt ich einmal den 
Zyklus Fopen(), Fclose() hatte.

Schaue mir gerade die beiden Funktionen genauer an. Vielleicht machen 
die irgendwas mit dem Timer. Ich benutze die Lib von Peter Fleury.

von Mike (Gast)


Lesenswert?

... hat noch eine delay-Funktion die mit dem gleichen Timer wie die 
Drehzahl erfassung gearbeitet hat. Daher die Probleme. Nun funktioniert 
es.

Danke an alle Helfer!


Gruß
Mike

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.