As a first sketch, I developed a little DCF77 library for the arduino. The DCF77 sender broadcasts the exact time in Germany. It uses a binary format which needs to be decoded – which is exactly what the library does.
There are others around who wrote a DCF77 decoder: I would like to thank Captain for his DCF77 code. You need to have an Arduino and a DCF77 receiver in order to use this sketch.
I use the “DCF-Empfänger BN 641138″ of Conrad. You need a pull-up resistor as displayed here:
When everything is connected, the exact time is printed on the serial line. Note that this is a very early release of the software – there is a lot of functionality missing. From the README:
The current todo list is: * Use interrupt routines for detecting signal changes * Use interrupt routines to add seconds automatically (currently, the 59th second is shown properly) * Implement parity checks to prevent faulty time signals to be evaluated
The sketch eats up 6400 of the 7168 bytes in the Arduino. I am currently considering to upgrade my board to the ATMega 168 processor in order to have 16kb of memory…
You can download the code here:
The code is released under terms of the CC-GNU GPL.
hallo, nice idea!
But is it so that the Arduino can get the time ONLY when you plug in the DCF77 or time is checked every now and then?
Thanks
Ale
In a private eMail, ale asked:
“Does your arduino code check the time on the DCF77 only once or it updates the time once in a while? I’ve read you still didn’t implement interrupts, but may be there’s a dummy time-update every.. ‘n’ seconds?”
Actually, the time is only updated when the DCF77 receiver is connected. I receive an external interrupt each second from the receiver. While I update my internal buffers, I also update the current second counter. If the received time is valid (i.e. the checksums match), I use this time as the current time. If something goes wrong, I use the old (internal) time which has been updated each second.
So, to sum it up: This version relies on a working receiver all the time.
wow!
thanks for your answers! I’ll try the code as soon as I get a DCF77 receiver. Btw, you think that you can find a DCF77 receiver disassembling a DCF-clock? Some of them are ridicously cheap..
hi ale,
I heard of someone who disassembled an old radio-controlled clock and just used the receiver. Unfortunately, I don’t have a link ;-) You can try it. Typically, a DCF77 receiver module has an open-collector signal output as well as GND and VCC to power the module – so it’s pretty simple to connect. However, I don’t know whether the input voltage of 5V would be tolerated by a custom-build receiver for another device.
On the other hand, tinkering for 3 Euros… Give it a try and tell me!
-Mathias
[...] Microcontroller bestuurde klok met DCF Een langjarig project, deze klok. Ik heb er ieder jaar een ander idee over, maar er zijn wat gelijkblijvende factoren: LED-matrix, nét groot genoeg, ook ‘foefjes’ op het display, lichtsensor, DCF-ontvanger, uitbreidbaar en/of aanpasbaar. Dit is een leuk voorbeeld, of deze, of hier, Arduino met DCF. [...]
Hi
I got one “radio clock receiver” from Conrad. But,it does not work, it seems that this code is not compatible for my Arduino board(Diecimila).
Because, following statement does not work on my arduino program, if I used “#include ” in my code.
Serial.println(“bla bla”)
Actually, your code, it self does not give any compilation error, but in my program it does not show any output, I tried to debug it using Serial.println(“”); , but it gives error.
Your help in this matter will be really appericiated!
Code:
#include
#define redPin 13
int DCF77Pin=7;
int blinkPin=13;
int seconds=0;
int previousSecond =0;
int minutes=0;
int hours=0;
DCF77 myDCF=DCF77(DCF77Pin);
void setup(void) {
pinMode(blinkPin, OUTPUT);
}
void loop(void) {
int DCFsignal = myDCF.scanSignal();
if (DCFsignal) {
digitalWrite(blinkPin, HIGH);
} else {
digitalWrite(blinkPin, LOW);
}
hours=myDCF.hh;
minutes=myDCF.mm;
seconds=myDCF.ss;
if (seconds != previousSecond)
myDCF.serialDumpTime();
delay(20);
previousSecond = seconds;
}
Best regards
Ali Mahmood Khan
Hi Khan,
You write “Because, following statement does not work on my arduino program, if I used “#include ” in my code. Serial.println(”bla bla”)”. This actually sounds to me as if your development environment is somehow broken. In the code snippet you posted, there is no Serial.println(foo) anyway. It would also be helpful if you could post the error message.
Please note that I don’t know whether the code will work on recent Arduino development environments or the Diecimila board (although the board is compatible, AFAIK).
-Mathias
[...] wordt op het internet al een tijdje gewerkt met de Arduino en een externe (Conrad) DCF77 ontvanger, maar er valt nog [...]
Have you tried to setup the serial connection? ;)
Now, in my house are:
Time: 22:32:38 Date: 31.1.2009
void setup(void) {
pinMode(blinkPin, OUTPUT);
// open the serial port at 9600 bps:
Serial.begin(9600);
}
Tnx for your dcf77 code! :)
Ciao!
Hi! I have now the DCF-Empfänger BN 641138″ of Conrad. BUT it is not working very well. I live in Sweden, 250 km west of Stockholm. Maybe the BN 641138 can’t handle this distans? I am reciving pulses but only now and then. Any idea? Positioning the BN 641138 don’t seem to help.
Best regards
/Dag
Hi Dag,
my suspicion is that the receiver is not able to pick up the signal reliably. Be careful, it needs some minutes sometimes to stabilize – so just try to leave it alone for some time. You might also try to change the value of the pullup resistor – I found that there is quite some tolerance from one receiver to another.
HTH,
-Mathias
Hi,
I’m quite new to Arduino & Co and I was wondering if you could explain to me why exactly we need a pull-up resistor here and how you figured out that you need one with 8 kOhm?
Thanks,
Lars.
I’d like to second Lars’ question, I’d like to know the same thing. Thanks!
@Lars: sorry, I did not write a reply so far – call me lazy :-)
The pullup-resistor is needed because you want to supply pin #7 with a defined voltage at all times. Look at the schematic: if the DCF77 pin 3 (lets call it signal) is in an undefined state, you will receive noise on pin #7 of the arduino (lets call it receiver).
So, in order for the receiver to be in a defined state at all times, you connect it to either +5V (pull-up) or GND (pull-down). If you would do so without a resistor, this could be a short-circuit (if any of signal or receiver are at a low level). You definitely want to avoid this. (Side note: ATMega pins are tristates. In this context it means that an uninitialized pin will connect to ground – which will force all available power of your short-circuit through the ATMega. They are pretty robust – but not that robust.)
To do so you just use a resistor to limit the current that flows from 5V to GND. Usually people use with a 10k resistor. In this circuit I found the DCF77 signal reception to be better with 8k. I didn’t calculate this, I found the value through experimentation. I rarely calculate anything in my schematics, this is hobby, not work :-)
HTH,
-Mathias
Hi
I have recently got the DCF77 module from Conrad, and connected it to my Arduino Duemillanueve. My DCF77 module is highly unstable. I am unable to recieve one signal/second, i get anything from 4signals/second to 0signals/second. It just depends on how the module is lying on my desk.
My guess is that this module isnt able to detect DCF77 signals outside of central Europe(i live in the south of Sweden).
//Alexander
Hi Alexander,
have a look here: http://gonium.net/md/2009/09/16/dcf77-radio-receiver-filter-signals/
Gwen was having similar problems, maybe his solution works for you.
-Mathias
Hi md,
I have some trouble, to get my clock running…
I’ve got a signal but no value coming in :(
maybe my debug text can help you to find an answer:
Initializing DCF77 lib
Using DCF77 pin #
Time: 0:0:1 Date: 0.0.0
Time: 0:0:1 Date: 0.0.0
: Double flank detected
0: DCF77 Signal detected, Time: 0:0:1 Date: 0.0.0
duration: 171, appending value at position 0
Time: 0:0:2 Date: 0.0.0
Time: 0:0:2 Date: 0.0.0
: Double flank detected
0: DCF77 Signal detected, Time: 0:0:2 Date: 0.0.0
duration: 409, appending value at position 0
Time: 0:0:3 Date: 0.0.0
Time: 0:0:4 Date: 0.0.0
648: DCF77 Signal detected, Time: 0:0:4 Date: 0.0.0
duration: 102, appending value
thanks a lot,
Stefan
Hallo,
I am asking myself if there is any software switch when to believe the the DCF time is correctly received and does not have any outages.
Is there somthing I didn’t see?
[...] gonium.net » Blog Archive » Arduino DCF77 radio clock receiver – [...]
I tried to get your code to run on a Duemilanove which didn’t work at first. I figured out some very small changes in the names of some of the timers used by the ATMega 328. Might be useful for the people getting here from the arduino playground. Just rename the timers in the original code to the ones listed below:
TCCR2 to TCCR2A, TIMSK to TIMSK2, OCIE2 to OCIE2A
Compile, upload to your Duemilanove and have fun!
The DCF-Empfänger you specified is no longer available (under that name?) at Conrad.
Stick with this one:
http://www.conrad.de/ce/de/product/641138/DCF-EMPFAENGERPLATINE
So, I built everything together as specified in your sketch and the receive LED blinks well in like five seconds intervals differenting but it only gets time 0:0:0 and date 0.0.0 and sometimes time 0:0:1 or 0:0:2
Hi there,
I have this module : http://cgi.ebay.nl/DCF-77-Receiver-Module-Atomic-Time-Receiver-DCF77-/230545017637?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item35ad8dcb25
But it has only an inverted output. Can anyone help me with the code/schematic for arduino?
Thanks a lot..
Hi,
I tried my DCF77 module, and happened to encounter same troubles as many ( as several peaks per second, or 5 peaks per second then nothing) and then i hooked up a low pass filter (made with a 4.7mH inductor and a 10µF capacitor) on the power line of the DCF77 (I use a arduino mega, and my DCF is powered by 3.3V, but it should work as well on 5V)
Then, there’s a real improvment, i can “lock” in one or two minutes). I live in North France, that is no really very close to Frankfort …
Hope this helps !