Forum: Mikrocontroller und Digitale Elektronik DCF77 Vorgehensweise


von Hannes (Gast)


Lesenswert?

Hi,

da es sich bei dem Thema "DCF77" hier um ein sehr weit verbreitetes 
handelt, hoffe ich das mir jemand weiterhelfen kann.



1. Was ist die beste Vorgehensweise bei der Pulsauswertung:

1.1 Mit einem Flankeninterrupt fallende und steigende Flanke erfassen 
und einen Timer zur Pulszeitmessung nutzen.

Hier wird das Problem bei Störungen sein, der uc wird in Intterupts 
absaufen.

1.2 Intern einen 1ms Interrupt erzeugen und direkt "nachsehen" was am 
DCF77 Pin vorgeht, entsprechend auswerten.

Hier hätte man die DCF77 Auswertung im Interrupt des timers...

1.3 Intern einen 1ms Impuls erzeugen. DCF77.c stellt eine Funktion zur 
Verfügung die dann vom Hauptprogramm ca. alle 1ms? aufgerufen werden 
kann, und entsprechende Auswertung macht. Der 1ms Timer setzt nur ein 
Flag welches vom Main "gepollt" wird.

1.3.1 oder würden auch 10ms reichen?





2 Welche Fehlerprüfungen sind nötig (ab wann würdet Ihr ein empfangenes 
Datum als "gültig" erkennen?):

2.1 Beim Empfang

2.1.1 Das Zeitfenster: Wie würdet Ihr die Grenzen für gültige 100ms und 
200ms einstellen?
2.1.2 Die Pulsanzahl: Wie synchronisiert man sich am besten, ist es 
sinvoll die Pulse mitzuzählen und zu kontrollieren das nach dem 59 einer 
weg bleibt?

2.2 Im Datenpaket

2.2.1 Parity: Parity Prüfen

2.3 Datenpaketübergreifend
2.3.1 Abfolge: Wenn zwei Pakete empfangen wurden und "gültig" sind, 
könnte man vergleichen ob sie in einem DCF77 Protokoll entsprechenden 
logischen Zusammenhang stehen, ist das nötig? Also z.B. nach 20:44 
müsste 20:45 kommen, nach Sa kommt So oder ...

2.4 Was kann man noch machen?

3 Uhrwerk
3.1 eine "freie" Uhr nebenher laufen lassen, und gelegtenlich mit dem 
DCF77 Synchronisieren

3.1.1 Wie oft sollte man einen Sync machen? Peter Dannegger macht es 
glaube ich täglich um 3:20?

3.1.2 Gibt es noch andere Möglicheiten das zu synchronisieren

3.2 direkt einblenden




4 Ich habe hier fast 2 Stunden sehr viele Threads durchforstet, die 
meisten posten Code und stellen dann fest das etwas fehlt....

Beitrag "DCF 77"
Bei Stunden 60 statt 24
keinen Parity check
keine Fehlerabfrage

Ich suche einen code in c.

4.1 Dieser Code gefiel mir recht gut:
http://www.mikrocontroller.net/wikifiles/6/6e/Wordclock-0.11.zip

Da hier die Schnittstelle in DCF77.h zumindest beschrieben ist, auch 
wenn ich mich noch nicht bis ins Detail dort eingearbeitet habe. Etwas 
verwirrend finde ich die Aussage zur dcf77_init:

/**
 *  receive and decode DCF77 signal
 *  @details  Decode DCF77 signal - measure pulse time to
 *            decode the received signal
 *            must be called each 10ms (1000 HZ)
 *
 */

10ms sind bei mir keine 1000Hz, zumal nicht daraus hervorgeht ob es 
genau 10ms sein müssen oder ob es reicht das gepollt aus einen main zu 
machen...

Die ISR wird nur einmal am Tag aufgerufen?



4.2 Dann findet man natürlich noch den:
Beitrag "DCF77 Uhr in C mit ATtiny26"

Der startet erstmal recht "bescheiden":

extern u8 dcf77error;
extern u8 synchronize;


void scan_dcf77( void );

aber das muss nichts heißen. Arbeitet auch mit einem unabhängigen 
Uhrwerk.



Ich würde mich über eine Rückmeldung zu meinen Detailfragen, eure 
Erfahrungen und  eure Erweiterungen oder sogar Codeempfehlungen sehr 
freuen.

Viele Grüße,
Hannes

von Peter D. (peda)


