Skip to content

"Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source

I hate having to set clocks. Most of our clocks at home get the time from Internet or from the DCF77 time signal.

The problem with the DCF77 time signal is that it is quite sensitive to environmental noise from lamps or other appliances, and the reception inside buildings can be problematic in some places.

I recently installed a clock in such a location. Using Udo Klein's DCF77 analysis tool it was clear that it would be nearly impossible to get the clock to work properly as initially planned, so I started looking for solutions:

- bigger antenna (eg this one)
- external antenna
- external receiver
- different time source

For different reasons, the only viable option seemed to be a different time source. But I did not want to change the clock design. While researching a solution, I came across the Chronvertor. Although this would allow to run the clock without DCF77 signal, the clock would still have to be set from time to time (due to lack of precision of the RTC, but at least twice per year for DST adjustments), so I quickly dismissed that option. However it provided inspiration for what I eventually ended up building: a NTP to DCF77 "adapter".

I had experimented previously with the TimeNTP example from the Arduino Time library, and there was plenty of information available online about the DCF77 signal, so this quickly appeared to be a viable option. This is the result: ntp2dcf.ino.
  • Twitter
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at del.icio.us
  • Facebook
  • Google Bookmarks
  • FriendFeed
  • Digg "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source
  • Mixx "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source
  • Bloglines "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source
  • Technorati "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source
  • Fark this: "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at YahooMyWeb
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at Furl.net
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at reddit.com
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at blinklist.com
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at Spurl.net
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at NewsVine
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at Simpy.com
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source at blogmarks
  • Bookmark "Convert" NTP to DCF77 - generate a DCF77 signal on an Arduino using an NTP time source with wists
  • wong it!
  • Bookmark using any bookmark manager!
  • Stumble It!
  • Print this article!
  • E-mail this story to a friend!
  • Identi.ca

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

Лъчезар Георгиев on :

Thank you very much for this programme! I needed exactly such a converter and when I tested it, it turned out that it works 100% for me! Have you thought about selecting a software licence for it?

crox on :

Thank you very much for your feedback! I'm happy if my work can be useful to someone else.

As for the license, I will think about it and update the file (probably CC or GPL), in any case if you make improvements please share them :o)

Лъчезар Георгиев on :

I'm sorry for the lost formatting when browsing this patch, but it's still there in the comment source:

--- ntp2dcf.in0 2014-10-20 12:05:58.000000000 +0300
+++ ntp2dcf.ino 2014-10-27 19:59:42.000000000 +0200
@@ -99,7 +99,7 @@

void loop()
{
- if (timeStatus() != timeNotSet) {
+ if (timeStatus() == timeSet) {
if (now() != lastUpdate) { // new pulse every second
lastUpdate = now();
uint8_t curSec = second();
@@ -144,7 +144,7 @@
digitalClockDisplay();
#endif
}
- if (outOff < millis()) {
+ if ((signed long)(outOff - millis()) < 0) {
digitalWrite(DCFOUT, LOW);
}
}
@@ -294,7 +294,7 @@
#endif
sendNTPpacket(timeServer);
uint32_t beginWait = millis();
- while (millis() - beginWait < 1500) {
+ while ((signed long)(millis() - beginWait) < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
#if DEBUG

Anonymous on :

OK. I made a change for boards with a ceramic resonator instead of quartz crystal like my UNO: replaced the line

if (timeStatus() != timeNotSet) {

with

if (timeStatus() == timeSet) {

Thus if the gateway crashes, DCF pulse generation will stop (for 10 minutes they drift about 0,5 s here which I think is still acceptable) and the quartz crystal of the clock will determine its time, until the connection with the NTP server is resumed and a sync can be done. The other alternative is to replace the ceramic resonator with a quartz crystal, but this is not so easy and not for everybody.

Have you checked your code against mills() rollover (occurs in 7 weeks)? Do you think that the following line is safe?

if (outOff < millis()) {

Лъчезар Георгиев on :

Another small patch to get an IP address after a brownout. (Again, sorry for the lost leading spaces in each line but they're kept in the comment source.):

@@ -76,14 +76,11 @@
delay(250);
Serial.println("NTP to DCF77");
#endif
- if (Ethernet.begin(mac) == 0) {
- // no point in carrying on, so do nothing forevermore:
- while (1) {
- #if DEBUG
- Serial.println("Failed to configure Ethernet using DHCP");
- #endif
- delay(10000);
- }
+ while (Ethernet.begin(mac) == 0) {
+ #if DEBUG
+ Serial.println("Failed to configure Ethernet using DHCP, will try again...");
+ #endif
+ delay(10000);
}
#if DEBUG
Serial.print("IP number assigned by DHCP is ");

Alexander Grigorev on :

Arduino: 1.8.2 (Windows 7), Плата:"Arduino/Genuino Uno"

C:\Users\gam.FSKVOLGA\Desktop\ntp2dcf\ntp2dcf.ino: In function 'void setup()':

ntp2dcf:96: error: 'setSyncProvider' was not declared in this scope

setSyncProvider(getNtpTime);

^

ntp2dcf:97: error: 'setSyncInterval' was not declared in this scope

setSyncInterval(600); // default is 300

^

C:\Users\gam.FSKVOLGA\Desktop\ntp2dcf\ntp2dcf.ino: In function 'void loop()':

ntp2dcf:102: error: 'timeStatus' was not declared in this scope

if (timeStatus() != timeNotSet) {

^

ntp2dcf:102: error: 'timeNotSet' was not declared in this scope

if (timeStatus() != timeNotSet) {

^

ntp2dcf:103: error: 'now' was not declared in this scope

if (now() != lastUpdate) { // new pulse every second

^

ntp2dcf:105: error: 'second' was not declared in this scope

uint8_t curSec = second();

^

C:\Users\gam.FSKVOLGA\Desktop\ntp2dcf\ntp2dcf.ino: In function 'void calculateDCF()':

ntp2dcf:159: error: 'now' was not declared in this scope

if (LTZ.locIsDST(now())) {

^

ntp2dcf:167: error: 'minute' was not declared in this scope

bcdWrite(21, 27, minute());

^

ntp2dcf:171: error: 'hour' was not declared in this scope

bcdWrite(29, 34, hour());

^

ntp2dcf:175: error: 'day' was not declared in this scope

bcdWrite(36, 41, day());

^

ntp2dcf:177: error: 'weekday' was not declared in this scope

bcdWrite(42, 44, ((weekday()+5)%7)+1);

^

ntp2dcf:179: error: 'month' was not declared in this scope

bcdWrite(45, 49, month());

^

ntp2dcf:181: error: 'year' was not declared in this scope

bcdWrite(50, 57, year()-2000);

^

exit status 1
'setSyncProvider' was not declared in this scope

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"

crox on :

Hi Alexander, is it possible that you use a different Time library?

See the comments in the code - I'm using the one from https://www.pjrc.com/teensy/td_libs_Time.html

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options