Hallo!
Ich möchte eine Sportzeitmessung aufbauen, die auf millisekunden genau
sein sollte (Über einen Zeitraum von 2min).
Ich kenn mich etwas mit Mikrocontrollern aus und weiß auch, dass ich
dafür den Timer einsetzen kann. Aber sind dise Timer auch ausreichend
genau?
Ich denke mal das hängt auch vom eingesetzten Quartz ab...
Oder wie wird das in professionellen Zeitmessungen gemacht?
Gibts vielleicht irgendwelche Realtime-Clocks die auch Millisekunden
messen?
Für ein paar Tipps wäre ich sehr dankbar...
Gruß Stefan
Laß Deinen Mikrocontroller im 1 ms-Zyklus laufen, der von einem Timer
gesteuert wird. Dann brauchst Du beim Messen einfach nur die Zyklen
zählen. Die Genauigkeit der ganzen Geschichte hängt von Deiner
Quarzgenauigkeit ab. Die Angaben zur Genauigkeit findest Du in dem
Quarz-, bzw. Oszillator-Datenblatt von dem Baustein, der Deinen
Mikrocontroller taktet.
Ja, die Taktung ist ausschlaggebend!
- Zum einen kann man sagen, dass die interne Müll ist, was exakte
Genauigkeiten angeht.
- Zum anderen hast du eine im Vergleich zur Taktung riesige Zeit, die du
messen willst. Daher solltest du die Taktung des µC so langsam wählen,
wie möglich. Damit würdest du dann die Abweichung kleiner halten
können.
Angenommen du taktest mit 500kHz.(Abweichung des Quartz: X%)
Dann kannst du 60 000 000 mal takten, bis du auf 120 sek. bist
die Abweichung wird leider addiert. Darum ist es sinnvoll, wenn du die
Taktung sehr langsam wählst.
Angenommen du taktest mit 20MHz
Dann musst du 2 400 000 000 mal takten, bis du auf 120s bist
die Abweichung ist dann viel höher!!!
Stefan wrote:
> Ich denke mal das hängt auch vom eingesetzten Quartz ab...
Wenn Du keine dirty Hacks in Deiner Software hast, d.h. die Timer nicht
willkürlich umsetzt, hängt es nur vom Quarz ab.
Leider setzen Anfänger gerne mal willkürlich die Timer, d.h. ohne
Berücksichtigung von Interruptlatenzen und anderen
Softwareausführungszeiten.
Klar, daß dann die Uhr nachm Mond geht.
1ms ist fürn nen MC kein Hexenwerk, sondern elendig lang.
Also überhaupt kein Problem.
Erst bei <1µs wirds knifflig.
Peter
"Ich kenne mich etwas aus" bedeutet: Ich hab schon mehrere Programme für
Mikrocontroller geschrieben, auch mit Timer, Capture/Compare usw.
Nur mit Quarten kenn ich micht nicht allzu gut aus.
Außerdem dachte ich mir, dass es für eine derartige Anwendung spezielle
Bauteile gibt, die mir die Zeitmessung abnehmen...
Als Anmerkung!
bei Uhren wird öfter mal gworben mit dem Schlawort
"Quartzuhr" Und die müssen noch größere Zeiten überbrücken, als du
Also eine ausreichende Genauigkeit wirst du auf Jeden Fall erreichen.
Wichtig ist nur, dass du die Abweichung(aus dem Quartz-Datenblatt) mit
der errechneten Taktanzahl hochrechnest.
@Namenloser:
> die Abweichung ist dann viel höher!!!
Nein. Quarze mit einer hohen Frequenz haben oftmals auch viel kleinere
Abweichungen. Eine Ausnahme stellen allerdings die Uhrenquarze mit
32.768 kHz dar.
@Stefan:
Ich würde den Microcontroller nicht unbedingt sehr langsam Takten, dafür
folgendes machen:
Der Timer wird so initialisiert, dass er, sagen wir mal alle 10 ms
überläuft. In der Interrupt-Routine zählst du dann eine Variable hoch.
Wenn die Variable auf 100 hochgezählt hat, ist genau 1 Sekunde durch
(100x 10 ms = 1000 ms oder 1 s). Der Rest ist simpel: Nun musst du jede
Sekunde eine weitere Variable hochzählen. Wenn die auf 60 überläuft, ist
eine Minute um usw.
@Matte:
Wieso? Klar, der Interrupt wird, je nach Aufgabe, die die CPU sonst
erledigt, nicht sofort aufgerufen (Latenz). Aber: der Interrupt wird
eben in regelmässigen Abständen aufgerufen. Die Latenz bleibt ja da mehr
oder weniger gleich, schlussendlich tritt der Interrupt halt doch immer
im selben Zeitraster auf.
Ausserdem: Meist ist ja die Verzögerung ein paar CPU-Takte. Bei einem
8051, der mit 12 MHz getaktet ist, wäre die Latenz z.B., sagen wir mal,
3 uS. Das ist auf die 2 min gesehen vernachlässigbar klein... Ausserdem
muss er die abgelaufene Zeit ja noch irgendwo ausgeben können. Bei
Polling des Timer-Überlaufs wird das sehr hässlich zu programmieren...
Matte wrote:
> @ Tobias Plüss:>> Ohne Interrupt wird es genauer!
Und wie willst Du ohne Interrupt mit vertretbarem Programmieraufwand
Sekunden, Minuten (und Stunden) zählen? Außerdem ist der Interrupt bei
einer Millisekunde zwischen zwei Ereignissen absolut unkritisch!
Hi Leute,
nachdem jetzt dem völlig Ahnungslosen die Vor- und Nachteile von
verschiedenen Taktfrequenzen und Nutzung des Interrupt erläutert wurden,
sollten wir jetzt unser Augenmerk auf die diversen
Ausführungsmöglichkeiten von Lichtschranken richten.
Später kommt dann noch die Anzeige des Ergebnisses auf einer möglichst
hochauflösenden TFT-Anzeige mit mind. 1600x1200 Pixeln in 24-Bit dazu.
Oder besser gleich die Funkdatenübertragung und Kopplung an eine
Datenbank.
Es ist also noch viel zu tun an diesem Projekt !
@ Johannes M.:
Ohne Interruptaufruf benötigst Du sogar noch einige Zeilen weniger
Programmcode, somit wird es eher einfacher.
Ein Zyklus (siehe meinen ersten Beitrag) könnte so aussehen:
- Zyklusstart: Timer startet Zyklus jede ms
- Eingände werden abgefragt
- Daten werden verarbeitet
- Daten werden ausgegeben
- Sprung zum Zyklusstart
Du solltest bei der Analyse von Problemen vielleicht ein wenig flexibler
werden. Die Einstellung "Das habe ich immer schon so gemacht" führt
nicht unbedingt zur besten Lösung.
@ tastendrücker:
Das Interruptflag eines Timers läßt sich auch direkt abfragen und muß
nicht zwangsläufig einen Interrupt abfragen!
... denk mal drüber nach.
@Matte
Also ich bin doch wesentlich flexibler, wenn ich die "Abfrage" des Timer
I-Flags den µC machen lasse und er mir Bescheid sagt, wenn's soweit ist?
Aber wer weiss... vielleicht hast du da ja geniale Techniken, auf die
andere noch nicht gekommen sind.
@ tastendrücker:
Auch außerhalb des Interrupt fragt der µC das Timer-I-Flag ab. Und wenn
es dann soweit ist, startet er einfach den Zyklus. Er muß somit
niemanden Bescheid sagen und vertrödelt damit keine unnötige Zeit oder
jittert beim Interrupt-Aufruf herum (siehe µC-Datenblatt).
Womit hast Du eigentlich ein Problem?
Oder, ohne Timer: Den Micro einfach Register incrementieren lassen, und
warten bis es überläuft....
8051 Assembler:
PAUSE: DJNZ R0,$
DJNZ R1,PAUSE
RET
gibt exakt 65.536 ms Verzögerung, abzüglich der 2 us für den LCALL und
der 2 us für RET.... ;)
"Angenommen du taktest mit 500kHz.(Abweichung des Quartz: X%)
Dann kannst du 60 000 000 mal takten, bis du auf 120 sek. bist
die Abweichung wird leider addiert. Darum ist es sinnvoll, wenn du die
Taktung sehr langsam wählst.
Angenommen du taktest mit 20MHz
Dann musst du 2 400 000 000 mal takten, bis du auf 120s bist
die Abweichung ist dann viel höher!!!"
Hast Du Dein Beispiel mal ausgerechnet?! Angenommen, Deine Quarze
weichen um 1% ab:
500 kHz => 1%-Abweichung = 20 ns
60 000 000 * 20 ns = 1,2 s
20 MHz => 1%-Abweichung = 0,5 ns
2 400 000 000 * 0,5 ns = 1,2 s
Übrigens: 120s => 1% Abweichung = 1,2 s
1% Abweichung sind nunmal 1% Abweichung.
>Angenommen du taktest mit 500kHz.(Abweichung des Quartz: X%)>Dann kannst du 60 000 000 mal takten, bis du auf 120 sek. bist>die Abweichung wird leider addiert. Darum ist es sinnvoll, wenn du die>Taktung sehr langsam wählst.>>Angenommen du taktest mit 20MHz>Dann musst du 2 400 000 000 mal takten, bis du auf 120s bist>die Abweichung ist dann viel höher!!!
Blödsinn. Lies Dir mal Steffens Beitrag durch. Du hast offenbar den
Unterschied zwischen einem absoluten und einem relativen Fehler nicht
begriffen.
Steffen Hausinger wrote:
> Hast Du Dein Beispiel mal ausgerechnet?! Angenommen, Deine Quarze> weichen um 1% ab:
So schlechte Quarze müssen aber erst noch hergestellt werden...
Die übliche Abweichung von der Nominalfreq. liegt bei Standardquarzen so
bei 30-50ppm, das sind 0.003-0.005%
Hm, angenommen wir nehmen einen 8 Mhz Quarz. Für eine ms sind das dann
eben 8000 Takte. Da können wir z.B. einen 16-Bit Timer nehmen der im
CTC-Modus einfach 8000 Takte abzählt oder bei einem 8-Bit Timer eben 31
* 256 + 1 * 64. Je nachdem auch mit Vorteiler 8 oder so.
8000 Timertakte / 8000µC-Takte = 1ms
Bei Reichelt entnehme ich den Angaben des 8-Mhz Quarzes:
• Temperaturkoeffizient: ± 30 ppm
• Frequenztoleranz: ± 30 ppm
Gehen wir meinetwegen mal von einer Abweichung von +100ppm aus. D.h. aus
8Mhz werden dann eben mal 8.000.800 Mhz
d.h. wir haben jetzt in einer ms nicht 8000 sondern 8000,8 Takte.
8000 Timertakte / 8000,8 µC-Takte = 0,9999ms
Somit ist eine reale ms für den µC nur 0,9999ms lang, er wird weniger
Zeit messen als real vergangen ist. Wenn man mit dem µC nun auf eine ms
abstoppt, vergehen in Wirklichkeit 1,0001ms. Hochgerechnet auf die 1000
* 120ms die in 2 Minuten vergehen ergibt das 120,0120s also 120ms
Abweichung. => Unbefriedigend.
Diese Abweichung müsste man unter realen Umständen messen nach dem
Verfahren in
http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC
vorgehen.
lg PoWl
@Paul:
Da ist Dir aber eine Null flöten gegangen. 100 ppm sind 0,1 Promille,
macht bei 120 s eine Abweichung von 12 ms...
Ich sehe grad, Du hast es sogar noch richtig da stehen, aber 0,012 s
sind 12 ms...
Das hätte man auch einfacher rechnen können...
Hi
Hm, angenommen wir nehmen einen 8 Mhz Quarz...
Für solche Anwendungen muss man halt den richtigen Quarz aussuchen.
Rechne das nochmal mit 4.096MHz.
MfG Spess
spess53 wrote:
> Hm, angenommen wir nehmen einen 8 Mhz Quarz...>> Für solche Anwendungen muss man halt den richtigen Quarz aussuchen.> Rechne das nochmal mit 4.096MHz.
???
Und was soll das bitteschön für einen Unterschied machen? Mit einem 8
MHz-Quarz geht das sehr gut, es besteht kein Grund, einen 4,096
MHz-Quarz zu nehmen (abgesehen von dem evtl. geringeren Stromverbrauch
bei kleinerer Taktfrequenz).
Wenn der 4,096 MHz-Quarz dieselbe Genauigkeit hat wie der 8 MHz-Quarz,
dann spielt das für das Ergebnis überhaupt keine Rolle.
Mit einem 8 MHz-Quarz kann man z.B. mit einem AVR sehr schön einen
ms-Takt erzeugen, sogar mit einem 8-Bit-Timer. Prescaler auf 64, Timer
im CTC-Modus, Compare-Register auf 124 und los geht's. Bei nem
16-Bit-Timer kann man auch nen Prescaler von 8 nehmen und dann 1000 ins
Compare-Register...
Stefan wrote:
> Ich möchte eine Sportzeitmessung aufbauen, die auf millisekunden genau> sein sollte (Über einen Zeitraum von 2min).
Und wie genau soll das aussehen?
Wie schon geschrieben wurde: 1ms ist absolut kein Problem.
Ups, hast völlig recht, hab mich da verguckt.
4096 ist eine 2erpotenz. Demnach kann man da ganz einfach mit einem
Overflow-Interrupt arbeiten.
z.B. 4096000 / 256 = 16000 Timeroverflows / Sekunde. Man kann jetzt 16
OVFs für eine ms abzählen oder mit dem Vorteiler von 8 eben 2 OVFs.
An der Genauigkeit ändert das jedoch nix. Man müsste also mit einer
genauen Referenz die Abweichung messen. Am besten über einen längeren
Zeitraum, z.B. mit einer Funkuhr und dann ein paar Tage durchzählen
lassen. Das ganze kann man dann leichter mit der CTC-Methode
korrigieren. Oder man nimmt einfach einen Uhrenquarz und ist damit
glücklich.
Solange die Messungen per Hand ausgelöst werden bringt diese hohe
Genaugikeit eh nix.
lg PoWl
Paul Hamacher wrote:
> Solange die Messungen per Hand ausgelöst werden bringt diese hohe> Genaugikeit eh nix.
Ja, selbst wenn man sich Muehe gibt kommt man nicht besser als +/- 100ms
ran. Da braeuchte man dann mind. eine Lichtschranke. Deswegen frag ich
ja wie das Gesamtsystem aussehen soll.
>Hochgerechnet auf die 1000>* 120ms die in 2 Minuten vergehen ergibt das 120,0120s also 120ms>Abweichung. => Unbefriedigend.
Es sind nur 12 ms.
>Diese Abweichung müsste man unter realen Umständen messen nach dem>Verfahren in>http://www.mikrocontroller.net/articles/AVR_-_Die_...>vorgehen.
Genau. Es ist möglich, den Fehlgang des Quarzes sehr genau per Software
auszugleichen, und das ist gar nicht mal so schwierig.
Vorüberlegung:
Ein idealer Quarz würde mit exakt 8 MHz schwingen, und der Timer
müsste (bei Prescaler 1) immer bis 8000 zählen, bis die nächste ms - der
"fundamentale Zeitschritt" des gesamten Programms - vergangen ist. Die
Frequenz eines realen Quarzes wird jedoch etwas davon abweichen. Also
könnte man erwägen, den Timer einfach immer bis 7999 oder 8001 statt bis
8000 laufen zu lassen. Aber das würde die Frequenz um 1 - 7999/8000 =
125 ppm ändern, was für das gewünschte "Feintuning" zu grob ist.
Die Lösung: Man lässt den Timer z. B. 99 mal bis 8000 laufen, und nur
jedes einhundertste mal bis 7999 oder 8001. Das ist der Trick! Dazu
zählt man in der Interruptroutine einen Extra-Zähler immer nach dem
Schema 0, 1, 2, ..., 99, 0, 1, ... 99, 0, 1, 2, ... hoch (ist mit ein
paar Zeilen Code erledigt). Solange dieser Zähler ungleich 0 ist, setzt
man das OCR1A-Register auf den Standardwert 8000, aber wenn es Null ist,
auf 8000 + C. Dabei ist C ein weiteres Register, dessen Wert die
Frequenzkorrektur bestimmt.
Für 100 ms braucht der Controller dann nicht 100 * 8000 = 800000
Taktzyklen, sondern 99 * 8000 + 1 * (8000 + C) = 800000 + C Taktzyklen.
800000 + C hat aber gegenüber 800000 die relative Abweichung (1 -
(800000 + C)/800000) = C/800000 = C * 1.25 ppm.
------------
Ergebnis: Macht man es so, dann lässt sich über C die Frequenz
softwaremäßig in 1.25 ppm-Schritten tunen. Das ist ausreichend genau
(1.25 ppm sind ca. 3 Sekunden pro Monat).
Die ganze Sache "tickt" dann eine Winzigkeit unregelmäßig, und zwar
folgen immer auf 99 gleiche, aber minimal zu kurze[lange] Millisekunden
dann eine etwas genau derart zu lange[kurze] Millisekunde, dass es
insgesamt alle 100 ms stimmt. Die Tick-Unregelmäßigkeit ist jedoch sehr
gering und ist für die Praxis ohne Bedeutung.
Vielen Dank für eure Vorschläge!
Das Meiste hab ich auch verstanden...
@Michael G.
Hast recht: Das Gesamtsystem soll mit Lichtschranken aufgebaut werden!
Bin auch schon am recherchieren, was ich da noch beachten muss.
Die Hardware krieg ich schon hin, bin trotzdem für Vorschläge offen
(z.B. welche Lichtschranken sich dafür eignen)
Gruß Stefan