Electronics > Open Source Hardware
"Laureline" embedded GPS NTP server
gxti:
A simple but effective project for your perusal. Laureline is an embedded SNTP server that receives time from a GPS receiver in the form of a pulse-per-second (PPS) input as well as the usual serial data in whatever format it comes (NMEA, Oncore, TSIP, etc.). I call it SNTP and not NTP because time is served from GPS alone and no other NTP servers are consulted. However, laureline is perfectly suitable as a Stratum 1 reference for NTP and SNTP clients alike.
The processor is a STM32F107 which includes a built-in 100Mbit Ethernet MAC, which I have paired with an inexpensive transceiver to get a good Ethernet solution with predictable and minimal latency unlike the USB-based MACs found in e.g. Raspberry Pi. Also onboard is a small VCXO which is disciplined by the microcontroller to precisely 10MHz using the GPS pulses, in effect making laureline a low-grade GPSDO. The board is powered by a buck converter that accepts 8-40VDC, allowing for direct power from a 12V or 24V lead acid battery. Other than that, the rest of the magic is in software: observing the frequency of the local oscillator by way of incoming GPS pulses, calculating NTP time from the 70MHz timer when queried and handling network administrivia.
Because almost all STM32 IOs are 5V-tolerant, the serial interface works with both 3.3V and 5V GPS receivers. I've designed but not yet fabricated some tiny adapters to connect two types of receivers to the 6-pin header on laureline, one being Oncore GT+/UT+ and probably other Motorola receivers as well, and the other being Trimble's Resolution T and Resolution SMT carrier boards. Both types are presently available used on Ebay for about $30, half that in the case of UT+. As you can see in the pictures, jumper wires also work perfectly well in lieu of an adapter. There's enough current at either 3.3V or 5V to power a typical receiver with active antenna, as well.
Here is laureline paired with an Oncore GT+, the board at lower left is an isolated USB UART I'm using for debugging:
A (blurry) closeup of the board:
Current status: rev 1 of the hardware works flawlessly, except for the power supply which needed extra capacitance. rev 2 will have a separate PSU module of my own design, so that when I screw it up again at least I can test it separately and/or swap it out.
The software is still in early development. All of the disciplining/GPSDO stuff is not written yet, although I have written such things before for an earlier project that actually was a GPSDO. Presently I hacked together a simple mechanism that just resets the counter each time a PPS arrives and does no disciplining but it's still performing quite well. It also needs to handle leap seconds, both internally and also for presenting the leap flag to NTP clients. I haven't added the code to the repository but I'll do so in the next day or two.
Repository (design docs, code, etc.): http://hg.partiallystapled.com/circuits/laureline/
In zip format: http://hg.partiallystapled.com/circuits/laureline/archive/tip.zip
Also download the library and unzip it to lib/: http://hg.partiallystapled.com/circuits/alib/archive/tip.zip
Schematic PDF: http://hg.partiallystapled.com/circuits/laureline/raw-file/tip/out/production.PDF
gxti:
Forgot to post this yesterday -- actual NTP results:
--- Code: ---[root@rei ~]# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
-64.73.32.134 192.41.214.45 4 u 501 1024 377 65.940 7.184 0.689
-24.124.0.251 128.206.12.130 3 u 457 1024 377 106.168 -18.808 46.581
+64.73.32.135 18.26.4.105 2 u 443 1024 377 67.824 5.759 0.714
-169.229.70.95 128.32.206.55 2 u 629 1024 377 103.428 7.904 1.133
*172.24.0.6 .GPS. 1 u 19 64 377 2.483 0.777 0.346
-172.24.0.66 172.24.0.1 3 u 491 1024 377 0.169 1.038 0.369
x172.24.0.68 172.24.0.66 4 u 530 1024 377 0.202 109.953 170.476
+172.24.0.1 172.24.0.6 2 u 607 1024 377 0.129 1.566 0.049
--- End code ---
--- Code: ---[root@hanmyo ~]# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
*172.24.0.6 .GPS. 1 u 5 64 377 2.531 -0.583 0.291
172.24.0.64 172.24.0.6 2 u 730 1024 377 0.135 -1.500 0.077
172.24.0.66 172.24.0.1 3 u 889 1024 377 0.387 -0.636 0.329
x172.24.0.68 108.133.178.111 2 u 932 1024 377 0.314 157.627 123.609
-64.73.32.134 192.41.214.45 4 u 993 1024 377 66.944 4.189 1.518
-24.124.0.251 64.6.144.6 3 u 846 1024 357 106.791 -21.016 37.217
+64.73.32.135 18.26.4.105 2 u 831 1024 377 68.850 4.766 0.517
+169.229.70.95 128.32.206.55 2 u 27 1024 377 103.022 5.961 0.445
--- End code ---
172.24.0.6 is laureline, 172.24.0.68 is a windows box that just can't seem to keep up :[
Note the not-fantastic 2.4ms delay. I will see what I can do about that, probably it is due to context switching. I am using ChibiOS and its example LWIP bindings, which ends up having one thread handling packets and another doing the NTP server stuff and on top of that some third thread ends up processing the receive interrupt to begin with. Which means there's a lot of handing off to other threads, which incurs additional delay. So reducing the entire network stack to a single thread will probably improve latency considerably.
gxti:
Turns out those Oncore receivers are not suitable for timing purposes. The auction listed them as "GT+" but they seem to be some older revision and don't say "GT" at all in the receiver ID. Also "GT+" isn't even the timing-oriented model, "UT+" is. That part is my fault. In any case, the dealbreaker is that the pulse-per-second output jumps forward by exactly 1ms every 16-20 seconds. With enough smoothing it could be made to work since I presume that on average the pulses are still accurate, but for now I've switched to my known-good Trimble Resolution SMT receiver. I bought 3 of these stupid Oncore receivers too, for $10 each... not the most expensive mistake I've made, and at least they will work well for position applications. I always wanted to make a data logger for my car.
I also fixed the Ethernet latency issue by using a single thread to process network data. I talked to someone else who is using the same stack and was able to get good latency figures using the regular, multi-threaded arrangement but I was unable to determine why I was not. Either way, single-threaded works and doesn't make the code any more complex so long as I'm not trying to do TCP.
New NTP figures:
--- Code: ---[root@rei ~]# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
-138.236.128.36 216.218.254.202 2 u 21 1024 377 68.819 3.228 0.641
+108.59.14.130 209.51.161.238 2 u 298 1024 377 34.920 1.167 0.288
+108.61.73.244 96.47.67.105 2 u 300 1024 377 39.524 1.135 1.604
-64.6.144.6 128.252.19.1 2 u 772 1024 377 84.329 6.609 0.252
*172.24.0.6 .GPS. 1 u 2 16 377 0.320 -0.073 0.016
-172.24.0.66 135.34.116.162 3 u 237 1024 377 0.197 0.130 0.581
x172.24.0.68 172.24.0.6 2 u 291 1024 377 0.237 113.341 77.665
-172.24.0.1 172.24.0.6 2 u 287 512 377 0.123 2.382 0.876
--- End code ---
--- Code: ---[root@maruko ~]# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
-67.18.187.111 129.7.1.66 2 u 850 1024 177 66.888 2.844 1.485
+174.129.25.69 158.227.98.15 2 u 639 1024 377 35.557 2.227 0.196
+2001:470:1:15b: 132.239.1.6 2 u 397 1024 377 107.438 1.415 0.126
172.24.0.1 172.24.0.6 2 u 673 1024 377 0.175 2.176 0.446
*172.24.0.6 .GPS. 1 u 48 16 377 0.324 0.382 0.083
172.24.0.64 172.24.0.6 2 u 795 1024 377 0.309 -0.067 0.073
172.24.0.68 172.24.0.6 2 u 821 1024 377 0.837 193.564 57.882
--- End code ---
joe912:
Cool project.
What's the end use for it? Have you investigated the IEEE 1588 timestamping features of the uC?
Also taking a look at the schematic I would recommend 0.1uF caps from TCT and RCT of the magjack to ground.
gxti:
Just for fun, mainly. I plan on building a few into enclosures and maybe selling them, but sourcing the GPS module is the limiting factor for making them in any volume. Probably I will try to find a module that's good enough for NTP but not "timing grade" since it seems that new timing receiver modules cost $70 and up. Buying more Resolution Ts from China on ebay is also an option but not ideal as I've seen similar stock dry up and disappear. I need to do some experiments with the Oncores that have a phase skip as that will likely be similar to what I see with new non-timing receivers. I don't foresee it being problematic for NTP due to less demanding precision needs and use of the VCXO as a "flywheel" to smooth out jitter. The PLL parameters will need to be slower and I will need to soak test everything to make sure they track well over time.
I may investigate IEEE 1588 in the future. A 1588 PHY is only another $5, but I would probably want to upgrade to a full ovenized oscillator once getting into that territory. Definitely worth investigating though.
I'll look at best practice for the Ethernet grounding. I don't recall if the one I'm using has builtin EMI caps but I didn't tie the shield to ground anywa.
Navigation
[0] Message Index
[#] Next page
Go to full version