DCF77 Empfänger mit Arduino betreiben

DCF77 ist ein Langwellensender in der Nähe von Frankfurt, über den die Physikalisch-Technische Bundesanstalt (PTB) die offizielle Zeit der Bundesrepublik sendet.

Ich hatte in meiner Bastelkiste noch eine DCF77 Empfängerplatine von Conrad liegen und für ein Projekt das ich plane, konnte ich den auch gut gebrauchen.  Empfänger gibt es auch bei PolinReichelt und sicher bei diversen anderen Versendern.

IMG 0266 2

Laut Anschlußbelegung ist der Empfänger wie folgt (von links nach rechts) belegt:

Pin 4: DCF-Ausgang invertiert
Pin 3: DCF-Ausgang
Pin 2: Betriebsspannung 2.5V bis 15V =
Pin 1: GND

Mit einem 10 KΩ Widerstand als Pull up und Pin2 des Arduino zum einlesen, ergibt sich folgender Aufbau.

DCF77 Arduino

In echt sieht das dann so aus.

IMG 0267

Der DCF77-Sender sendet sogenannte „Sekundenmarken“. Sie bilden den Anfang jeder Sekunde und sind entweder 100ms oder 200ms lang. Während dieser 100ms oder 200ms wird die Sendeleistung auf etwa 25% abgesenkt. Danach beginnt eine „Pause“ mit der vollen Sendeleistung (100%). Diese Pause ergänzt die laufende Sekunde: Sie ist also 900ms lang, wenn die Sekundenmarke 100ms lang war oder 800ms lang, wenn die Sekundenmarke 200ms lang war. Die Sekundenmarken werden von 0 bis 58 durchnummeriert. Eine 59. Marke gibt es normalerweise nicht, stattdessen verlängert sich die Pause nach der 58. Sekundenmarke auf 1900ms oder 1800ms (je nach Länge der 58. Marke). Diese Pause dient bei den Decodern zur Synchronisation: Wenn sie endet, beginnt die neue Minute und damit auch das nächste DCF77-Telegramm mit der Sekundenmarke 0.

In dem jeweils einminütigem Zeittelegramm ist die Zeit (Stunde und Minute) der nächstfolgenden Minute sowie das komplette Datum und der jeweilige Wochentag codiert. Die folgende Tabelle zeigt die Bedeutung der 59 Bits, die pro Minute versandt werden.

Bit  Bedeutung                    Wertig-      Bit  Bedeutung                Wertig-
                                  keit                                       keit
------------------------------------------------------------------------------------
 0   Minutenbeginn Low                         30   Stunden Einer                2
 1   Reserve                                   31   Stunden Einer                4
 2   Reserve                                   32   Stunden Einer                8
 3   Reserve                                   33   Stunden Zehner              10
 4   Reserve                                   34   Stunden Zehner              20
 5   Reserve                                   35   Prüfbit 2
 6   Reserve                                   36   Kalendertag Einer            1
 7   Reserve                                   37   Kalendertag Einer            2
 8   Reserve                                   38   Kalendertag Einer            4
 9   Reserve                                   39   Kalendertag Einer            8
10   Reserve                                   40   Kalendertag Zehner          10
11   Reserve                                   41   Kalendertag Zehner          20
12   Reserve                                   42   Wochentag                    1
13   Reserve                                   43   Wochentag                    2
14   Reserve                                   44   Wochentag                    4
15   Reserveantenne                            45   Monat Einer                  1
16   Zeitumstellung Ankündigung                46   Monat Einer                  2
17   Zeitzonenbit 1                            47   Monat Einer                  4
18   Zeitzonenbit 2                            48   Monat Einer                  8
19   Schaltsekunde Ankündigung                 49   Monat Zehner                10
20   Telegrammbeginn High                      50   Jahr Einer                   1
21   Minuten Einer                  1          51   Jahr Einer                   2
22   Minuten Einer                  2          52   Jahr Einer                   4
23   Minuten Einer                  4          53   Jahr Einer                   8
24   Minuten Einer                  8          54   Jahr Zehner                 10
25   Minuten Zehner                10          55   Jahr Zehner                 20
26   Minuten Zehner                20          56   Jahr Zehner                 40
27   Minuten Zehner                40          57   Jahr Zehner                 80
28   Prüfbit 1                                 58   Prüfbit 3
29   Stunden Einer                  1          59   keine Austastung

