Hallo,

ich möchte gerne mit einem ATtiny2313 bei einem E-Bike die Geschwindigkeit erfassen. Dazu habe ich das Tacho-Signal gefunden. Dieses liefert mir 20 High-Impulse pro Rad-Umdrehung, bzw. 40 Fankenwechsel pro Umdrehung.

Der Rad-Durchmesser ist 22", was einen Umfang von ca. 175cm entspricht. Dies bedeutet wiederum eine gefahrene Strecke von 4,3 cm pro Flankenwechsel am Tacho-Signal.

Wenn man 1 km/h fährt bedeutet dies 23256 Flankenwechsel bzw. 6,5 pro Sekunde. Die Zeit zwischen den Flankenwechseln ist 155 ms.
Bei 100 km/h sind dies entsprechend 2325600 Flankenwechsel bzw. 646 pro Sekunde. Die Zeit zwischen den Flankenwechseln ist 1,55 ms.

Soweit zur Theorie. Der Tacho ist am INT0 angeschlossen.

Meine erste Herangehensweise war beim Flankenwechsel von INT0 einen Zähler laufen zu lassen.
Weiterhin habe ich den Timer0 im AVR dazu benutzt um einen Takt von 1 Sekunde zu erzeugen. (Interner RC-Oszillator mit FCPU = 8000000 und den Timer0-PreScaler auf 256. Den Zähler lade ich dann immer beim Overflow mit dem Wert 5. Beim Overflow-IRQ hat er dann 250 Stellen gezählt. (5 + 250)
8000000 / 256 / 250 = 125
Diese 125 zähle ich im Overflow-Interrupt dann noch mit einem eigenen Zähler, danach ist meine Sekunde abgelaufen. Dies habe ich durch blinken einer LED überprüft.
Immer bei der Sekunde übernehme ich meinen Wert der gezählten Flanken von INT0 in eine Variable und setzte diesen Zähler dann wieder auf 0.
Diesen Wert in der Variable muss ich dann nur noch durch 3,25 teilen (6,5 Impulse pro km/h / 2, warum durch 2 ist mir gerade entfallen) und habe damit die gefahrene Geschdingkeit in km/h.
Leider ist diese Methode zu "grob". Ich würde gerne eine Auflösung in Zehntel-km/h haben, was mit diese Methode scheinbar nicht möglich ist. Zumindest waren die Sprünge auf meinem Display immer zu groß.

Kann das jemand nachvollziehen? Habe ich vielleicht irgendwo einen Denkfehler?

Ich habe dann weiterhin versucht die Zeit zwischen den Flankenwechseln zu messen.

Dafür benutzte ich den Timer1 mit einem Prescaler von 8. Dies bedeutet ich kann mit einer Auflösung von 1 µs Zeit messen. Wenn ich 1,55ms als "schnellste" Zeit für 100 km/h messen möchte ist dies mehr als ausreichend.

Im Overflow-Interrupt des Timer1 lasse ich dann noch eine weitere U16-Variable die Überläufe zählen, da die 16 Bit des Timer1 sonst nicht ausreichen würden.
Beim Flankenwechsel INT0-Interrupt berechne ich dann eine U32-Zahl, die die Zeit zwischen diesem und dem letzten Flankenwechsel in µs darstellt.

Von dieser Zahl muss ich dann nur noch in ms umrechnen und die 155 ms durch diese Zahl teilen.

Dummerweise ist dieser Wert total "instabil" und hört auch bei ca. 20 km/h auf und steigt nicht weiter. Selbst mit einer Glättung über 5 Werte springt der Wert munter um bis zu 5 km/h umher. Weiterhin verstehe ich nicht, warum nach ca. 20 km/h Schluß sein soll.

Die ganze Umrechnung mit Multiplikation und Divison übernehme ich im Hauptprogramm, welches nur aus einer Schleife besteht, die die Umrechnung durchführt und den Wert auf einem Display anzeigt.

In den Interrupt-Routinen wird so wenig wie möglich durchgeführt. Im INT0 werden nur die 3 Werte (Überlauf-Zähler, TCNT1L und TCNT1H) in temporäre Variablen kopiert und der Zähler dann auf 0 gesetzt. Im Overflow-Interrupt vom Timer1 zähle ich nur die U16-Variable um eins weiter.

Ich sitzte an diesem Problem nun schon sehr viele Stunden über die letzten Tage verteilt. Aber irgendwie stecke ich nun in einer Sackgasse. Wo könnte mein Denkfehler liegen? Was mache ich falsch?

Viele Grüße
Andreas