Lesenswert?

Hannes schrieb:
> 1.3.1 oder würden auch 10ms reichen?

Reicht sicher.
Günstig ist eine Wert, daß zum Zählen des Sync (2s) ein Byte ausreicht.


> 2.1.1 Das Zeitfenster: Wie würdet Ihr die Grenzen für gültige 100ms und
> 200ms einstellen?

+/-10..20%


> 2.1.2 Die Pulsanzahl: Wie synchronisiert man sich am besten, ist es
> sinvoll die Pulse mitzuzählen und zu kontrollieren das nach dem 59 einer
> weg bleibt?

Ja


> 2.2.1 Parity: Parity Prüfen

Ja, kostet kaum Code.


> 2.3.1 Abfolge: Wenn zwei Pakete empfangen wurden und "gültig" sind,
> könnte man vergleichen ob sie in einem DCF77 Protokoll entsprechenden
> logischen Zusammenhang stehen, ist das nötig?

Nein.


> 3.1 eine "freie" Uhr nebenher laufen lassen, und gelegtenlich mit dem
> DCF77 Synchronisieren

Unbedingt.
Schon ein Gewitter kann den Empfang stören.


> 3.1.1 Wie oft sollte man einen Sync machen? Peter Dannegger macht es
> glaube ich täglich um 3:20?

Einfach immer, wenn ein Paket gültig ist.
Mein Problem war, daß die Antenne zu nahe an der Multiplexanzeige sitzt. 
Mit Anzeige an kriege ich daher nie gültige Pakete.


Peter

von Joachim (Gast)


Lesenswert?

Moin,

mein allererster Schritt war, daß ich das Modul an ein Scope gehängt 
habe, um erstmal zu sehen, was überhaupt passiert. Danach hab ich mir 
Gedanken über die Auswertung gemacht.

Ich mache es mit dem 1ms-Timer-Interrupt. Da checke ich dann jedes mal 
den Pegel des Pins. Ich hab dann auch erkennen können, ob ich einfach so 
zwischendurch mal Spikes hab, oder ob die Spikes schon/noch zu dem 
übertragenen Bit gehören. Mein eines Modul hat bei schlechtem Empfang 
die Bits nicht mit sauberem Pegel rausgegeben, sondern als Spike-Pakete 
mit einer Gesamtlänge des jeweiligen Bits +- 20%. Das konnte ich aber 
alles zuverlässig mit meinem kurzen Zeitfenster auswerten.

Ich führe außerdem einen Parity-Check UND einen Plausibilitätscheck 
durch. Es müssen also zwei Datenpakete direkt hintereinander fehlerfrei 
Empfangen werden.
Außerdem führe ich einen Reset des Moduls durch, wenn 20 Bits 
hintereinander den gleichen Wert hatten. Ich hab festgestellt, daß das 
Modul (Pollin) manchmal mehrere Anläufe braucht, um "sauber" zu 
empfangen.

Außerdem rechne ich noch den Zeitdrift des Controllers raus. Ich 
vergleiche ich die neu empfangene Zeit mit der Vorigen, beziehe das auf 
die gesamte Zeit zwischen den Synchronisierungen und rechne einen 
Korrekturfaktor aus, der bei jedem Interrupt berücksichtigt wird. 
Beispiel: Uhrzeit, zu der eine neue gültige Uhrzeit empfangen wird: 
3:20:36. Empfangene Uhrzeit: 3:23. Zeit zwischen den Synchronisierungen: 
24h, 16m (vorige Uhrzeit wurde um 3:07 empfangen). Dann: rechnen :)

Gruß

von Hannes (Gast)


Angehängte Dateien:

Lesenswert?

Hi Zusammen,

danke für die Rückmedlung.

Peter, wie machst du das mit der Signalerfassung, auch mit 1ms pollen?

Joachim, danke für den Tip.

Ich habe jetz erstmal das Gehäuse zusammengeklöppelt. Wollte 24 7 
Segmentanzeigen nutzen.

1 9 - 0 2 - 5 9   F r
 _ _ _ _ _ _ _ _ _ _ 

2 8.  M A r   2 0 1 1
 _ _ _ _ _ _ _ _ _ _ 

Gruß

von Hannes (Gast)


Lesenswert?

so soll es dann aussehen:

        ----        ----   ----          ----   ----          ----
     | |    |      |    |      |        |      |    |        |
     | |    |      |    |      |        |      |    |        |
        ----  ----         ----   ----   ----   ----          ---- 
