DCF77 with Arduino ATMEGA 328 and ATTINY85 and DCF-2 module from ELV

The DCF77 library from Thijs Elenbaas can be used to get time from an DCF receiver.
This page describes the problems I ran into when programming the DCF with an ATMEGA 328 ie Arduino UNO and a ATTINY85 processor.


It took me several days and four false starts to get the DCF77 module working with the DCF77 library from Thijs Elenbaas with an Arduino UNO.

I bought my DCF-module from ELV elektronik AG. The DCF-2. The module operates from 1.2 - 15V, gives a pulse between 0 and 5V and therefor easy to connect in the Arduino environment.

The DCF77 library is part of the Arduino software IDE and with the examples it is easy to start. Unfortunately not all is as easy as one would like it to be. Especially if the system is not working.

Produktabbildung DCF-Empfangsmodul DCF-2
This DCF-2 module gives a reversed signal what results is that 0 bits becomes a 1 and 1 bits zero in the software.
The blue line is what is measured direct from the DCF77 module (no signal at 5V and a pulse at 0V) and the yellow line what it should be (0V signal with a pulse of 5V).
To get this inversed (yellow) signal a inverter was made with a PNP-transistor BC327.

The 4.7K resistor is for pulling down the signal. The 2.2K resistor is for safety. With out the resistor the circuit also operates.
The 100 nF ceramic capacitor is added for a smoother signal.
A BC556 transistor also works well.

Update June 2016
What would life be easy when documentation was complete and clear. The library contains a flag to invert the signal.

The library initialization contains a third parameter. OnRisingFlank. This is default set to true (HIGH).
Initialize the library as follows: DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT, LOW);

Below are the functions the library gives you to use:
DCF77(DCF77Pin, DCFinterrupt, OnRisingFlank); // Initialize library
time_t getTime(); // Returns the current time in CET
time_t getUTCTime(); // Returns the current time in UTC
Start(); // Start listening to DCF77 signal
Stop(); // Stop listening to DCF77 signal

Nice links with info about DCF receivers:
Online signal from Mainflingen on website
Explains the bits in the received string Arduino projects 4you
HKW-Elektronik GmbH  Sells all kinds of receivers
Rheinturmfunkuhr mit Arduino
Arduino DCF77 radio clock receiver ,Matthias Dalheimer
Github Thijs Elenbaas
Conrad receiver

Update September 2016

After updating the libraries and boards some compiling errors occured

after changing
#include "Time.h"
#include "TimeLib.h"
the source code compiled again without errors



Programming the ATTINY85 was easy after discovering that the ATTINY85 must be bootloaded as a 16MHz processor and that the signal must be attached to Pin3 with interrupt 0. Detecting Rising flank interrupt seems only be possible on pin3 was a suggestion in a forum. A processor running at 16MHZ seems essential without changing the library timings

Because the ATTINY85 does not have a serial.print I used the heartbeat subroutine to indicated that a time has been received. Until then the program shows the DCF77 signal that is received. The signal should be steady, turning on and off every second.

The INO source file

// Version 04. Ed Nieuwenhuys 7 may 2017
// ATtiny45 / ATtiny85
// |----U----|
// Pin 5 Reset | 1 o 8 | VCC
// (Analog input 3) Pin 3 | 2 7 | Pin 2 (Analog Input 1, SCK)
// (Analog input 2) Pin 4 | 3 6 | Pin 1 (PWM, MISO)
// -GND | 4 5 | Pin 0 (PWM, AREF, MOSI)
// |---------|
// #include "DCF77.h" #include "TimeLib.h" enum PinAssignments { PIN01 = 0, // DCF_LEDP1 = 1, // DCF LedPin PIN02 = 2, // DCF_PIN = 3, // DCF Pulse on interrupt pin PIN04 = 4, // PIN05 = 5, // };

static unsigned long msTick; // the number of millisecond ticks since we last incremented the second counter

//-------------------------------------------- // Heartbeat //-------------------------------------------- uint8_t hbval = 128; int8_t hbdelta = 8; static unsigned long last_time = 0; time_t time; byte Heartbeat = 0; //--------------------------------------------
#define DCF_INTERRUPT 0 // Interrupt number associated with pin
byte DCF_signal = 0; // is a proper time received?

void setup()
pinMode(DCF_LEDP1, OUTPUT );
analogWrite(DCF_LEDP1, 5);
msTick = millis();

void loop() {
time_t DCFtime = DCF.getTime(); // Check if new DCF77 time is available
if (DCFtime!=0)
Heartbeat = 1;
if (Heartbeat) heartbeat();
else digitalWrite(DCF_LEDP1,1-digitalRead(DCF_PIN)); //Turn on/off the led
}void heartbeat()
unsigned long now = millis();
if ((now - last_time) < 40) return;
last_time = now;
if (hbval > 230 || hbval < 20 ) hbdelta = -hbdelta;
hbval += hbdelta;
analogWrite(DCF_LEDP1, hbval);

Ed Nieuwenhuys, May 2017 September 2016  
< -- Back to the Word clock project