Binäre DCF77 Uhr mit exponentiellem Filter und Blinkenlighty

Hmmm, bei Gelegenheit schaue ich mal per FFT nach wie hoch die Bandbreite denn jetzt wirklich ist. Ich hatte jedenfalls irgendwo in einem Datenblatt dazu was von 300Hz Bandbreite gelesen. Ich finde das nur nicht mehr. Die Wahrheit zeigt am Ende aber sowieso nur eine Messung.

Klar, daß ein digitaler Ausgang keine "Bandbreite" hat. Die Frage ist aber wie denn das Signal intern aufbereitet wird. Beim C Modul vermutlich nur per Trigger und bei den Pollins per RC + Trigger. So zumindest meine Vermutung. Wenn die Vermutung stimmt, dann muß das C Modul zappeliger sein.

Sag bescheid wenn Du vor mir was rauskriegst.

[quote author=Udo Klein link=topic=135153.msg1021130#msg1021130 date=1354728429] Klar, daß ein digitaler Ausgang keine "Bandbreite" hat. Die Frage ist aber wie denn das Signal intern aufbereitet wird. Beim C Modul vermutlich nur per Trigger und bei den Pollins per RC + Trigger. So zumindest meine Vermutung. Wenn die Vermutung stimmt, dann muß das C Modul zappeliger sein.

Sag bescheid wenn Du vor mir was rauskriegst. [/quote]

So ich habe hier mal eine erste Version meines DCF-Modul-Testprogramms am Laufen. Direkter Vergleich Pollin vs. Conrad DCF-Modul.

Die Auswertung erfolgt "traditionell", also zu kurze (<50 ms) Impulse werden verworfen, Impulse von 50...150 ms als 0-Bit und Impulse von 150...250 ms als 1-Bit interpretiert.

Anbei die Datenausgabe, normalerweise je Modul eine Zeile pro Sekunde. Anbei 61 Sekunden Auswertung, von einem Minuten-Sync zum nächsten Minuten-Sync.

Erklärung der sechs Spalten wie folgt:

  1. Spalte: P/C Impuls vom Pollin oder Conrad DCF-Modul

  2. Spalte: 0/1 Impuls wurde als 0-Bit oder 1-Bit decodiert

  3. Spalte: Millisekunden des gültigen Impulses Traditionelle Auswertung, 50...150 ms bei 0-Bit, 150...250 ms bei 1-Bit

  4. Spalte: Anzahl der zu kurzen Impulse zwischen zwei gültigen Impulsen Kurze Impulse unter 50 ms werden verworfen, die Zahl der verworfenen Impulse aufaddiert und als Summe hier angezeigt, wenn der nächste gültige Impuls als Zeile ausgegeben wird

  5. Spalte: millis()-Timer von Arduino beim Beenden des Impulses, nur die letzten 5 Stellen angezeigt Die beiden ersten Ziffern der fünfstelligen Zahl kann man als Sekundenwerte interpretieren

  6. Spalte: SYNC Falls länger als 1500 ms kein gültiger Impuls empfangen wurde, wird beim Anzeigen des nächsten gültigen Impulses SYNC angezeigt. Normalerweise sollte das nur beim Minutenimpuls alle 60 Sekunden passieren. Wenn es "Zwischendurch" passiert, dann ist aufgrund von Empfangsstörungen ein Impuls bei der Auswertung verlorgengegangen. (In diesem Fall nicht, Störlevel gering)

Also P/C 0/1 xxx yy millis() SYNC mit xxx= Dauer des gültigen Impulses yy= Anzahl der verworfenen zu kurzen Impulse vor diesem gültigen Impuls millis()= die letzten fünf Stellen des millis()-Timers SYNC= Falls 1500ms lang vorher kein gültiger Impuls empfangen wurde

P 0 108   0  79416 SYNC
C 0 150   5  79464 SYNC
P 1 212   0  80522 
C 1 213   1  80544 
P 0 107   0  81417 
C 0 118   2  81438 
P 0 103   0  82415 
C 0 130   2  82458 
P 1 209   0  83517 
C 1 241   1  83558 
P 0 110   0  84416 
C 0 142   1  84457 
P 0 116   0  85426 
C 0 114   1  85438 
P 1 203   0  86514 
C 1 207   2  86535 
P 1 204   0  87517 
C 1 236   7  87560 
P 0 111   0  88418 
C 0 120   2  88440 
P 0 103   0  89415 
C 0 114   5  89443 
P 1 209   0  90516 
C 1 205   2  90529 
P 0 101   0  91413 
C 0  83  10  91424 
P 0 102   0  92412 
C 0 116   1  92437 
P 0 107   0  93415 
C 0 112   2  93433 
P 0 108   0  94417 
C 0 120   1  94435 
P 0 115   0  95421 
C 0 126   5  95448 
P 0 107   0  96418 
C 0 125   1  96455 
P 1 212   0  97521 
C 1 241   2  97568 
P 0 105   0  98413 
C 0 149   2  98469 
P 1 215   0  99520 
C 1 249   1  99555 
P 0 112   0    419 
C 0 131   5    458 
P 0 103   0   1409 
C 0 143   2   1454 
P 1 206   0   2515 
C 1 221   4   2537 
P 0 108   0   3419 
C 0 112   2   3440 
P 1 211   0   4519 
C 1 215   2   4532 
P 0 107   0   5412 
C 0 108   6   5425 
P 1 210   0   6521 
C 1 230   1   6569 
P 1 210   0   7515 
C 1 243   1   7555 
P 1 208   0   8517 
C 1 213   3   8535 
P 0 113   0   9420 
C 0 114   2   9429 
P 0 111   0  10419 
C 0 134   0  10448 
P 1 206   0  11514 
C 1 219   3  11543 
P 1 207   0  12518 
C 1 225   3  12546 
P 0 112   0  13419 
C 0 115   3  13444 
P 1 206   0  14514 
C 1 198   3  14527 
P 1 216   0  15523 
C 1 227   3  15546 
P 0 104   0  16415 
C 0 138   1  16459 
P 1 207   0  17514 
C 1 215   0  17534 
P 0 103   0  18412 
C 0  93   0  18421 
P 0 103   0  19412 
C 0 104   3  19438 
P 0 107   0  20417 
C 0 102   3  20439 
P 1 206   0  21517 
C 1 218   2  21544 
P 1 204   0  22513 
C 1 233   4  22555 
P 0 106   0  23414 
C 0 123   2  23448 
P 0 116   0  24419 
C 0 121   2  24430 
P 1 213   0  25517 
C 1 244   0  25557 
P 0 109   0  26415 
C 0 116   3  26436 
P 0 109   0  27415 
C 0 150   1  27466 
P 1 207   0  28514 
C 1 239   6  28552 
P 0 108   0  29417 
C 0 142   1  29472 
P 1 205   0  30516 
C 1 227   1  30540 
P 0 101   0  31412 
C 0 136   9  31458 
P 0 109   0  32414 
C 0 123   2  32444 
P 1 210   0  33516 
C 1 216   4  33534 
P 0 107   0  34413 
C 0 129   2  34452 
P 0 106   0  35414 
C 0 112   1  35431 
P 0 107   0  36412 
C 0 134   7  36451 
P 0 109   0  37419 
C 0 121   3  37443 
P 0 110   0  39418 SYNC
C 0 129   2  39461 SYNC

Drei Dinge kann man an der Auswertung sehr schön sehen:

  1. Das Conrad-Modul hinkt immer etwas hinterher!

Wenn das Pollin-Modul seinen Impuls bereits als "fertig eingelesen" anzeigt, braucht das Conrad-Modul immer noch ca. 10 bis 50 ms extra, bevor der Pegel denselben Status annimmt.

  1. Die Conrad-Impulse sind im Schnitt länger als die Impulse des Pollin-Moduls!

  2. Bei geringen Störpegeln wie zum Zeitpunkt dieser Auswertung liefert das Pollin-Modul noch ein völlig fehlerfreies Ausgangssignal. Die vierte Spalte mit der Anzahl der verworfenen zu kurzen Impulse zwischen zwei ausgewerteten Impulsen ist beim Pollin-Modul hier immer bei 0, während das Conrad-Modul da meist eine einstellige Zahl von Fehlimpulsen als Störzappler am Ausgang stehen hat.

Bei Gelegenheit werde ich das Programm nochmal um Deinen Filter erweitern und etwas allgemeiner halten, so dass man nicht nur zwei verschiedene Module gegeneinander testen kann, sondern auch beim selben Modul den ungefilterten gegen den gefilterten Ausgang darstellen kann.

Merkwürdig. Wenn das C Modul ungefiltert wäre sollte es vor dem Pollin Modul anschlagen. Kannst Du die Modulanschlüsse mal vertauschen und schauen ob das C Modul immer noch hintendran ist?

[quote author=Udo Klein link=topic=135153.msg1021546#msg1021546 date=1354746025] Merkwürdig. Wenn das C Modul ungefiltert wäre sollte es vor dem Pollin Modul anschlagen. Kannst Du die Modulanschlüsse mal vertauschen und schauen ob das C Modul immer noch hintendran ist? [/quote]

Anbei mal ein Datenauszug einer Minute, wo ich mitten in der Minute die Anschlüsse Pin2 und Pin3 der beiden Module am Arduino-Board vertauscht habe.

A 0 107   0  18886 SYNC
B 0 124   3  18916 SYNC
A 0 112   0  19890 
B 0 128   4  19916 
A 0 117   0  20893 
B 0 131   5  20920 
A 1 208   0  21986 
B 1 212   2  22001 
A 0 107   0  22883 
B 0 112   0  22907 
A 0 103   0  23883 
B 0 134   1  23913 
A 1 205   0  24986 
B 1 222   2  25031 
A 0 103   0  25884 
B 0 113   2  25909 
A 1 204   0  26983 
B 1 197   3  26990 
A 0 108   0  27888 
A 0 100   0  28881 
B 0 118  24  28908 SYNC
A 0 112   0  29887 
B 0 117   3  29917 
A 1 212   0  30988 
B 1 204   1  30991 
A 0 102   0  31883 
B 0 118   8  31910 
A 1 208   0  32985 
A 0 105   0  33887 
A 0 104   0  34884 
B 0 123  19  34913 SYNC
A 0 113   0  35887 
B 1 229   1  36007 
A 1 202   0  36986 
B 1 212   4  37010 
A 0 105   0  37883 
B 0 114   2  37903 
A 1 202   0  38984 
B 1 234   1  39028 
A 1 210   0  39987 
B 1 218   2  40007 
A 0 101   0  40882 
B 0  94   5  40898 
A 0 115   0  41895 
B 0 126   1  41931 
A 0 111   0  42888 
B 0 101   2  42896 
A 1 210   0  43991 
B 1 241   1  44029 
A 0 110   0  44887 
B 0 130   2  44938 
A 0 108   0  45884 
B 0 144   2  45933 
A 0 112   0  46888 
B 0 128   4  46910 
A 1 207   0  47989 
A 1 205   0  48984 
A 1 207   0  49985 
A 0 100   0  50880 
B 0  77   3  52853 SYNC
B 1 205   1  53983 
B 0 110   0  54888 
B 1 211   0  55988 
B 1 201   0  56982 
A 1 209   0  57004 SYNC
B 0 106   0  57883 
A 0 121   0  57908 
B 0 106   0  58883 
A 0 107   0  58895 
B 0 103   0  59885 
A 0  97   0  59897 
B 0 107   0  60884 
A 0 122   0  60911 
B 0 108   0  61885 
A 0 125   0  61919 
B 1 203   0  62984 
A 1 204   0  62995 
B 0 109   0  63883 
A 0 144   0  63931 
B 1 209   0  64986 
A 1 205   0  64996 
B 0 102   0  65883 
A 0 109   0  65896 
B 0 103   0  66880 
A 0 124   0  66913 
B 1 209   0  67988 
A 1 207   1  68006 
B 0 111   0  68886 
A 0 113   0  68897 
B 1 202   0  69984 
A 1 193   0  69992 
B 0 107   0  70886 
A 0  94   0  70895 
B 0 112   0  71890 
A 0 120   0  71914 
B 1 208   0  72983 
A 0  93   0  73671 SYNC
B 0 105   0  73882 
A 1 158   1  73932 
B 0 102   0  74881 
A 0 104   6  74905 
B 0 107   0  75883 
A 0 117   2  75908 
B 1 202   0  76984 
A 1 210   0  77008 
B 0 111   0  78889 SYNC
A 0 134   0  78919 SYNC

18xxx ... 46xxx => A=Pollin, B=Conrad 47xxx ... 57xxx => 10 Sekunden für das händische Umstecken der Arduino-Anschlüsse 58xxx ... 78xxx => A=Conrad, B=Pollin

Das ist schon so: Die Conrad-Impulse dauern im Schnitt länger und sie sind später zuende als die Pollin-Pulse. Das kann natürlich auch an der Beschaltung liegen.

Das Pollin-Modul betreibe ich nur an 3.3V vom Uno-Board, da es laut Spezifikation nur bis max 3.5 V betrieben werden soll. Das Conrad-Modul hängt an 5 V mit einem 10K PullUp-Widerstand. Pegel des Pollin-Moduls also 3.3 V und Pegel des Conrad-Moduls 5 V am Arduino-Eingang.

Jedenfalls bei dieser Beschaltung produziert das Conrad-Modul bei leichten Empfangsstörungen schon kurze Störimpulse am Ausgang, bei einem Störpegel, bei dem das Pollin-Modul noch völlig fehlerfreie Impulse am Ausgang liefert. In Sekunde 28xxx, 34xxx und 73xxx hat das Conrad-Modul sogar je einen Empfangsfehler (die Empfangsfehler während ich die Module umgesteckt habe außen vor).

Trotz des bei leichten Empfangsstörungen besseren Ausgangssignals scheint das Pollin-Modul keinen Filter eingebaut zu haben, der extra Zeit benötigt, sondern im Gegenteil: Beim Durchgang durch das Conrad-Modul scheint das Signal eher ein paar mehr Millisekunden extra zu benötigen als beim Durchgang durch das Pollin-Modul.

Ich bohre mein Testprogramm nochmal ein bisschen weiter auf, es fehlt noch - Erkennung gedrehter Bits (wenn beide Module verschiedene Bits in derselben Sekunde auswerten) - Möglichkeit zum Testen mit Deinem Filter gegen ein ungefiltertes Signal

Noch ein beobachteter Unterschied zwischen Pollin- und Conrad-Modul: Unterschiedliche Zeit bis zur Impuls-Synchronisation nach einer Störung. Wenn ich mal durch Einschalten einer Energiesparlampe in 60 cm Entfernung von den Antennen eine plötzlich auftretende, starke Empfangsstörung simuliere, dann verhalten sich die Module wie folgt: - Pollin: Der Impuls kommt noch einige Sekunden lang normal, danach gar nichts mehr - Conrad: Impulse am Ausgang werden sofort zappelig, wenn die starke Störung kommt

Beim Abschalten der starken Störung beobachte ich folgendes Verhalten: - Pollin: Es dauert nach dem Entfernen der Störung ca. 15 Sekunden, bis wieder Impulse kommen - Conrad: Sofort nach dem Entfernen der Störung wieder normale Impulsausgabe

Es sieht für mich so aus, als wenn das Conrad-Modul am Ausgang genau das anzeigt, was gerade empfangen wird. Das Ausgangssignal wird nur vom gerade aktuellen Eingangssignal beeinflußt.

Und das Pollin-Modul scheint einen Speicher zu haben, mit Hilfe dessen das Timing vergangener Impulse mit dazu herangezogen wird, um den aktuellen Impuls zu bewerten und auf den Ausgang zu geben. D.h. die Flankenanstiege vor 1, 2, 3, 4, 5 etc. Sekunden führen jeweils eine Sekunde später auch unmittelbar zum Flankenanstieg am Ausgang, wenn ein Flankenanstieg empfangen wird. Und das Modul muß dann quasi anhand des Signals nur noch entscheiden, ob die Flanke nach 100 oder 200 ms wieder runtergeht. Der Start des Signals wird dagegen nicht nur direkt vom aktuellen Empfang gesteuert, sondern auch vom Empfang 1, 2, 3, 4, 5 Sekunden davor, rein über eine Fortschreibung des Timings, wann der Impuls in den Sekunden davor anfing.

@jurs: Könntest Du evtl. Dein Testprogramm zur Vergfügung stellen. Es wäre sicher für einige interessant, wie Du den Vergleich / die Auswertung umgesetzt hast. Mario (ist einer der Interessierten :) )

mkl0815: @jurs: Könntest Du evtl. Dein Testprogramm zur Vergfügung stellen. Es wäre sicher für einige interessant, wie Du den Vergleich / die Auswertung umgesetzt hast. Mario (ist einer der Interessierten :) )

