Sunday, September 22, 2013

DCF77 via GPIO on the Raspberry Pi (patched radioclkd2)

Update 2015-02-15, see below.
Update 2016-02-14, see even farther below.

After replacing my old linux-PC based router with a Telco-supplied plastic-box, I no longer have a usable NTP server at home. As a first measure, I’ve put a small DCF77 module on a raspberry-pi. It seems that most people add a serial to usb converter for that, but the raspberry has perfectly fine GPIOs that are capable of generating an interrupt for low CPU load -- and that’s all one needs. You can find my very lightly patched radioclkd2 for parsing the pulses on github.
I’ve added an additional filtering capacitor to the back of the module (be careful, inrush current will crash your Pi when connecting the leads!) a long time ago when it was still connected to the old PC, and there’s a pullup from the pulse output (which typically is open-drain/open-collector) to Vcc (3.3V). In my case, on a Rev. A Raspberry, I use GPIO0 (probably a bad choice, because it’s also one of the two accessible i2c pins, but easily changed).
Unfortunately it turned out that at its current location, reception is pretty bad, but easily solved by repositioning the Pi.
IMG_20130922_121308764

Update:I got a few emails regarding this project (which I hadn't had running for quite some time) recently, so I'll try to add this information on the old blog-post.

First, if you get a lot of pulses with bad, and very short, lengths (<10ms)
  • Reposition the DCF77 receiver with a long cable, away from all your computer stuff and switch-mode power supplies.
  • Wrap a huge ferrite core around this cable, to attenuate wire-conducted noise to the DCF77 receiver.
  • Add additional filtering caps at both sides of the cable (near the Rpi and DCF77 receiver module).
That way, I could get reliable reception again.

Second, if your ntpd doesn't seem to register any time from radioclkd2, even if it seems to receive properly: If you enable debug mode in radioclkd2, it will *not* update the shared memory. So after you've verified proper operation, put radioclkd2 in the background without -d.

Update 2016-02-14: Here are two pictures showing radioclkd2 acquiring time from a DCF77 module.

From Chris’ Miscellanea

From Chris’ Miscellanea






13 comments:

silviu said...

Hi,

I'm curious about a few things:

- How far did you locate the receiver from the PI?
- is there a special reason for not using the default GND ?

I'm in romania - a bit far from the transmitter but I do have dcf77 clocks that work just fine, but I can't get the pi to pick it up.

Thanks

Unknown said...

- I don't have the setup running right now, but I just used a few metres of normal unshielded cable. The signal is quite strong in Germany, where I'm located, so there are normally no issues.

What do you mean by "not using the default GND?"

You could try to use a longer cable and wind it through a huge ferrite coil to suppress HF (from the Raspberry PI).

silviu said...

Thanks, I'll try moving the receiver further away from the pi and my desktop.

Regarding GND I saw from your picture that you used Pin 9 as opposed to Pin 6 - all diagrams present Pin 6 as a black ground and all the other (including the one you used) as white - I thought that maybe there's something special about them that make them desirable for this application.

Cheers

Unknown said...

There's no difference between all the GND pins, as far as I know (and according to the schematics).

Unknown said...

Thanks for the post, nice work, trying to replicate.

I am using one of these from SYMTRIK
http://www.pvelectronics.co.uk/index.php?main_page=product_info&cPath=9&products_id=2

the LED seems stable with a flash about every second.

Connected Vdd and GND to two 1.5v batteries and the TCON output to GPIO0 on my Pi (next to the 3V pin). I downloaded and compiled your code from Git. But when I run the command in your readme all i get is "no serial line change". I did not use the capacitor, do you think this could be the problem? Is this absolutely necessary, if so what size?

Thanks,

Pete.

Unknown said...

I haven't used radioclkd for a some time, but...

- run it with -d and -v, it should print every single pulse
- touch the gpio pin with a wire to Vcc(3.3V!) or GND, it must show at least one pulse!
- check if "cat /sys/class/gpio/gpioNUMBER/value" shows 0 or 1 when you connect the GPIO to Vcc or GND

If that does not show proper data, something is screwed up with that GPIO pin.

Unknown said...

Two additional remarks for troubleshooting:

- after you "echo both >/sys/class/gpio/gpioNUM/edge", the interrupt counter for GPIO should increase over time

[root@rpi-cvogel gpio4]# grep gpio /proc/interrupts
49: **3178** ARMCTRL 49 Edge 20200000.gpio:bank0
50: 0 ARMCTRL 50 Edge 20200000.gpio:bank1

Whever there are pulses, radioclkd2 in debug/verbose mode should show them (reception is very poor in my office).

[root@rpi-cvogel gpio0]# radioclkd2 -d -v -s gpio /sys/class/gpio/gpio0/value:dcd
version 0.06
Added clock unit 0 on line '/sys/class/gpio/gpio0/value:dcd'
pid 1185 for device /sys/class/gpio/gpio0/value
warning: bad pulse length 1455363072.715686
pulse start: at 1455363072.750117
warning: bad clear length 0.034431
warning: bad pulse length 0.048952
pulse start: at 1455363072.908969
warning: bad pulse length 0.008809
pulse start: at 1455363073.022650

You can have a very crude "digital scope" on your GPIO pins by doing this:


[root@rpi-cvogel gpio0]# while cat /sys/class/gpio/gpio0/value ; do : ; done
1
1
1
1
0
0

Unknown said...

Hi Christian,

Many thanks for the tips. I think I am making some progress now. When I connect the TCON pin out from the PCB to GPIO0 and run the radioclkd2 -d -v -s gpio /sys/class/gpio/gpio0/value:dcd I get the following:

[root@raspi ~]# radioclkd2 -v -d -s gpio /sys/class/gpio/gpio0/value:DCD
version 0.06
Added clock unit 0 on line '/sys/class/gpio/gpio0/value:DCD'
pid 7950 for device /sys/class/gpio/gpio0/value
warning: bad pulse length 1338508556.097678


And nothing more. Also I noticed the LED on the small PCB stays on and no longer flashes!

I did the other test you suggest, i.e. gounding the GPIO0 and I get the change in state as expected.


Any suggestions....

Thanks,

Pete.

Unknown said...

That's odd... I've added two additional pictures to the blog-post illustrating the steps I perform. -- If your pulses aren't registered on the RPI GPIOs, I have no idea what else could be wrong.

One thing of note, though: I'm using a really old Raspberry-Pi-1 (the one with the single-core CPU). But of course GPIOs should still work.

Does it stop working only after you connected the GPIO pin, or maybe even as soon as it's powered from the Raspberry-Pi? Maybe the power-supply is bad and injecting some noise?

Unknown said...
This comment has been removed by the author.
Unknown said...

Christian,

Thanks for all your help. Appears I now have a working radioclock. Appears positioning of antenna is key to get a good reception!

Thanks again,

Added clock unit 0 on line '/sys/class/gpio/gpio0/value:-DCD'
pid 24432 for device /sys/class/gpio/gpio0/value
warning: bad pulse length 0.000000
pulse start: at 1456083401.010611
warning: bad clear length 1456083401.010611
warning: bad pulse length 0.244607
pulse start: at 1456083402.008892
warning: bad clear length 0.753674
pulse end: length 0.137454 - 0: 1
pulse start: at 1456083403.017807
pulse end: length 0.134396 - 1: 1

Anonymous said...

Hi Christian,

Is there a line like "server 127.127.28.0 ..." to add to ntp.conf file ?

DCF77 module works fine and shm is updated but it seems that ntp coudn't read info.

Thanks.
Robert.

Unknown said...

Yes, one such line is needed.