----
     |      |      |    | |                  |      |        |      |
     |      |      |    | |                  |      |        |      |
        ----        ----   ----          ----   ----





 ----   ----        ----   ----                ----   ----
     | |    |      |    | |    |                   | |    |      | 
|
     | |    |      |    | |    |                   | |    |      | 
|
 ----   ----               ----   ----         ----
|      |    |      |    | |    | |            |      |    |      |      |
|      |    |      |    | |    | |            |      |    |      |      |
 ----   ---- o                                 ----   ----


Hannes

von Hannes (Gast)


Angehängte Dateien:

Lesenswert?

Harrr

von John (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Hannes,
ich würde Dir, für den Text, 16-Segment-Anzeigen empfehlen. Das sieht 
viel besser aus.

Gruß
John

von Hannes (Gast)


Lesenswert?

Hey,

hätte ich auch gern genommen, gibt es nur leider nicht so einfach in Low 
Current, zumal der Verdrahtungsaufwand dann noch mal verdoppelt wird... 
:-)

Danke für den Hinweis.

H.

von Hannes (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

so, ich habe jetzt die Hardware erstmal soweit fertig. Die erste Test 
App läuft auch schon...

Nacht,
H.

von Alex (Gast)


Lesenswert?

Hi,

ich würde an deiner stelle noch den DCF-Empfang signalisiere, indem du 
einfach das Zeichen zwischen den Ziffern Blinken lässt. Oder hast du das 
schon so gemacht?

Dein Gehäuse sieht übrigens sehr gut aus, wo bekommt man das, bzw. die 
Einzelteile (Profile/Seitenteile)?

von niemand (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Hannes schrieb:
>> 1.3.1 oder würden auch 10ms reichen?
>
> Reicht sicher.
> Günstig ist eine Wert, daß zum Zählen des Sync (2s) ein Byte ausreicht.

Hannes schrieb:
> Peter, wie machst du das mit der Signalerfassung, auch mit 1ms pollen?

Liest du Peters Beiträge? Scheinbar nicht und damit geht meine 
Motivation dir zu helfen gegen Null. Du liest die Beiträge nicht. 
Schade.

von Hannes (Gast)


Lesenswert?

Hallo Alex,

das Gehäuse ist von Conrad 523224. Gibt es in zwei größen, ich habe das 
kleinere genommen. Meiner Meinung nach ein sehr guter Preis und sieht 
gut aus.

die Filterglasscheibe hat eine Dicke von 1,5mm. Es gibt sie z.B. auch 
bei RS:

http://de.rs-online.com/web/search/searchBrowseAction.html?method=getProduct&R=0588724

Ich bin kein Fan von blinkenden Sachen am Display vorn in dem Fall. Es 
ist eine kleine 3mm LED (Low Current) am zweiten Ausgang direkt hinter 
der RJ11 Buchse an dem das DCF77 Modul angeschlossen wird (für leigenden 
Platinenzusammensetzung solange noch entwickelt wird), siehe Bild 8310. 
Im zusammengefalteten und eingebauten Zustand sind von Aussen 2 Duo LEDs 
zwischen der RJ11 und der RJ12 Buchsen hintem an der Uhr, die dann u.a. 
über den Controller den Signaleingang des DCF widerspiegeln, siehe Bild 
8166.

Hallo niemand,

du kannst deinen Namen ruhig nennen, ich bin kritikfähig, denke ich. Ich 
mag es auch nicht wenn ich den Eindruck habe das nicht gelesen wird.
Ich bewundere es ja immer wieder das Peter überhaupt alle Threads die 
seine Themen betreffen noch so fleißig betreut. Ich bin darüber sehr 
froh.

Bei der Frage ist das nicht richtig rüber gekommen, ich bin mir an der 
Stelle einfach nicht sicher wie ich das von der Programmstruktur her 
machen kann/will. Bei 10ms wären es 200 Takte in 2s, das passt in ein 
Byte. Worum es mir bei der Frage ging ist das Prinzip des Polling. Ich 
würde das ungern im Timer Interrupt machen, deswegen würde ich einen 
Softtimer alle 10ms kommen lassen. Der wird im main gepollt. In der 
Softtimerroutine würde ich im main dann den DCF Pin pollen. Es geht mir 
darum wie genau das Timing sein muss, usw...
Ich bin mir nur nicht sicher wie sich das alles mit den Routinen von 
Peter verträgt. Es kommt jetzt eh die Tage das ich den Code bei mir 
einbauen werde... Sorry wenn es so rüber kam als würde ich nicht lesen, 
Peters Antworten haben mir zu 90% Sicherheit gegeben und sehr geholfen.

Sonstiges:

Ich habe das DCF77 Modul ja extra extern, mit einem 3 Meter langen Kabel 
realisiert. Nachdem was man hier so liest schien mir das besser zu sein. 
Modul ist von Conrad, habe ich da mal vor Jahren gekauft. Ich hatte 
gestern den Eindruck das das Multiplexing auch in der Entfernung noch 
den Empfang stören kann, wobei ich noch nicht überprüft habe ob dies 
über die Versorgungsspannung geschieht, oder über Elektromagnetische 
Abstrahlungen. Aber das Modul war auch nur eben hin gebämselt...Mal 
sehen wie es ist, wenn ich es mal wieder ins Gehäuse stecke, und das 
Modul noch ein wenig bewege und drehe...

Gruß,
H

von W.S. (Gast)


Lesenswert?

Hallo zusammen,

ich meine, das Empfangssignal kriegt man in den uC doch am ehesten über 
den ADC herein oder verlaßt ihr euch auf einen Diskriminator im 
Empfangsmodul, der dann H oder L sagt? Bei letzterem gehört ein Tiefpaß 
dahinter, entweder klassisch analog oder digital im Empfangsprogramm. 
Ich mach sowas meist so, daß ich die letzten 16 oder 32 Werte mir merke 
und daraus dann eine Mehrheitsentscheidung bilde. In diesem Fall würde 
ich alle 1 ms nachschauen und ein Byte von/bis z.B. 0/31 rauf oder 
runter zählen. Vielleicht etwa so:
          if (pegel==low)&&(merker>0) --merker;
          if (pegel!=low)&&(merker<31) ++merker;
          if (dcf_entprellt&&(merker<8)) = dcf_entprellt = low;
          else if (!dcf_entprellt&&(merker>24)) dcf_entprellt = high;
oder so ähnlich.
Naja und anschließend wird nach so etwa 1500 Zyklen (also 1.5 Sekunden) 
geguckt, ob dcf_entprellt überhaupt seit dem letzten mal wenigstens 50 
mal low war oder nicht (--> Minute um) und wenn es low war, dann ob 
länger als 150 mal oder nicht und je nachdem eine 0 oder eine 1 in das 
Ergebnis-Schieberegister geschoben. Die 150 sind jetzt aus dem Stegreif, 
ich glaube es waren 100 oder 200 ms - oder?

W.S.

von Hannes (Gast)


Lesenswert?

Hallo zusammen,

so ich bin nun dabei den code von Peter bei mir einzubringen - die 
Hardware ist komplett angesteuert - das ist etwas hakelig, denn ich habe 
eigene Timer, und in Peters Code ist ein Timer fest mit eingebunden.

Eine Art Übergabe scheint über die Variablen

dcf77_period
dcf77_pulse

die in timebase.c verankert sind, stattzufinden.

die routine:

scan_dcf77() (rufe ich alle 100ms auf)

wertet das Geraffel dann aus und macht eine zeitübergabe wenn gültig.

Enthalten sind hier Zahlen wie:

dcf77_pulse > 3 && dcf77_pulse < 8

dcf77_pulse > 9 && dcf77_pulse < 15

dcf77_period > 120 && dcf77_period < 140

wenn ich den Inhalt der Timerinterruptroutine (ohne timerspezifisches 
Zeug) alle 10ms aufrufe, wie erwartet, dann habe ich dort Werte von 100 
bis 102 für die Periode und 8-11 für kurz und 19-21 für lang.

Mir stellt sich die Frage wie oft der Timer ausgeführt wird, scheinbar 
nicht alle 10ms, probiere gerade mit 8 hier rum, bekomme aber nichts 
gültiges...

Peter, wie ist das gedacht!?

Gruß,
H.

von Hannes (Gast)


Lesenswert?

und wie ist das hiermit:

      if( dcf77_period < 60 || dcf77_period > 70 )
      {
        //dcf77error = 1;
        dsp_set_decimal(1,2,10);
      }

aus scan_dcf77()

läuft er da nicht jede minute zur Sendesekunde rein?

H.

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.