Eigentlich schrieb ich ja, dass ich es erst noch fertigstellen möchte, aber wem unkommentiertes Programmlisting reicht, mit der Funktionsbeschreibung aus diesem Thread, für den kann ich es auch jetzt schon mal posten.

Wie gesagt, bisher nur "Standardauswertung" (alle Impulse <50ms als Störimpulse betrachten), Udos Filter ist noch nicht eingebaut, so dass nur zwei DCF-Module gegeneinander verglichen werden können, momentan aber nicht auch ein Modul mit seinem gefilterten Ausgang. Das kommt erst noch.

So wie der Code unten eingefügt ist: Ausgang DCF-Modul A an Pin-2 Ausgang DCF-Modul B an Pin-3 (PullUp-Widerstände bei den Modulen nicht vergessen, die einen benötigen)

Ach ja: Ich habe keine zusätzliche LED als Empfangskontrolle angeschlossen, es blinkt nur die Pin13 LED, im Code könnt ihr Umstellen, ob sie im Takt des Modul-A oder des Modul-B blinken soll.

#define DCF_A_MODULE 2
#define DCF_B_MODULE 3
#define LED 13

char error[]="SYNC";
char noerror[]="";

void setup() {
 Serial.begin(9600);
 Serial.println();
 pinMode(DCF_A_MODULE, INPUT);
 pinMode(DCF_B_MODULE, INPUT);
 pinMode(LED, OUTPUT);
}