(Tabelle von http://www.stefan-buchgeher.info)

Ein ganz einfaches Programm, das nur die Pegeländerungen registriert und auf der Konsole ausgibt, sollte also 2 Pegeländerungen pro Sekunde erkennen.

#define DCF77PIN 2

unsigned char signal = 0;
unsigned char buffer;

void setup(void) {
 Serial.begin(9600);
 pinMode(DCF77PIN, INPUT);
}

void loop(void) {
 signal = digitalRead(DCF77PIN);
 if (buffer != signal) {
 Serial.println(signal);
 buffer = signal;
 }
}

Die Ausgabe sieht dann so aus. Jeweils  2 Werte pro Sekunde.

Pegelaenderungen konsole

Hier hatte ich ein ernstes Problem. Zunächst rauschten bei mir die 0 und 1 nur so durch. Also nicht 2 Pegeländerungen pro Sekunde sondern eher so 3-6. Des Rätsels Lösung: Ich hatte den Arduino über den USB Anschluss mit Strom versorgt, zwar über einen Hub mit eigenen Netzteil, aber letztendlich über das PC Netzteil. Offenbar sind in den 5V des PC Netzteils so starke Störungen, die den Empfang unmöglich machen. Nach dem ich das Arduino Netzteil eingesteckt hatte, hab ich wie erwartet die 2 Pegeländerungen pro Sekunde bekommen.

En Arduino Programm, das ohne weitere Bibliotheken auskommt hat  Mathias Dalheimer geschrieben ( http://gonium.net/md/2007/01/06/arduino-dcf77-v02-released/index.html ). Da diese Version bei mir in der Arduino IDE 1.0 einige Fehler beim Compilieren auswirft, hier die von mir angepasste Version, mit aktiven Debuging.

/**
 * Arduino DCF77 decoder v0.2
 * Copyright (C) 2006 Mathias Dalheimer (md@gonium.net)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/**
 * Where is the DCF receiver connected?
 */
#define DCF77PIN 2
/**
 * Where is the LED connected?
 */
#define BLINKPIN 13
/**
 * Turn debugging on or off
 */
#define DCF_DEBUG 1
/**
 * Number of milliseconds to elapse before we assume a "1",
 * if we receive a falling flank before - its a 0.
 */
#define DCF_split_millis 140
/**
 * There is no signal in second 59 - detect the beginning of
 * a new minute.
 */
#define DCF_sync_millis 1200
/**
 * Definitions for the timer interrupt 2 handler:
 * The Arduino runs at 16 Mhz, we use a prescaler of 64 -> We need to
 * initialize the counter with 6. This way, we have 1000 interrupts per second.
 * We use tick_counter to count the interrupts.
 */
#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
int tick_counter = 0;
int TIMSK;
int TCCR2;
int OCIE2;
/**
 * DCF time format struct
 */
struct DCF77Buffer {
  unsigned long long prefix	:21;
  unsigned long long Min	:7;	// minutes
  unsigned long long P1		:1;	// parity minutes
  unsigned long long Hour	:6;	// hours
  unsigned long long P2		:1;	// parity hours
  unsigned long long Day	:6;	// day
  unsigned long long Weekday	:3;	// day of week
  unsigned long long Month	:5;	// month
  unsigned long long Year	:8;	// year (5 -> 2005)
  unsigned long long P3		:1;	// parity
};
struct {
	unsigned char parity_flag	:1;
	unsigned char parity_min	:1;
	unsigned char parity_hour	:1;
	unsigned char parity_date	:1;
} flags;
/**
 * Clock variables
 */
volatile unsigned char DCFSignalState = 0;
unsigned char previousSignalState;
int previousFlankTime;
int bufferPosition;
unsigned long long dcf_rx_buffer;
/**
 * time vars: the time is stored here!
 */
volatile unsigned char ss;
volatile unsigned char mm;
volatile unsigned char hh;
volatile unsigned char day;
volatile unsigned char mon;
volatile unsigned int year;

/**
 * used in main loop: detect a new second...
 */
unsigned char previousSecond;

/**
 * Initialize the DCF77 routines: initialize the variables,
 * configure the interrupt behaviour.
 */
void DCF77Init() {
  previousSignalState=0;
  previousFlankTime=0;
  bufferPosition=0;
  dcf_rx_buffer=0;
  ss=mm=hh=day=mon=year=0;
#ifdef DCF_DEBUG
  Serial.println("Initializing DCF77 routines");
  Serial.print("Using DCF77 pin #");
  Serial.println(DCF77PIN);
  pinMode(BLINKPIN, OUTPUT);
  pinMode(DCF77PIN, INPUT);
#endif
  pinMode(DCF77PIN, INPUT);
#ifdef DCF_DEBUG
  Serial.println("Initializing timerinterrupt");
#endif
  //Timer2 Settings: Timer Prescaler /64,
  TCCR2 |= (1< 59,
 * a new minute begins -> time to call finalizeBuffer().
 */
void appendSignal(unsigned char signal) {
#ifdef DCF_DEBUG
  Serial.print(", appending value ");
  Serial.print(signal, DEC);
  Serial.print(" at position ");
  Serial.println(bufferPosition);
#endif
  dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) signal << bufferPosition);
  // Update the parity bits. First: Reset when minute, hour or date starts.
  if (bufferPosition ==  21 || bufferPosition ==  29 || bufferPosition ==  36) {
    flags.parity_flag = 0;
  }
  // save the parity when the corresponding segment ends
  if (bufferPosition ==  28) {flags.parity_min = flags.parity_flag;};
  if (bufferPosition ==  35) {flags.parity_hour = flags.parity_flag;};
  if (bufferPosition ==  58) {flags.parity_date = flags.parity_flag;};
  // When we received a 1, toggle the parity flag
  if (signal == 1) {
    flags.parity_flag = flags.parity_flag ^ 1;
  }
  bufferPosition++;
  if (bufferPosition > 59) {
    finalizeBuffer();
  }
}

/**
 * Evaluates the information stored in the buffer. This is where the DCF77
 * signal is decoded and the internal clock is updated.
 */
void finalizeBuffer(void) {
  if (bufferPosition == 59) {
#ifdef DCF_DEBUG
    Serial.println("Finalizing Buffer");
#endif
    struct DCF77Buffer *rx_buffer;
    rx_buffer = (struct DCF77Buffer *)(unsigned long long)&dcf_rx_buffer;
    if (flags.parity_min == rx_buffer->P1  &&
        flags.parity_hour == rx_buffer->P2  &&
        flags.parity_date == rx_buffer->P3)
    {
#ifdef DCF_DEBUG
      Serial.println("Parity check OK - updating time.");
#endif
      //convert the received bits from BCD
      mm = rx_buffer->Min-((rx_buffer->Min/16)*6);
      hh = rx_buffer->Hour-((rx_buffer->Hour/16)*6);
      day= rx_buffer->Day-((rx_buffer->Day/16)*6);
      mon= rx_buffer->Month-((rx_buffer->Month/16)*6);
      year= 2000 + rx_buffer->Year-((rx_buffer->Year/16)*6);
    }
#ifdef DCF_DEBUG
      else {
        Serial.println("Parity check NOK - running on internal clock.");
    }
#endif
  }
  // reset stuff
  ss = 0;
  bufferPosition = 0;
  dcf_rx_buffer=0;
}

/**
 * Dump the time to the serial line.
 */
void serialDumpTime(void){
  Serial.print("Time: ");
  Serial.print(hh, DEC);
  Serial.print(":");
  Serial.print(mm, DEC);
  Serial.print(":");
  Serial.print(ss, DEC);
  Serial.print(" Date: ");
  Serial.print(day, DEC);
  Serial.print(".");
  Serial.print(mon, DEC);
  Serial.print(".");
  Serial.println(year, DEC);
}

/**
 * Evaluates the signal as it is received. Decides whether we received
 * a "1" or a "0" based on the
 */
void scanSignal(void){
    if (DCFSignalState == 1) {
      int thisFlankTime=millis();
      if (thisFlankTime - previousFlankTime > DCF_sync_millis) {
#ifdef DCF_DEBUG
        serialDumpTime();
        Serial.println("####");
        Serial.println("#### Begin of new Minute!!!");
        Serial.println("####");
#endif
        finalizeBuffer();
      }
      previousFlankTime=thisFlankTime;
#ifdef DCF_DEBUG
      Serial.print(previousFlankTime);
      Serial.print(": DCF77 Signal detected, ");
#endif
    }
    else {
      /* or a falling flank */
      int difference=millis() - previousFlankTime;
#ifdef DCF_DEBUG
      Serial.print("duration: ");
      Serial.print(difference);
#endif
      if (difference < DCF_split_millis) {
        appendSignal(0);
      }
      else {
        appendSignal(1);
      }
    }
}

/**
 * The interrupt routine for counting seconds - increment hh:mm:ss.
 */
ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  tick_counter += 1;
  if (tick_counter == 1000) {
    ss++;
    if (ss==60) {
      ss=0;
      mm++;
      if (mm==60) {
        mm=0;
        hh++;
        if (hh==24)
          hh=0;
      }
    }
    tick_counter = 0;
  }
};

/**
 * Interrupthandler for INT0 - called when the signal on Pin 2 changes.
 */
void int0handler() {
  // check the value again - since it takes some time to
  // activate the interrupt routine, we get a clear signal.
  DCFSignalState = digitalRead(DCF77PIN);
}

/**
 * Standard Arduino methods below.
 */

void setup(void) {
  // We need to start serial here again,
  // for Arduino 007 (new serial code)
  Serial.begin(9600);
  DCF77Init();
}

void loop(void) {
  if (ss != previousSecond) {
    serialDumpTime();
    previousSecond = ss;
  }
  if (DCFSignalState != previousSignalState) {
    scanSignal();
    if (DCFSignalState) {
      digitalWrite(BLINKPIN, HIGH);
    } else {
      digitalWrite(BLINKPIN, LOW);
    }
    previousSignalState = DCFSignalState;
  }
    //delay(20);
}

Wenn man sie startet, wird auf der Konsole ausgegeben welcher Bitwert gerade erkannt wurde und, nach einem vollständigen Telegramm, auch die Uhrzeit.

Download der geänderten Version: dcf77clock_mod.ino

Bildschirmfoto 2012 06 14 um 22 53 03

 

*Info: In diesem Beitrag verweisen orangefarbende Links auf Affiliates.

41 Gedanken zu „DCF77 Empfänger mit Arduino betreiben

  1. Hallo,

    Danke für den Sketch 🙂
    Leider kann ich den Sketch nicht auf meinen Arduino Mega2560 hochladen, die IDE bleibt bei „Upload“ stehen. Andere Sketches (auch größere) kann ich wie gewohnt uploaden, nur den hier nicht. Woran kanns liegen?

    • Keine Ahnung. Habe auch leider keinen Mega zur Verfügung. Ich frage mal in der Mailingliste rum, ob jemand einen hat und ob der das nachvollziehen kann.

      • Leider nein, ich arbeite bisher nur mit Uno oder Duemilanove. Tut mir leid.
        Ansonsten habe ich bislang gute Erfahrungen gemacht mit folgender von Manfred Fuchs modifizierten DCF77 library. Den nachfolgenden Text habe ich schlicht aus meinem Sketch kopiert in der ich auch die von mir benutzte Hardware beschreibe. Vielleicht hilft das ja irgendwie weiter.

        * Origin Author: Copyright (C) 2006 Mathias Dalheimer (md@gonium.net)
        * Modified 2009 by Manfred Fuchs
        * manfred@fuchsrudel.de / http://www.mafu-foto.de
        *
        * DCF77 – Read data from a DCF77 module named DCF1 and displays date and time
        * Pollin DCF1 Article No.: 810 054
        * 77,5kHz receiver module. 3.3V!!!!
        * Level shifter for data line not needed
        * Depending on signal strength it can take a few minutes before first result will be displayed
        * PON=VCC -> Receiver is switched off
        * PON=GND -> Receiver is switched on
        * DATA=GND When carrier is max.
        * DATA=VCC When carrier is modulated

  2. Hi Dave,

    es gibt zwei „Standardgründe“:
    1) Dein Modul ist falsch angeschlossen oder kaputt
    2) Du empfängst nur ein verrauschtes Signal. Da das DCF77 Signal sehr rauschanfällig ist passiert sowas nicht gerade selten. Bei mir z.B. immer dann wenn die Waschmaschine läuft. Um das zu beheben braucht es Filter- und Fehlerkorrekturcode. Da hast aber Glück, ich habe gerade ein Projekt mit genau diesem Ziel gestartet. Die Details findest Du hier: http://blog.blinkenlight.net/2012/12/01/dcf77-project/

  3. Hi Dave,

    es gibt zwei “Standardgründe”:
    1) Dein Modul ist falsch angeschlossen oder es ist kaputt
    2) Du empfängst nur ein verrauschtes Signal. Da das DCF77 Signal sehr rauschanfällig ist passiert sowas nicht gerade selten. Bei mir z.B. immer dann wenn die Waschmaschine läuft. Um das zu beheben braucht es Filter- und Fehlerkorrekturcode. Da hast aber Glück, ich habe gerade ein Projekt mit genau diesem Ziel gestartet. Die Details findest Du hier: http://blog.blinkenlight.net/2012/12/01/dcf77-project/

  4. auf meinem mega2560 scheint es so als würde er viel zu schnell durch das signal gehen:
    Kurzer ausschnitt aus dem Debug:
    15756: DCF77 Signal detected, duration: 29, appending value 0 at position 57
    15836: DCF77 Signal detected, duration: 29, appending value 0 at position 58
    15916: DCF77 Signal detected, duration: 30, appending value 0 at position 59
    15995: DCF77 Signal detected, duration: 31, appending value 0 at position 0
    16075: DCF77 Signal detected, duration: 31, appending value 0 at position 1
    16156: DCF77 Signal detected, duration: 30, appending value 0 at position 2
    16236: DCF77 Signal detected, duration: 30, appending value 0 at position 3
    16316: DCF77 Signal detected, duration: 31, appending value 0 at position 4
    16396: DCF77 Signal detected, duration: 31, appending value 0 at position 5
    16476: DCF77 Signal detected, duration: 30, appending value 0 at position 6
    woran könnte dies liegen?

    • Hallo Simon,

      das kann daran liegen das der Empfang schlecht ist oder das Signal auf andere Art und Weise gestört wird. Ich z.b. hatte dieses Verhalten als ich den Arduino nur über USB mit Strom versorgt hatte durch die Störungen des PC Netzteils. Als ich ihm sein eigenes Netzteil gegeben hatte, hatte ich auch Empfang.

      Gruß
      Frank

  5. Hallo ich hatte das selbe Problem. Ich habe beimir den Fehler gefunden.
    Serial.println(„#### Begin of new Minute!!“);
    Drei Ausrufezeichen bei der Ausgabe mag der Arduino Mega2560 nicht.

  6. Hallo,

    Ich habe ein Arduino Mega 2560. Den upload of deine sketch bliebt am upload stehen, aber nach den entfernung die „!!!“ den upload vervollständigd mit keine probleme.

    Aber diese sketch kan nicht den zeit finden, hier ist den output:
    http://www.ravenslair.nl/files/dcf-output.txt

    Ich habe den Mega ein separat powersupply gegeben, nach ich habe gelesen dass den computer powersupply can Interferenz mit den signal, aber noch nicht den zeit….

    Vielleicht nützlich: Meine Casio Waveceptor armbanduhr kan den DCF signal empfangen, so ich weiß das den signal ist verfügbar hier.

    • Hallo Bart,

      Wenn du kannst, versuch mal das Netzteil zu tauschen. Dein Output sieht so aus, wie ich ihn auch hatte, als ich zuviele Störungen hatte.
      Bei mir lag es am Netzteil, woran es bei dir liegt kann ich dir leider nicht sagen.

      Gruß
      Frank

  7. …. Ich habe den problem entschlossen.

    Alle dcf-sketches das ich habe gesehn gebrauchen pin zwei, ein interrupt pin. Aber meine mega had eine ethernetshield oben drauf. Erraten welchen pin den shield gebraucht……

  8. Hab das ganze mal nachgebaut, aber bei mir spuckt er nur als Wert bei so ziemlich jeder Zeile nur 0 aus. Woran könnte das liegen?

    Widerstand von 10k habe ich direkt am DCF77 zwischen Signal und +5V gehängt. Der Arduino hängt an einer 9V Batt. und an USB am Laptop. Ausstecken der Stromversorgung des Laptops ändert nichts.

    Kabel zwischen Arduino (Uno R3) und DCF ist ca. 60cm lang (spielt das vll. eine rolle?).

    Bin irgendwie ratlos?
    Hier ein Screenshot: http://img46.imageshack.us/img46/5127/dcf77.jpg

    Danke
    Lg Thomas

    • Musste wohl doch an der Signalstärke gelegen haben. Habe es mal aus dem Fenster gehängt und erhalte hin und wieder nun eine 1 bei den werten anstatt fast nur nullen. Aber dennoch ist Uhrzeit und Datum immer auf 0:0:0 usw.
      Lg

  9. bekomme hier immer nen Fehler:

    //Timer2 Settings: Timer Prescaler /64,
    TCCR2 |= (1 time to call finalizeBuffer().
    */

    scheint fehlerhaft zu sein der code 🙁

  10. Hallo,
    aus den Kommentaren sehe ich, dass es wohl häufig Empfangsprobleme gibt, dazu kann ich ein paar Tipps geben.
    Das DCF Modul wird stark von Schaltnetzteilen beeinflusst. Ein Empfang in der Nähe von Computern, Fernsehgeräten, usw. ist nicht möglich. Deshalb das DCF Modul weit weg von entsprechenden Geräten betreiben. Das Kabel zum Modul kann >10m lang sein.
    Die Ferritantenne des Moduls muss quer zur Richtung Frankfurt liegend montiert werden. Das Gehäuse für das DCF Modul muss aus Kunststoff sein. Montagebleche möglichst vermeiden. Insbesondere Stahlbleche (die sind magnetisch leitfähig) beeinflussen den Empfang.
    Die Spule auf der Ferritantenne darf nicht verschoben werden. Die Spule bildet mit dem Ferritstab eine abgleichbare Induktivität, die beim Hersteller auf die Resonanzfrequenz 77,5kHz eingestellt wird.
    Zum Überprüfen des DCF Moduls schlage ich vor, das Modul alleine zu betreiben (mit Batterieversorgung). Zur Kontrolle kann dazu eine LED zwischen 5V Versorgung und dem nicht invertierten Ausgang in Reihe mit einem 1kOhm Widerstand geschaltet werden. Bei Empfang leuchtet die LED jede Sekunde für 0,1 bis 0,2s. Keine Angst, der Ausgang wird dabei nicht überlastet.
    Viel Erfolg
    Jürgen

    • Hallo,
      ich möchte mich dem Kommentar von Jürgen anschliessen: Ich hatte zwei Wochen erfolglos mit dem Pollin Modul „rumprobiert“ und das Teil beinahe aus dem Fenster geworfen… Dann habe ich mir vor einer Woche ein Scope gekauft und sofort gesehen, woran es liegt: Weg von möglichen Störquellen und eine saubere Eingangsspannung! Meine Konstruktion (noch in der Bastelphase) ist jetzt 1,5m vom Rechner und das Pollin Modul 30cm vom Arduino entfernt. So habe ich ein absolut sauberes Signal vom Pollin Modul, wobei die Ausrichtung der Antenne (Standort Neuss) bei mir keine Rolle spielt.
      Das oben geschilderte Upload Problem (hatte ich auch) liegt übrigens einzig an den drei Ausrufezeichen!
      Beste Grüsse
      Peter

      • Übrigens noch Tausend Dank an Frank, Mathias Dalheimer und alle, die hilfreiche Kommentare einstellen. Alleine würde ich sollche Programme nie hinbekommen!
        Beste Grüsse
        Peter

      • Hallo Peter Z.
        Es ist richtig, dass man vordergründig nicht viel merkt beim Drehen der Ferritantenne, aber je besser die Richtung stimmt, um so besser ist die Störfestigkeit. Ein Abweichung von +- 30 Grad spielt aber kaum eine Rolle. Es gibt aber noch einen weiteren Trick mit der Antennenausrichtung: die Antenne hat ein ausgeprägtes Empfangsminimum, wenn die Antenne genau auf den Sender zeigt. Dies lässt sich nutzen, um bekannte Störquellen auszublenden. Ideal ist also, wenn die Antenne längs auf den Störer zeigt und gleichzeitig quer zum DCF77 Sender steht.
        Seit vorgestern hab ich jetzt ein Arduino Micro und ein DCF-Modul von Reichelt. Das Reichelt DCF Modul hat einen sehr schwachen Ausgang (treibt nur +- 5µA). Das Modul versorge ich mit 3,3V vom Arduino. Am Ausgang des Moduls verbleiben dann noch 2,5V Highpegel. Es funktioniert, denn der Arduino erkennt Highpegel >= 1,9V. Dieser Ausgang ist aber nicht für längere Leitungen geeignet. Übrigens, ohne Pegelwandler braucht man bei diesem Modul keinen Pull Up Widerstand, da es einen Push/Pull Ausgang hat.
        Meine SW läuft (basiert auf Frank und Mathias). Eine Gemeinheit hatte ich zu bewältigen, beim Micro ist der Interrupt von Pin 2 + 3 vertauscht.
        Gruß
        Jürgen

  11. Hallo, ich bin mit meinem Projekt wieder etwas weiter gekommen.
    Mit der Einbindung der Library „time.h“ kann ich jetzt die interne Arduino Zeit vom DCF77 Signal synchronisieren.
    Dabei fiel gleich auf, dass überraschend häufig eine falsche Zeit gesetzt wird? Ich nahm an, dass die Parity Bits im DCF Protokoll dies verhindern würden? Dem ist leider nicht so!
    Schaltnetzteile erzeugen häufigere und kürzere Störimpulse als das DCF Signal. Diese werden als DCF Impulse mit dem Wert „0“ erkannt. Dummerweise stimmt dann auch das Parity!
    Um die Auswertung zu verbessern, ergänzte ich die Abfrage der Impulsbreiten der DCF Impulse:
    // Abfrage des Minutenwechsels
    if ((startpulse-previouspulse) > 1400 && (startpulse-previouspulse) 160) && (pulsewide 60) && (pulsewide < 140))….
    Jetzt ist es nicht mehr möglich, dass periodische Störungen als DCF Signal erkannt werden und der Minutenwechsel wird nicht durch "kein Empfang" ausgelöst.
    Die Abfrage des Zeitpunkts des Minutenwechsels verbessert die Störungserkennung weiter:
    Da das DCF Protokoll hoch präzise ist, muss auch der Minutenwechsel exakt nach 60.000ms erfolgen. Fehler entstehen nur durch schwankende Impulsbreiten und atmosphärische Störungen. Bei mir lagen fast alle Werte bei 60s +- 5ms. Also nur den Zeitstempel (millis()) bei jedem Minutenwechsel speichern und mit dem vorhergehenden vergleichen. Bei größeren Abweichungen den DCF Zeitstempel verwerfen. Wenn man die Minutenwechsel statistisch auswertet, kann man sogar den Frequenzfehler des Arduino Taktes bestimmen!

  12. Da ist leider ein Fehler in meinem letzten Kommentar (ich hab das so nicht geschrieben):
    Zu den Codeauszügen:
    // 1. Abfrage des Minutenwechsels
    if ((startpulse-previouspulse) > 1400 && (startpulse-previouspulse 160 && (pulsewide 60 && (pulsewide < 40))….
    Ich hoffe das kommt diesmal lesbar rüber?

  13. Hallo zusammen,
    erst einmal vielen Dank für die Anleitung, sie ist genau, wonach ich gesucht habe.
    Ich habe die Schaltung ebenfalls mit einem Arduino Mega und dem DCF77 Empfänger von Pollin ausprobiert, erhalte aber in der Konsole lediglich folgende Ausgabe:

    Initializing DCF77 routines
    Using DCF77 pin #2
    Initializing timerinterrupt
    Initializing DCF77 signal listener interrupt

    Danach tut sich nichts mehr. Zum Überprüfen habe ich einmal die Spannung am Empfänger gemessen. Als ich das getan habe, erhielt ich mit jedem Kontakt in der Konsole diese Ausgabe:

    Time: 0:0:0 Date: 0.0.0
    ####
    #### Begin of new Minute!
    ####
    29203: DCF77 Signal detected, 29459: DCF77 Signal detected, duration: 1, appending value 0 at position 0

    Die Schaltung sollte m.E. also korrekt sein? Wenn ich die Spannung nicht messe, bleibt die Ausgabe in der Konsole wie oben beschrieben und ändert sich auch nach einiger Zeit nicht.

    Hat jemand eine Idee, woran das liegen könnte?

    Vielen Dank & viele Grüße,
    Matthias

  14. Pingback: Poor Men’s Word Clock | Der Elektronik Freak

  15. Pingback: DS3231 – die Atomuhr des Arduino | Arduino-Hannover

  16. Ich bastle grade an einer ESP8266-Funkuhr. Nachdem ich schon aufgegeben hatte, ein halbwegs klares Signal zu kriegen (die Nadeln werden im DCF77-Modul erzeugt) hat mich Dein Beitrag dazu gebracht mal einen 1000μF-Kondensator an die Spannungsversorgung zu klemmen und es geht.

  17. Hallo!
    Ich habe eine Mega2560 die eine 16×16 LUM 2568MU302 ansteuern soll. das Programm ist geschrieben. habe eine library eingefügt in der ich vorgegeben habe wie jede Zahl von 0-9 auf der Matrix angezeigt werden soll. Suche nun eine library in der sich ein schieberegister befindet. mit dem sich die urhzeit auf der Matrix anzeigen lässt.
    wäre nett wenn mir jemand helfen könnte

  18. Hallo,
    Danke zuerst einmal für den Sketsch. Ich hab den DCF77 an einen Arduino UNO angeschlossen. Die Ausgabe funktioniert soweit, das ich ein Signal bekomme.
    Das Problem daran ist aber, das ich immer 1 Minute hinter her bin. Das heißt, wenn jetzt 8:30 Uhr ist, dann wird mir 8:29 Uhr angezeigt. Was könnte das das Problem sein?

    Ich hoffe, mein Problem ist gut geschildert und mir kann jemand weiter helfen.
    Vielen Dank

    • Hallo,
      von mir auch vielen Dank für den Sketch. Ebenfalls DCF77 an einem UNO. Ausgabe funktioniert, jedoch ist auch bei mir die Uhrzeit immer genau eine Minute hinterher. Also wie bei Daniel.
      Vielen Dank

      • Das mit dem Nachgehen um 1 Minute ist bei mir leider auch so. Liegt wohl an der Auswertung des Bitfeld-Buffers, da bin ich noch am Suchen nach dem Bug. Ich habe behelfsweise einfach die Minuten um 1 erhöht( wenn dabei 60 herauskommt, auf 0 setzen und Stunden um 1 erhöhen. Wenn dabei 24 herauskommt, die Stunden auf 0 setzen…
        Ist zwar „gepfriemelt“, aber es funktioniert…

      • Hallo,
        auch von mir vielen Dank für den Sketch. Bei mir geht die Uhr auch 1 Minute nach.
        Hat das Problem inzwischen jemand gelöst?
        Ich nutze einen Uno R3, am Notebook ohne Netzteil oder sonstigen Störquellen in der Umgebung. Andere DCF77 Uhren auf dem Schreibtisch zeigen die richtige Uhrzeit an.
        Gruß und Danke für Hilfe, bin Anfänger, habe den Uno erst seit zwei Tagen

  19. Hallo Frank,
    vielen Dank für den Sketch. Habe ihn mit einem Pollin DCF77 Modul ausprobiert. Mich hat beim Nachvollziehen verwirrt, dass in dem oben abgedruckten Listing (Textfenster) offenbar ein Stück fehlt. Und zwar befindet sich die Lücke hinter“ TCCR2 |= (1<" .
    Im Downloadfile ist aber alles ok.
    Vielleicht möchtest Du diesen Schönheitsfehler noch korrigieren?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

I accept that my given data and my IP address is sent to a server in the USA only for the purpose of spam prevention through the Akismet program.More information on Akismet and GDPR.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.