Die finale Frage gleich vorweg: Hat jemand Erfahrung mit dem "Input-Capture-Feature" des Atmega8? Tut das prinzipiell beim Erfassen von Periodendauern? Oder gibts da spezielle Dinge zu beachten? Hintergrund der Frage: Das Thema DCF77-Uhr ist ja hier schon öfters diskutiert worden. Allerdings mehr als Uhr, die direkt eine Anzeige hat. Ich will die gewonnene Zeit an einen Rechner (und dort NTP) weiterreichen und habe daher ein paar höhere Anforderungen an die "Qualität" der Zeit...und verzweifel gerade daran. Es ist nicht die erste DCF77-Uhr, die ich baue, nur die anderen zeigen auch die Zeit einfach nur an. Daher dachte ich: Alles ganz einfach, und habe angefangen. Da ich die Zeit über USB weiterrechen will, kommt noch das AVR-USB-Programm dazu. Weil das sehr enge Latenzanforderungen hat, habe ich für die Dekodierung des DCF77-Signals gleich auf Interrupte verzichtet und lasse das "entspannt" in der Hauptschleife machen. Damit das geht, läuft mein 16Bit-Timer1 im "Normal" Modus und das DCF77-Signal löst jeweils ein "capturing" des Timerwerts in ICR1 aus. Damit kann man dann in Ruhe auch nachträglich die Zeitpunkte der Flanken recht genau bestimmen (dachte ich). Hier wurde schon mehrfach diskutiert, dass die 0 und 1 Kodierung mehr oder weniger von den idealen 100ms und 200ms abweicht. Damit kann ich aber leben, durch Vergrößern der Toleranzen beim Erkennen der Pulsbreite. Was ich jetzt aber sehe ist, dass auch die Startflanke, die ja den Beginn der jeweiligen Sekunde definiert, ebenfalls deutlich hin und her springt. Ich hatte naiv versucht, meine interne Zeitreferenz mit Hilfe des DCF77-Signals abzugleichen. Ich verwende einen 12MHz Quarz, Timer1 sieht diesen durch 256 geteilt. Somit "sollte" eine Sekunden-Intervall-Dauer von 46875 Zählern rauskommen. Was ich tatsächlich sehe, wenn ich die Timer1-Werte von zwei Sekundenstarts vergleiche, sind Schwankungen von 45934...47130. Das sind -19,9ms...+5,4ms! Ein paar Zähler hin und her hatte ich berücksichtigt, das ist nunmal immer so, wenn man zwei zueinander asynchrone Dinge vergleicht. Aber so viel? Meine Glättungsroutinen laufen alle ins Leere, weil sie solche Schwankungen einfach nicht bügeln können. Die Phasennachführung der internen Zeitreferenz zum DCF77-Signal weiß gar nicht, wohin sie nachführen soll. :-( Gibt es bei dem "Input-Capture-Feature" des Timer1 vielleicht etwas zu beachten, was ich vergessen habe? Es ändert sich schonmal nichts, ob ich den "Noise Canceler" zu- oder abgeschaltet habe. Da der DCF77-Empfänger seine Signale mittels OC liefert (es ist das Conrad-Ding), habe ich auch extra die fallende Flanke als Sekundenstart verwendet, weil sie steiler ist (oder sein sollte). Zusätzlich jage ich dieses Signal noch über den Analog-Komparator des Prozessors, Schwellwert liegt bei halber VCC (2.5V), um dann erst das ICR1 damit füllen zu lassen. Mein Oszi zeigt eigentlich ein perfektes Signal vom Empfänger. Leider reicht das Ding nicht aus, um über die 1 Sekunde hinweg den möglichen Jitter zu zeigen. Somit stehe ich etwas auf dem Schlauch, ob nun im Prozessor noch was schief laufen könnte, oder ob das Empfängermodul wirklich so einen Senf übermittelt. Leider weiß ich jetzt auch nicht, woher ich eine brauchbares Referenzsignal bekommen soll, um zu prüfen, ob das "Input-Capture-Feature" vielleicht das Problem ist. Bevor ich nun noch weiter in vielleicht falsche Richtungen weitersuche: Hat jemand das "Input-Capture-Feature" am Laufen und erzielt "gute" Ergebnisse (muss ja nicht auch ein DCF77-Signal sein)? Gruß Jürgen
Input-Capture funktioniert einwandfrei. Deine Software dazu wäre mal interessant. Du ließt nicht zufällig versehentlich den aktuellen Zählerstand aus statt des Capture-Wertes, oder?
@Juergen Beisert (jbeisert) >Timer1-Werte von zwei Sekundenstarts vergleiche, sind Schwankungen von >45934...47130. Das sind -19,9ms...+5,4ms! Ein paar Zähler hin und her Völlig "normal". Die meisten "billigen" DCF77 Empfänger sind nicht soooo tierisch genau in der Demodulation. Bei schwachem Empfangspegel erst recht nicht. >Gibt es bei dem "Input-Capture-Feature" des Timer1 vielleicht etwas zu >beachten, was ich vergessen habe? Es ändert sich schonmal nichts, ob ich >den "Noise Canceler" zu- oder abgeschaltet habe. Der macht ja auch nur eine Mittelwertbildung über 4 Takte. >ist (oder sein sollte). Zusätzlich jage ich dieses Signal noch über den >Analog-Komparator des Prozessors, Schwellwert liegt bei halber VCC >(2.5V), um dann erst das ICR1 damit füllen zu lassen. ;-) Das ist unnötig, denn genau DIESE Schaltschwelle haben die normalen Digitaleingänge. >Mein Oszi zeigt eigentlich ein perfektes Signal vom Empfänger. Leider >reicht das Ding nicht aus, um über die 1 Sekunde hinweg den möglichen >Jitter zu zeigen. Für sowas braucht man ein Digitaloszi. > Somit stehe ich etwas auf dem Schlauch, ob nun im >Prozessor noch was schief laufen könnte, oder ob das Empfängermodul >wirklich so einen Senf übermittelt. Letzteres. >Hat jemand das "Input-Capture-Feature" am Laufen und erzielt "gute" >Ergebnisse (muss ja nicht auch ein DCF77-Signal sein)? Das funktioniert so wie im Datenblatt. Hänge einen Quarztakt dort dran, geteilt auf 1s und du wirst nur Sprünge von +/-1 erhalten. MFG Falk
Juergen Beisert wrote: > Damit das geht, läuft mein 16Bit-Timer1 im "Normal" Modus und das > DCF77-Signal löst jeweils ein "capturing" des Timerwerts in ICR1 aus. Ein Einlesen des DCF77 mit dem Capture-Interrupt bringt eine deutliche Verschlechterung der Empfangsqualität, da DCF77 Module gerne mal kleine Störnadeln liefern und die machen Dir das Capture komplett zur Sau. Um Größenordnungen besser ist daher eine Abtastung mit einem Timerinterrupt, z.B. alle 10ms. Besser ist dann dazu noch ne 4-fach Entprellung vorzunehmen. Noch besser ist theoretisch ein Korrelationsverfahren, aber der Gewinn ist nur unwesentlich, da der Übergang von leicht gestört zu total gestört bei den üblichen DCF77 Modulen sehr abrupt erfolgt. Das bringt daher nur wirklich was, wenn man schon das 77kHz-Analogsignal auswertet. Nach dem Kompatorausgang des DCF77-Moduls ist es zu spät. Peter
Stefan Ernst schrieb: > Input-Capture funktioniert einwandfrei. und Falk Brunner schrieb: > Das funktioniert so wie im Datenblatt. Hänge einen Quarztakt dort dran, > geteilt auf 1s und du wirst nur Sprünge von +/-1 erhalten. Danke. Dann ist das also auszuschließen. > Deine Software dazu wäre mal interessant. Du ließt nicht zufällig > versehentlich den aktuellen Zählerstand aus statt des Capture-Wertes, > oder? Ich denke, ich lese das richtige Register. Andernfalls dürften die Zahlen noch zufälliger aussehen. Derzeitiger Code ist recht simpel: static void detect_events(void) { uint8_t tmp; if (TIFR & 0x08) { TIFR |= 0x08; /* clear the flag first */ second_start_pulse_stamp = OCR1B; /* we expect the next second to start at: */ OCR1B = second_start_pulse_stamp + COUNT_PER_SECOND + period_correction + pulse_correction; dcf77_status |= EXPECT_EDGE; } tmp = ACSR; /* ensure one state per turn */ /* detect a regular external edge */ if (tmp & 0x10) { /* edge happened */ ACSR |= 0x10; /* clear the flag first */ /* does the timer "feel" the same edge? */ if (! (TIFR & 0x20)) dcf77_status |= NEW_BIT_IS_GARBAGE; TIFR |= 0x20; /* clear the flag */ /* ACO is '1' if * - negative input is lower than the positive input * -> DCF is 0V, ref is 2.5V * ACO is '0' if * - negative input is higher than the positive input * -> DCF is 5V, ref is 2.5V */ if (tmp & 0x20) { /* event was a rising edge of ACO, e.g. falling edge on the DCF signal -> start of a second */ dcf77_old_start_pulse_stamp = dcf77_start_pulse_stamp; dcf77_start_pulse_stamp = ICR1; TCCR1B &= ~0x40; /* next capture at the falling edge of ACO */ dcf77_status |= NEXT_SECOND_STARTS; } else { /* event was a falling edge of ACO, e.g. rising edge on the DCF signal -> end of bit per second */ dcf77_stop_pulse_stamp = ICR1; TCCR1B |= 0x40; /* next capture at the rising edge of ACO */ dcf77_status |= NEXT_BIT_ARRIVED; } } } Die Bits in dcf77_status werden dann später - in Ruhe - ausgewertet. Falk Brunner wrote: >> Timer1-Werte von zwei Sekundenstarts vergleiche, sind Schwankungen von >> 45934...47130. Das sind -19,9ms...+5,4ms! Ein paar Zähler hin und her > > Völlig "normal". Die meisten "billigen" DCF77 Empfänger sind nicht > soooo tierisch genau in der Demodulation. Bei schwachem Empfangspegel > erst recht nicht. Naja, "tierisch" genau hatte ich auch nicht erwartet. Aber auch nicht so ein grütziges Signal. Aber wenn Du von "billig" sprichst: Ab wann wäre denn ein DCF77-Empfänger teuer (und würde vielleicht mehr taugen als für Spielereien)? >> Mein Oszi zeigt eigentlich ein perfektes Signal vom Empfänger. Leider >> reicht das Ding nicht aus, um über die 1 Sekunde hinweg den möglichen >> Jitter zu zeigen. > > Für sowas braucht man ein Digitaloszi. Das hätte ich sogar. Trotzdem ist die lange Periodendauer hinderlich, wenn einem eigentlich ein paar im Verhältnis dazu sehr kurze Informationen interessieren. Peter Dannegger schrieb: > Ein Einlesen des DCF77 mit dem Capture-Interrupt bringt eine deutliche > Verschlechterung der Empfangsqualität, da DCF77 Module gerne mal kleine > Störnadeln liefern und die machen Dir das Capture komplett zur Sau. Hmm, die Erfahrung habe ich nicht gemacht, wenn Du auch vom Prinzip her Recht hast: Ich bekomme auch kurze Spitzen zu sehen. Allerdings habe ich das bisher eher als Vorteil gesehen, weil die sich nachträglich gut aussortieren lassen. Bzw. mir wertvolle Hinweise liefern, ob das gerade empfangene Bit und damit die gesamte Zeit-Information in dieser Periode brauchbar ist. Herzlichen Dank nochmal für die Informationen. Dann werde ich mich wohl zunächst um die Emfangsqualtität kümmern müssen. Gruß Jürgen
Vorallem wo liegt der Empfänger, wenn du den zum testen un Programmieren neben dem PC liegen hast kann das schon ganz schön das Signal versauen.
Ich habe mir die Sourcen jetzt nicht bis ins letzte Detail angeschaut, kann also nicht sagen, ob die beiden folgenden Dinge die Ursache deines Problems sein können. Beachten solltest du sie aber trotzdem.
1 | TIFR |= 0x08; |
2 | ...
|
3 | TIFR |= 0x20; |
Diese beiden Zeilen löschen jeweils alle gesetzten Flags im Register, nicht nur das eine.
1 | TCCR1B &= ~0x40; /* next capture at |
2 | the falling edge of ACO */
|
3 | ...
|
4 | TCCR1B |= 0x40; /* next capture at the rising |
5 | edge of ACO */
|
Hier hast du ein Detail aus dem Datenblatt nicht beachtet:
1 | After a change of the edge, the input capture flag (ICF1) must be |
2 | cleared by software (writing a logical one to the I/O bit location). |
> TIFR |= 0x08; > ... > TIFR |= 0x20; > Diese beiden Zeilen löschen jeweils alle gesetzten Flags im Register, > nicht nur das eine. Nein, Interrupt-Pending-Flags werden durch Schreiben von Einsen gelöscht. Das Schreiben einer Null ändert das entsprechende Bit nicht. Es wird also nur das jeweils eine Bit angesprochen. Das ist also schonmal kein Fehler... ...
Läubi .. schrieb: > Vorallem wo liegt der Empfänger, wenn du den zum testen un > Programmieren neben dem PC liegen hast kann das schon ganz schön das > Signal versauen. Den Effekt kenne ich schon, wenn ich den Empfänger in der Nähe meines alten Monitors betreibe ;-) Daher ist der Empfänger über eine 2m langes, geschirmtes Kabel an der Auswerteelektronik angeschlossen, damit ich beim Platzieren des Empfängers mehr Freiheitsgrade habe. Stefan Ernst schrieb: > TIFR |= 0x08; > TIFR |= 0x20; > Diese beiden Zeilen löschen jeweils alle gesetzten Flags im Register, > nicht nur das eine. Ach herrjeh. Stimmt. Ich habe mich von der GPIO-Programmierung leiten lassen. Aber diese Register reagieren ja anders! Danke für den Hinweis (ich setze mir gleich den Eselshut auf und stell' mich in die Ecke...). > Hier hast du ein Detail aus dem Datenblatt nicht beachtet: > After a change of the edge, the input capture flag (ICF1) must be > cleared by software (writing a logical one to the I/O bit location). Hmm, muss ich blind gewesen sein. Danke. Gruß Jürgen
Hannes Lux wrote: >> TIFR |= 0x08; >> ... >> TIFR |= 0x20; > > >> Diese beiden Zeilen löschen jeweils alle gesetzten Flags im Register, >> nicht nur das eine. > > Nein, Interrupt-Pending-Flags werden durch Schreiben von Einsen > gelöscht. Das Schreiben einer Null ändert das entsprechende Bit nicht. > Es wird also nur das jeweils eine Bit angesprochen. Das ist also > schonmal kein Fehler... Doch, ist es. Überlege mal, welchen Effekt das "|=" hier hat. Korrekt wäre:
1 | TIFR = 0x08; |
2 | TIFR = 0x20; |
Stimmt, ich nehme alles zurück, habe die "|=" übersehen, bin doch noch lange nicht bei C angekommen... (schäm) ...
Juergen Beisert wrote: > Naja, "tierisch" genau hatte ich auch nicht erwartet. Aber auch nicht > so ein grütziges Signal. Aber wenn Du von "billig" sprichst: Ab wann > wäre denn ein DCF77-Empfänger teuer (und würde vielleicht mehr taugen > als für Spielereien)? Die billigen sind in jeder Uhr drin und arbeiten üblicher Weise gut. Die teuren (>100,-€) sollten einen höhere Empfindlichkeit und Trennschärfe haben, d.h. weiter weg vom DCF77-Sender und bei höherem Störpegel noch arbeiten. Peter
Peter Dannegger wrote: > Juergen Beisert wrote: >> Naja, "tierisch" genau hatte ich auch nicht erwartet. Aber auch nicht >> so ein grütziges Signal. Aber wenn Du von "billig" sprichst: Ab wann >> wäre denn ein DCF77-Empfänger teuer (und würde vielleicht mehr taugen >> als für Spielereien)? > > Die billigen sind in jeder Uhr drin und arbeiten üblicher Weise gut. > > Die teuren (>100,-€) sollten einen höhere Empfindlichkeit und > Trennschärfe haben, d.h. weiter weg vom DCF77-Sender und bei höherem > Störpegel noch arbeiten. Huh, wo gibt es denn DCF77-Empfänger in der 100,- Euronen Klasse? Gruß Jürgen
>Huh, wo gibt es denn DCF77-Empfänger in der 100,- Euronen Klasse? Bei mir. Zu je 99,95€. WIeviel brauchst du denn? Musst mir das aber eine Woche Lieferzeit geben, ich muss die ja hier erst bestllen: http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=0;GROUPID=3636;ARTICLE=57772;START=0;SORT=artnr;OFFSET=16;SID=25X3mgiKwQARkAAGyK1qA1b8b9e94a293250115562214edaf0d4a ;-)
@Peter Dannegger (peda)
>Die billigen sind in jeder Uhr drin und arbeiten üblicher Weise gut.
Das tun sie auch. Aber wen der OP ne superdolle Zeitbasis haben will
braucht er was besseres. Ne Armbanduhr interessieren 10ms Jitter nicht.
MFG
Falk
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.