boolean 
  BdcfState,AdcfState,
  lastBdcfState=false,
  lastAdcfState=false;

long 
  looptime,
  lastBdcfH,lastBdcfL,
  lastAdcfH,lastAdcfL,
  BdcfShortPulses,AdcfShortPulses,
  BdcfLastPulse,AdcfLastPulse,
  BdcfHighcycle,
  AdcfHighcycle;

void loop() {
  looptime=millis()%100000L; // last 5 digits
  AdcfState=digitalRead(DCF_A_MODULE);
  BdcfState=digitalRead(DCF_B_MODULE);
  digitalWrite(LED,BdcfState);
  CheckForHighCycle(looptime, AdcfState, lastAdcfState, AdcfHighcycle, lastAdcfH, lastAdcfL, AdcfShortPulses);
  CheckForHighCycle(looptime, BdcfState, lastBdcfState, BdcfHighcycle, lastBdcfH, lastBdcfL, BdcfShortPulses);
  printIfValidPulse('A', looptime, AdcfHighcycle, AdcfLastPulse, AdcfShortPulses);
  printIfValidPulse('B', looptime, BdcfHighcycle, BdcfLastPulse, BdcfShortPulses);
}

void printIfValidPulse(char c, long ltime, long &Highcycle, long &LastPulse, long &ShortPulses)
{
  char *msg;
  char buf[32];
  int bitval;
  if ((Highcycle>=50)&&(Highcycle<=250))
  {
   if (looptime>LastPulse+1500) msg=error; else msg=noerror;
   LastPulse=looptime;
   if (Highcycle>150) bitval=1; else bitval=0;
   sprintf(buf,"%c %d %3ld %3ld %05ld %s", c,bitval, Highcycle, ShortPulses,looptime,msg);
   Serial.println(buf);
   Highcycle=0;
   ShortPulses=0;
 }
}

