aboutsummaryrefslogtreecommitdiffstats
path: root/README.html
blob: 60291200be7be0f28f3ba40d58ef283130320159 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<h1>dcf77_gps for nodemcu</h1>
<p>
 This is a lua program intended to be run on an ESP8266 loaded with
 <a href="https://www.nodemcu.com/">nodemcu</a>. It will parse pulses from a
 <a href="https://www.pollin.de/p/dcf-77-empfangsmodul-dcf1-810054">pollin</a>
 <a href="https://en.wikipedia.org/wiki/DCF77">DCF77</a> receiver module. It's
 output on the serial port (usually available over USB) will be
 <a href="https://en.wikipedia.org/wiki/NMEA_0183">NMEA GPZDA</a> sentences
 which can be understood by <a href="https://ntp.org">ntpd</a>.
</p>
<h2>Why this program?</h2>
<p>
 First of all i wanted to learn more about DCF77 and gain experience
 programming in lua. I also wanted to connect DCF77 to my (Raspberry Pi 2B
 based) ntp server without compromising the accuracy of it's already available
 PPS signal. When the receiver module looses it's signal it can easily generate
 hunderds or thousands of interrupts a second which will definately harm the
 PPS accuracy. By moving the processing to an ESP8266 the ESP will take the hit
 and just output valid data when it has a decent signal.
</p>
<h2>What does it do?</h2>
<p>
 It receives data from a DCF77 module and outputs the same data as a GPS would
 do. To do that, it has some (IMHO) neat tricks. Usually it will run in an
 interrupt driven way, with a clean signal this will trigger twice a second
 (one for the rising edge, one for the falling edge). When it detects way more
 interrupts than expected, it switches to polling mode. It will use polling to
 detect a clean signal, and only when it's clean enough it will change back to
 interrupt mode again.
</p>
<p>
 To improve accuracy and reduce the time from the rising edge of the radio 
 signal to the delivery of the GPS sentence over the serial port it partially
 calculates the required checksum for the sentences every minute. Doing so only
 leaves the second characters to be added to the checksum.
</p>
<p>
 When a clean signal is received it will blink a led to let you know it's
 working. Because LED's can be very bright when it gets dark you can set a
 minimum ambient light which will be read from the adc. When the ambient light
 is lower it will stop blinking.
</p>
<h2>How can i use this?</h2>
<p>
 Of course you'll need an ESP8266. The ESP32 might actually be compatible, but
 i don't know and haven't tested. And of course you'll need a DCF77 receiver
 module. The pollin one i have is pretty cheap (around
 <a href="https://www.vandijkenelektronica.nl/product/dcf77-moduul-met-ferrietantenne-voor-de-dcf-77-uitlezing/">EUR 10</a>,
 ignore the image on the site, it's the conrad module, but you'll get the
 pollin one when you order), the popular conrad module might also work but
 again: I haven't tested it.
</p>
<p>
 The nodemcu firmware can be build using
 <a href="https://nodemcu-build.com/">their build service</a>. This program
 requires the <b>adc</b>, <b>bit</b>, <b>gpio</b> and <b>timer</b> modules. If
 you want to use 
 <a href="https://github.com/kmpm/nodemcu-uploader">nodemcu-uploader</a> to
 upload the program, be aware that you will also need the <b>file</b>,
 <b>node</b> and <b>uart</b> modules.
</p>
<p>
 To use the program upload it to your ESP8266 and if you want it to start
 automatically when the ESP is started also upload the init.lua file. Restart
 the ESP3288 and then wait :-)
</p>
<p>
 If you look at the code you'll see quite some print statements commented out,
 those are there to help debugging. Unfortunately memory on the ESP8266 is too
 constrained to be able to uncomment them all at the same time, so use with
 caution.
</p>
<h2>What can do with this?</h2>
<p>
 With this you can make ntpd think it's receiving from a GPS while it's
 actually using your DCF77 receiver. To do that, first you'll have to instruct
 udev to create a gps symlink. I use the following rules in
 /etc/udev/rules.d/99-gps.rules:
</p>
<pre>
KERNEL=="ttyUSB0", SYMLINK+="gps0"
</pre>
<p>
 After that configure ntpd to use it with a server and fudge line in
 /etc/ntp.conf:
</p>
<pre>
server 127.127.20.0 mode 0x58 minpoll 3 maxpoll 3 prefer
fudge 127.127.20.0 stratum 0 flag1 0 flag2 0 flag3 0 flag4 0 time1 0.0 time2 0.0292 refid DCF0
</pre>
<p>
 Especially time2 should be tuned to your own setup. The command <b>ntpq
 -pn</b> should now show something like this:
</p>
<pre>
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*127.127.20.0    .DCF0.           0 l    4    8  377    0.000   -0.214   0.567
</pre>
<p>
 Have fun!
</p>