Tuesday 19 February 2019

GPS Controlled Clock

The Global Positioning System (GPS) relies on a series of very accurate clocks aboard a constellation of satellites whose orbits are well known.  Differences in arrival time of signals from those satellites are used to calculate distance from them and hence geographical position.  This means that, in addition to being a navigation aid, the GPS system is also a very accurate time standard.   Methods of using this to turn a computer into a very accurate  time server are well known - just search the web for "GPS time server" and you should get plenty of examples.  I've done that myself by connecting a GPS receiver to the Raspberry Pi 2 which acts as a DHCP server, DNS, ad-blocker and file server on my home network, but for this project I wanted to make a stand-alone clock.  I have a longer term ambition to use the GPS location to identify the time zone and summer time rules for the clock's location and show the correct time for that location.  For now, it assumes it's in the UK and only corrects for UTC (GMT) / BST.  Note for any would-be burglars or stalkers:  The location displayed in the photo above has been fudged.  I don't live there.

GPS modules such as the one I used here will send UTC time along with the position fix and other data at regular intervals.  Since the serial data link is rather slow, it is uncertain exactly how old the reported time is by the time it has been received.  Typically, a GPS module will transmit data once per second, starting soon after a UTC second boundary, so the the data is unlikely to be more than a second behind the actual time.  We can do better than that, though, if we use a GPS module that also transmits a PPS signal.  PPS stands for "Pulse Per Second" and, as the name suggests it is a pulse which occurs every second, but more than that, it has a very short rise-time (about 10ns) and starts on every UTC second boundary.  By co-ordinating the time data received with this signal, we can get a very accurate time.

The strategy I've used here goes something like this:  receive and interpret the serial data stream from the GPS module (that takes about 0.15s), add 1s to that (takes <1ms) then wait for the next PPS signal before updating the clock display.  It takes about 0.05 seconds for the program to completely redraw the clock display, which is far less than the time taken for a human brain to read & interpret it.

The program is a bit more sophisticated even than that - once a GPS signal has been received, the time data is used to set the computer's clock, thereafter, the display is updated using the computer's internal clock, but that is compared to the GPS time signal and re-synchronised only if it drifts by more than 0.02s.  That way, the clock will continue to work if the GPS signal is lost.  If the signal is lost, the position data is shown in red rather than the usual green.

Inside the Box

The computer used for this project is, once again, a Raspberry Pi Zero.  I love those things - less than a fiver each and more than enough computing power for something like this with a choice of OSes and programming languages.  The screen used is a 5 inch display with, as it says on the back there, 800x480 pixels which gives a nice crisp display and cost about £16 from Amazon.  This one was intended to be used with a model B, the first one, with the 26 pin GPIO headers.  If you plug that into the socket there, the HDMI output will line up nicely with the adapter that sits in the bulge at the top of the case, and that is how the display is, er, displayed.  There is also a touch-screen which uses some of the GPIO pins, but that's not used in this project.   the header pins are also connected to a series of pads on top of the board, and I've soldered some header pins onto some of those to plug in a connector to the socket on the back panel where the GPS module plugs in.  That uses the UART pins plus one other GPIO pin to monitor the PPS signal.  I used a short mini HDMI-HDMI adapter cable to make the HDMI connection to the screen.
Here it is with everything plugged in again. The device plugged into the micro USB port is the receiver for a wireless keyboard & trackpad.  










Here it is back together again, and with the GPS module.  The box for the GPS module was made before I added the socket for high-gain antenna to the module and so it doesn't fit properly and you certainly can't get the lid on.  I've since re-designed that to suit and it looks much neater.

For the OS and programming language I made what might seem an unusual choice.  RISC OS and BBC BASIC.  Make of that what you will.  I've been a RISCOS user since it was called ARTHUR and I've always liked BBC BASIC.  I'm sure I could have written it in Python, but that would be slower and doesn't really offer any advantage that I can see.  BBC BASIC gives me easy access to those nice anti-aliased outline fonts which look pretty good on this display, plus all the OS calls to mess around with time & date strings etc.  One minor glitch was that taking over the whole system to run the program, rather than letting the OS decide how big a time slice to allocate to the clock program) meant that the CPU ran a bit hot and crashed a few times.  Downclocking to 500MHz solved that, and it has been running almost continuously since last summer without crashing at all.

A little aside about BBC BASIC running under RISCOS on just about any ARM-based SoC you can get now:  The instruction cache will hold quite a lot of the BBC BASIC interpreter and the data cache will hold all of this program.  This means that a program like this one, with a fairly small inner loop that just keeps cycling around will give a cache hit rate of close to 100%, so it is not slowed down by the need to read/write to the relatively slow RAM and is therefore astonishingly fast.  Nearly as fast as a compiled language.

No comments:

Post a Comment