void CheckForHighCycle(long looptime, boolean &State, boolean &lastState, long &Highcycle, long &lastH, long &lastL, long &ShortPulses)
{
  if (State!=lastState)
  {
    if (State==LOW)
    {
      Highcycle=looptime-lastH;
      if (Highcycle<50) ShortPulses++;
      lastL=looptime; 
    }
    else lastH=looptime;
    lastState=State;
  }
}

Soweit ich das überblicke, gibt es handelsüblich vier DCF-Module in Deutschland: - Conrad-DCF-Modul - Pollin-DCF-Modul - ELV-DCF-Modul - Reichelt-DCF-Modul

Hast Du auch zwei verschiedene Module zum Testen? Oder möchtest Du sogar zwei identische Module gegeneinander testen?

@Jurs: das was Du beschreibst deutet darauf hin, daß das Pollin Modul bei 1 Hz mit dem Signal phasenverriegelt. Das ist genau das, was ich in der nächsten Ausbaustufe auch tun werde. Die Preisfrage ist was das Modul danach damit anfängt. Auf jeden Fall ist das ein guter Ansatz.

So wird man den Phasenfehler / die Phasenverschiebung durch einen einfachen Tiefpassfilter los.

jurs: Hast Du auch zwei verschiedene Module zum Testen? Oder möchtest Du sogar zwei identische Module gegeneinander testen?

Aktuell habe ich gerade einen alten Conrad-Wecker beim Wickel, dem ich mal versuchen werde das DCF-Modul zu entlocken. Die Schaltung ist auf der Platine recht gut separiert und läuft mit 3V (2xAA Batterie). Zum MC des Weckers gehen 2 Leiterbahnen. Die größte Herausforderung wird wohl, an die 0,2mm Leiterbahnen einen Draht zu löten :-) Dann kann ich anfangen zu testen. Ich werde auf jeden Fall berichten.

[quote author=Udo Klein link=topic=135153.msg1022540#msg1022540 date=1354815423] @Jurs: das was Du beschreibst deutet darauf hin, daß das Pollin Modul bei 1 Hz mit dem Signal phasenverriegelt. [/quote]

OK, dann habe ich wieder einen Fachbegriff zu einem Sachverhalt gelernt, den ich mühsam per Wortschwall umschrieben habe: Phasenverriegeltes Signal

But anyway, jetzt wo ich anfange, das Signal und das mit Deinem Filter gefilterte Signal mal etwas näher auszuwerten (nur per Arduino-Sketch, ein Oszilloskop habe ich nicht), kommen mir bei Deinem Filter doch immer mehr Zweifel, auch beim Conrad-Modul.

Mal eine kurze Rückfrage zu diesem Bild: http://blinkenlightblog.files.wordpress.com/2012/11/c05_simple_pulse_train_noise_60_1000.png

Hast Du ein Oszilloskop und mit Deinem Conrad-Modul tatsächlich bei DCF-Störungen einen solchen Signalverlauf am Ausgang per Oszilloskop zu sehen bekommen?

Oder ist das ein rein von Dir angenommener Signalverlauf bei Störungen, der nicht mit einem Oszilloskop an einem realen DCF-Modul verifiziert wurde?

jurs:
Hast Du ein Oszilloskop und mit Deinem Conrad-Modul tatsächlich bei DCF-Störungen einen solchen Signalverlauf am Ausgang per Oszilloskop zu sehen bekommen?

Oder ist das ein rein von Dir angenommener Signalverlauf bei Störungen, der nicht mit einem Oszilloskop an einem realen DCF-Modul verifiziert wurde?

Hallo, ich bin fleißiger Mitleser, allerdings beruflich bedingt noch nicht viel zum Testen meiner DCF-Module (von Pollin und Conrad) gekommen. Ein 2-Kanal-50MHz-Oszilloskop hätte ich, wenn es konkrete Signalverläufe (z.B. beide Module an jeweils einem Kanal) darzustellen gilt, könnte ich die wohl auch liefern.

Meine damaligen Erkenntnisse habe ich hier festgehalten: http://sth77.blogspot.de/2012/06/projekt-analoguhr-teil-3.html Auf den viel zu kleinen Bildern erkennt man den Signalverlauf nicht besonders gut, das Video im Vollbildmodus scheint mir da besser geeignet.

sth77: Hallo, ich bin fleißiger Mitleser, allerdings beruflich bedingt noch nicht viel zum Testen meiner DCF-Module (von Pollin und Conrad) gekommen. Ein 2-Kanal-50MHz-Oszilloskop hätte ich, wenn es konkrete Signalverläufe (z.B. beide Module an jeweils einem Kanal) darzustellen gilt, könnte ich die wohl auch liefern.

Meine damaligen Erkenntnisse habe ich hier festgehalten: http://sth77.blogspot.de/2012/06/projekt-analoguhr-teil-3.html Auf den viel zu kleinen Bildern erkennt man den Signalverlauf nicht besonders gut, das Video im Vollbildmodus scheint mir da besser geeignet.

Hallo, danke fürs Posten! Die von Dir gezeigten Signalverläufe passen eher zu dem, was mein Conrad-Modul auch liefert:

  • Einschwingfehler bzw. "Prellen": Beim Wechsel des Pegels kann es sein, dass ganz kurze Zeit danach der Pegel noch ein- oder mehrmals ganz kurz zurückschwingt und den Pegel mehrmals wechselt, bevor der Pegelwechsel endgültig vollzogen ist.

  • Spikes: Kurze, oft nur einzelne Störungen während ein Pegel gesetzt ist, die nach wenigen Millisekunden wieder verschwinden

Das von Udo in Bild http://blinkenlightblog.files.wordpress.com/2012/11/c05_simple_pulse_train_noise_60_1000.png gezeigte Störverhalten, mit ständigen und extrem kurzfristigen Pegelwechseln als ein dem Signal überlagertes "stochastisches Rauschen mit hoher Frequenz" kann ich für keines meiner Module nachvollziehen.

Anyway, wer selber Testen möchte, für den habe ich mein DCF-Modul-Testprogramm nochmal etwas weiter aufgebohrt.

Mit demselben Sketch kann man nun durch Setzen eines #define Statements sowohl zwei DCF-Module anschließen und deren Signale gegeneinander vergleichen. Oder man kann ein DCF-Signal vom DCF-Modul gegen das per Softwarefilter gefilterte Signal vergleichen.

Folgende Daten werden angezeigt (erste vier Spalten): A/B: Signale der beiden DCF-Module, oder ein DCF-Modul und dessen gefiltertes Signal 0/1: Es wurde ein 0-Bit oder 1-Bit erkannt xxx: Zahl zwischen 50 und 250 mit der erkannten Dauer des Bits Die vierte Spalte gibt die Anzahl der fehlerhaften (<50ms) Impulse an, die zuvor seit dem letzten gültigen Bit aufaddiert wurden

Folgende Fehler im Signalverlauf werden angezeigt: - Summe der kurzen Pegelfehler (<50ms Pegelwechsel) zwischen zwei korrekten Impulsen (50 ... 250 ms) - Bitfehler '#': Derselbe Eingang liefert zwei Bits nacheinander, das Bit des anderen Eingangs fehlt dazwischen - Bitfehler '*': Ein Eingang liefert innerhalb von weniger als 500ms ein anderes Bit als der andere Eingang (wobei aber nicht sicher ist, dass der mit * gekennzeichnete Eingang tatsächlich das falsche Bit geliefert hat) - SYNC-Fehler: Ein Eingang liefert für mehr als 1500 ms überhaupt kein Bit (normal beim Minuten-Marker zur vollen Minute)

Die fünfstellige Zahl sind die letzten fünf Ziffern des millis() Timers

Beispiel: B 0 124 0 24197 A 0 139 0 25168 B 1 178 0 25257* A 1 218 1 26236 A 0 122 8 27148# B 0 121 0 27197 SYNC A 0 128 0 28149 B 0 129 0 28199

Erklärung: In Sekunde 25xxx hat das B-Modul ein 1-Bit geliefert, aber das A-Modul ein 0-Bit, daher Bitfehler *

Bei Timer 27148 hat das A-Modul zweimal hintereinander gefeuert, daher Bitfehler #

Bei Timer 27197 tritt ein Sync-Fehler an Modul B auf, da das vorherige Bit von Modul B älter als 1500ms ist (Modul B hatte davor zuletzt bei Timer 25257 gefeuert, und in Sekunde 26xxx gar nicht)

Na ja, das ist das beste, was ich als Auswertung herausholen konnte. Die Messung und Ausgabe der Werte verfälscht natürlich immer etwas das, was eigentlich genauestens vermessen werden soll. So dauert die Formatierung mit "printf" recht lange, Pegelwechsel werden also automatisch etwas "entprellt", ohne dass dies gewollt ist. Dadurch sieht das Signal des Conrad-Moduls etwas besser aus als es tatsächlich ist.

So wie das Programm unten einkopiert ist, dient es zum Testen von Udos Exponentialfilter. Einfach DCF-Modul an Pin-2 hängen und Sketch laufen lassen mit Ausgabe über den seriellen Monitor.

Was man deutlich sieht: Der Exponentialfilter verzögert das DCF-Signal am gefilterten (B) Ausgang um ca. 50 ms.

Eine Verbesserung des Signals durch den Filter kann ich allerdings nicht feststellen, weder an einem mittelstark noch an einem stark gestörten Signal. Sobald der Störpegel hoch genug ist, dass die "High"-Pegel von Störsignalen zerhackt werden, so dass das Conrad-Modul keine einwandfreien Signale mehr liefert, ist auch das gefilterte Signal fehlerhaft (Sync-Fehler beim ungefilterten und beim gefilterten Signal in derselben Sekunde).

Nur sehr selten läßt sich durch das Filter eine gute Fehlerkorrektur erkennen wie hier: A 0 70 1 68087 B 0 70 0 68137 A 0 51 0 69069 A 0 108 0 69186# B 1 165 0 69233* A 0 89 0 70087 B 0 90 0 70138

In Sekunde 69xxx feuert das Conrad-Modul zwei gültige Bits (51 und 108ms lang) in derselben Sekunde (Bitfehler #), aber das gefilterte Signal gibt nur ein einziges Bit aus, und zwar ein langes 1-Bit statt zweier kurzer 0-Bits, daher Bitfehler * angezeigt. Da man weiß, dass im DCF-Protokoll nur ein Bit pro Sekunde übertragen wird, kann man also davon ausgehen, dass das am gefilterten Ausgang(B) gelieferte 1-Bit korrekt ist und die zwei davor am A-Ausgang signalisierten 0-Bits falsch.

Im Schnitt ist auf dem gefilterten Signal zwar weniger Gezappel durch weniger Flankenwechsel, aber dabei gehen praktisch genau so viele Bits von Sekundenpulsen verloren wie bei der Auswertung des ungefilterten Signals. Denn das Gezappel durch Flankenwechsel tritt bei gestörtem Signal nicht gleichverteilt über das gesamte Signal auf, sondern bevorzugt um die Zeit herum, um die tatsächlich ein Flankenwechsel stattfindet. Und das läßt sich eigentlich auch durch ein einfaches Entprellen des Signals von wenigen ms gut herausfiltern.

Was ergeben Eure Tests?

Also meine anfängliche Euphorie über den Exponentialfilter und dass damit das Signal viel besser aussieht, konnte ich durch meine Messungen nun nicht mehr bestätigen. Zwar sind gefilterte Signale immer mindestens 50 ms lang, während ungefilterte Signale oft sehr zappelig sein können, aber da die Zappeligkeit fast nur um den eigentlichen Flankenwechsel herum auftritt, ist eigentlich auch das Originalsignal gut auswertbar.

Hier das Testprogramm zum vorherigen Beitrag:

/************************************************************************* 
 Testprogramm zum Testen von DCF-Modulen und DCF-Softwarefiltern

 Es können entweder zwei DCF-Module gegeneinander getestet werden
 Dazu die zwei Dateneingänge mit den Pins DCF_A_MODULE und DCF_B_MODULE verbinden
 und die Zeile "#define B_IS_FILTERED_A" auskommentieren

 Oder es kann ein DCF-Modul gegen einen Softwarefilter getestet werden
 Beispielhaft ist der hier vorgestellte Filter eingebaut:
 http://arduino.cc/forum/index.php?topic=135153.0
 Dazu das DCF-Modul an den Pin DCF_A_MODULE anschliessen und
 die Zeile "#define B_IS_FILTERED_A" in den Code einfügen
 (Der Pin DCF_B_MODULE bleibt dann frei.)
  
**************************************************************************/

// Pin fuer DATA-Ausgang des DCF-Moduls
#define DCF_A_MODULE 2

// Pin fuer DATA-Ausgang des zweiten DCF-Moduls oder den Software-Filter
#define DCF_B_MODULE 3

// die nachfolgende Zeile auskommentieren, wenn zwei Module getestet werden sollen
#define B_IS_FILTERED_A
// (wenn "#define B_IS_FILTERED_A" gesetzt ist, den Pin für das DCF_B_MODULE freilassen!)

// legt fest, an welchem Pin eine LED blinken soll
#define LED 13

#ifdef B_IS_FILTERED_A
  #include 
#endif

char error[]="SYNC";
char noerror[]="";

void setup() {
  Serial.begin(9600);
  Serial.println();
  pinMode(DCF_A_MODULE, INPUT);
  pinMode(DCF_B_MODULE, INPUT);
  pinMode(LED, OUTPUT);
#ifdef B_IS_FILTERED_A
  pinMode(DCF_B_MODULE, OUTPUT);
  MsTimer2::set(1, low_pass_filter);
  MsTimer2::start();
#endif
}

#ifdef B_IS_FILTERED_A
void low_pass_filter() {
    // http://en.wikipedia.org/wiki/Low-pass_filter#Continuous-time_low-pass_filters
    // I will use fixed point arithmetics with 5 decimals
    const uint16_t decimal_offset = 10000;
    static uint32_t smoothed = 0*decimal_offset;
    const uint32_t input = digitalRead(DCF_A_MODULE) * decimal_offset;
//    const uint32_t input = analogRead(dcf77_analog_sample_pin)>200? decimal_offset: 0;
    // compute N such that the smoothed signal will always reach 50% of
    // the input after at most 50 samples (=50ms).
    // N = 1 / (1- 2^-(1/50)) = 72.635907286
    const uint16_t N = 72;
    smoothed = ((N-1) * smoothed + input) / N;
    // introduce some hysteresis
    static uint8_t square_wave_output = 0;
    if ((square_wave_output == 0) == (smoothed >= decimal_offset/2)) {
        // smoothed value more >= 50% away from output
        // ==> switch output
        square_wave_output = 1-square_wave_output;
        // ==> max the smoothed value in order to introduce some
        //     hysteresis, this also ensures that there is no
        //     "infinite memory"
        smoothed = square_wave_output? decimal_offset: 0;
      digitalWrite(DCF_B_MODULE, square_wave_output);   //changed jurs
    }
}
#endif


boolean 
  BdcfState,AdcfState,
  lastBdcfState=false,
  lastAdcfState=false;

byte
  AdcfBitval,BdcfBitval;

long 
  looptime,
  lastAdcfH,lastAdcfL,
  lastBdcfH,lastBdcfL,
  AdcfShortPulses,BdcfShortPulses,
  AdcfLastPulse,BdcfLastPulse,
  AdcfHighcycle, BdcfHighcycle;

void loop() {
//  looptime=millis()%100000L; // last 5 digits
  looptime=millis();
  AdcfState=digitalRead(DCF_A_MODULE);
  BdcfState=digitalRead(DCF_B_MODULE);
  digitalWrite(LED,BdcfState);
  CheckForHighCycle(looptime, AdcfState, lastAdcfState, AdcfHighcycle, lastAdcfH, lastAdcfL, AdcfShortPulses);
  CheckForHighCycle(looptime, BdcfState, lastBdcfState, BdcfHighcycle, lastBdcfH, lastBdcfL, BdcfShortPulses);
  printIfValidPulse('A', looptime, AdcfHighcycle, AdcfLastPulse, AdcfShortPulses, AdcfBitval, BdcfBitval, BdcfLastPulse);
  printIfValidPulse('B', looptime, BdcfHighcycle, BdcfLastPulse, BdcfShortPulses, BdcfBitval, AdcfBitval, AdcfLastPulse);
}

void printIfValidPulse(char c, long ltime, long &Highcycle, long &LastPulse, long &ShortPulses, byte &Bitval, byte OtherBitval, long LastOtherPulse)
{
  char *msg;
  char bitError;
  char buf[32];
  if ((Highcycle>=50)&&(Highcycle<=250))
  {
   // Falls mehr als 1500 ms kein Impuls ==> SYNC (Minutenimpuls oder Sync-Error) 
   if (looptime>LastPulse+1500) msg=error; else msg=noerror;
   // > 150 ms HIGH => 1-Bit, 50...150 ms HIGH => 0-Bit
   if (Highcycle>150) Bitval=1; else Bitval=0;
   // Biterror falls innerhalb der letzten 500 ms ein anderes Bit am anderen Eingang gemeldet wurde
   bitError=' ';
   // Biterror erkennen, falls weniger als 500 ms vorher ein anderes Bit am anderen Eingang erkannt wurde
   if ((looptimeLastOtherPulse) bitError='#';

   LastPulse=looptime;
   sprintf(buf,"%c %d %3ld %3ld %05ld%c%s", c, Bitval, Highcycle, ShortPulses,looptime%100000L,bitError,msg);
   Serial.println(buf);
   Highcycle=0;
   ShortPulses=0;
 }
}

void CheckForHighCycle(long looptime, boolean &State, boolean &lastState, long &Highcycle, long &lastH, long &lastL, long &ShortPulses)
{
  if (State!=lastState)
  {
    if (State==LOW)
    {
      Highcycle=looptime-lastH;
      if (Highcycle<50) ShortPulses++;
      lastL=looptime; 
    }
    else lastH=looptime;
    lastState=State;
  }
}

Interessanter Beitrag! Bin aber leider ebenfalls aus Zeitgründen noch nicht zum Testen gekommen. Hoffentlich schaffe ich das noch vor den nächsten Semesterferien :fearful:

Aber eine Frage kommt mir doch auf: Du tastest mit einer Frequenz von 1 kHz ab. Fehlt da nicht noch irgendeine Form von analogem Tiefpass vor der digitalisierung, damit höherfrequente Störungen nicht in den niederfrequenten Teil des Spektrums rutschen? Soetwas haben wir jedenfalls zum Thema Analog-Digitalwandlung in Verbindung mit digitaler Regelung in einer Vorlesung gehört...

Ich habe am Wochenende auch mal den DCF-Empfänger aus dem Conrad-Wecker ausgeschnitten. Die beiden Leiterbahnen die zum MC des Weckers gingen habe ich auf zwei digitale Eingänge gelegt. Einer liefert eine 1, der andere eine 0, daher vermute ich mal Signal und invertiertes Signal. Allerdings habe ich bisher noch keinerlei Änderungen an den Ausgängen feststellen können, ich muss mir noch eine bessere Position für den Aufbau suchen, zur Zeit sind da zu viele Netzteile und Monitore in der näheren Umgebung.

mkl0815: Die beiden Leiterbahnen die zum MC des Weckers gingen habe ich auf zwei digitale Eingänge gelegt. Einer liefert eine 1, der andere eine 0, daher vermute ich mal Signal und invertiertes Signal. Allerdings habe ich bisher noch keinerlei Änderungen an den Ausgängen feststellen können, ich muss mir noch eine bessere Position für den Aufbau suchen, zur Zeit sind da zu viele Netzteile und Monitore in der näheren Umgebung.

Es ist zwar richtig, dass die DCF-Module von Conrad auch einen invertierten ausgang haben, so recht kann ich mir das bei einer Funkuhr jedoch nicht vorstellen. Da halte ich es eher für einen Eingang, um das Modul zu Stromsparzwecken ein- und ausschalten zu können. Die Wikipedia schreibt im Funkuhr-Artikel dazu:

Obwohl das Zeitsignal kontinuierlich gesendet wird, wird es aus Stromspargründen oft nur ab und zu zum Nachstellen abgefragt. Bei Uhren, die mit größeren Zellen betrieben werden, ist ein Empfang jede volle Stunde üblich, bei Armbanduhren mit Knopfzellen oder mit Solarzellen nur einmal pro Tag, meistens zwischen 2:00 und 4:00 Uhr morgens.

Einen entsprechenden Eingang haben bspw. auch die Pollin-Module.

Hmm, guter Tipp. Bei den Pollin-Modulen wird der ON/OFF Eingang glaub ich auf Masse gezogen, um das Modul zu aktivieren. Ich werde das heute Abend mal testen.

Du tastest mit einer Frequenz von 1 kHz ab. Fehlt da nicht noch irgendeine Form von analogem Tiefpass vor der digitalisierung, damit höherfrequente Störungen nicht in den niederfrequenten Teil des Spektrums rutschen?

Wieso sollte es einen analogen Tiefpass brauchen? Der exponentielle Filter ist doch ein Tiefpass. "Analoge" Filter sind nicht auf magische Weise besser.

Kann der Digitale Filter denn die Aliaseffekte ausgleichen, die BEIM Abtasten entstehen?

And1G: ich dachte Du hast eine Vorlesung zu dem Thema gehört. Wieso fragst Du dann mich? Und vor allem wieso stellst Du Dich dumm? Selbstverständlich kann überhaupt kein Filter Alias Effekte ausgleichen die ins Passband rutschen. Die Frage ist nur: treten die tatsächlich auf? in meinem Fall also: gibt es Überlagerungen die nahe bei 500 Hz oder einer Oberwelle davon sind? Bei einem Empfänger der eine Bandbreite von wohel eher <300 Hz hat? Ich würde sagen nein. Wenn Du aber anderer Meinung bist, dann belege das doch bitte etwas genauer. Auf die Begründung bin ich mal gespannt.

Warum ich frage? Na weil meine bisherigen Kenntnisse etwas anderes sagen als das was du realisiert hast. Da wundert man sich und stellt dann halt eine Frage, ganz normaler Vorgang. Es hätte ja durchaus sein können, dass irgendetwas da zwischendurch eingekoppelt wird. Kein Grund sich gleich angegriffen zu fühlen oder so genervt zu reagieren.