GPS for the Pi
A GY-NEO6MV2 based GPS module can be found on eBay (from Hong Kong) for less than £10 (I paid £7.12 for one with an integrated antenna - for an extra £1 or less you can get one with a separate antenna and an LED to indicate** when the satellites have been found). They communicate using a 2 wire serial interface at a default baud rate of 9600 (a 'USB GPS dongle' will be at least 3 times more expensive). All have a 'PS' (Pulse Per Second) output that delivers a high-going 100mS pulse ever second. The +ve edge coincides with the seconds 'tick' to within 1uS or better. Note that cheap units often have problems picking up a signal indoors, especially if you try to run them from the Pi's 3.3v supply (they have their own on-board voltage reg. so you are best feeding them 4.5 - 5v)
**The 'back up battery' means they continue to keep time even when no satellite is found. This means that after being powered on, it will take 3 or 4 minutes (until the satellites are found) before the time reported can be replied on.
NOTE that the GPS serial Tx is 5v. The Pi expects 3v, so you need a 'voltage divider' (link Tx to a resistor chain, 22k, 33k, Gnd. 'Tap off' the mid point to the Pi Rx pin).
To maintain accurate time, the GPS 'Pulse Per Second' (PPS) signal must be used (the 'NMEA' message strings sent at 9600 baud typically 'wander' all over the place and can appear any time up to 400mS (i.e. almost half a second) after the seconds have 'ticked over' :-) ).
So long as you are using Pi system kernel version 3.18.3 or higher, the Pi system software will 'understands' what to do with a PPS signal and will adjust the system time appropriately (i.e. you DO NOT need to recompile anything) To use GPIO pin #18 as a 'PPS signal input', just edit the /boot/config.txt file by adding the line: dtoverlay=pps-gpio,gpiopin=18 Since you wnat to use the Serial GPIO for NMEA messages, you need to disable the Pi Command Console. To do this, edit /boot/cmdline.txt to 'comment out' (add the '#' prefix) and thus disable the following two lines:- # console=ttyAMA0,115200 # kgdboc=ttyAMA0,115200 NB. If you are using the Pi as aTime Server, you will need to minimise both Serial link and Pi Ethernet latency (which is a weak point of the Raspi). Adding the following to /boot/cmdline.txt helps Ethernet :- smsc95xx.turbo_mode=0 To set the the 'low_latency' flag on the serial port, use the 'setserial' utility.
For more on using PPS, see here and for how PPS improves accuracy, see here
Using GPS on the Pi
Enable the GPIO serial port for GPS use
By default, on boot-up, the Pi uses the serial port as a terminal window to allow you to login with a 'dumb terminal' when using the Pi 'totally headless' (i.e. without a local display / keyboard) in a non-networked (or model A) environment. This needs to be disabled before you can use the serial port for anything else (such as the GPS module)
Edit the boot options file:
sudo nano /boot/cmdline.txt
Locate and comment out or remove the two lines containing the serial link ref string "ttyAMA0". For example, to 'comment out', add a '#' at the strat of each line :-
# console=ttyAMA0,115200
# kgdboc=ttyAMA0,115200
You should also edit inittab so it doesn't launch a 'login' task for the serial connection:
sudo nano /etc/inittab
Find the line following "#Spawn a getty on Raspberry Pi serial line" and add a '#' to comment it out:-
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
$ sudo nano /boot/cmdline.txt
(remove the two parameters including the string "ttyAMA0":
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200)
$ sudo nano /etc/inittab
(Comment out the line like "2:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100"
by putting a hash (#) at the start of the line. Note that the line was not
2:23 on my version of Linux, so be sure to look for the actual line with ttyAMA0.
It was the last line of the file, as it happens).
(You need to reboot to bring these changes into effect)
$ sudo reboot
(Minicom then works - to exit minicom, Ctrl-A, release, Q or X.)
$ minicom -b 9600 -o -D /dev/ttyAMA0
(If minicom gives command not found, you need to install it:)
$ sudo apt-get install minicom
Install the GPS software
After chnaging the serial link use, you can power-off the Pi and plug in the GPS module. After rebooting, you need to install 'gpsd' and 'gpsd-clients' :-
sudo apt-get install gpsd gpsd-clients
Now launch gpsd so it uses the serial link :-
Run gpsd
sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
Note that we don't need to specify the serial link data rate = this is because the clever gpsd driver incorporates 'auto-baud' detection for the GPS unit
To test it's working, use the 'cgps' command :-
cgps -s
You should get the full set of NEMA text (GPS values) in a table starting with the 'Time:'
Note that, even with battery back-up, many GPS devices will start-up sending raw GPS rather than UTC. Raw GPS is 'offset' from UTC because the raw transmissions don't implement 'leap seconds' correctly - the offset was 16s, now (2014) it's 13 seconds. The GPS receiver usually 'works it out' within a few minutes, however NTP (below) can get a bit fussy about the time 'jumping' :-)
Getting the Pi NTP to use GPS
By default, the Pi will search for an NTP (time) source on the Internet. You need to ensure it uses the GPS as a 'local' npt source. Start by instaling the ntp service :-
pi@raspberrypi:~$ sudo apt-get install ntp
Next you need to edit the file: /etc/ntp.conf and add the GPS as a source :-
# gps ntp
# i.e. use as Server the shared memory driver (type 28) provided by gpsd
server 127.127.28.0 minpoll 4
fudge 127.127.28.0 time1 0.183 refid NMEA
server 127.127.28.1 minpoll 4 prefer
fudge 127.127.28.1 refid PPS
Restart ntp:-
pi@raspberrypi:~$ sudo service ntp restart
Finally, check it's working with a 'query' to the ntp server (and watch it synchronize) :-
pi@raspberrypi:~$ ntpq -p
TIP: if at this point the 'reach' field for the SHM device stays at zero, it's likely that gpsd wasn't started with the "-n" option.
PPS (Pulse Per Second) accuracy
The GPS chip generates a PPS signel and you can 'feed' this to the Pi (and have the Pi kernal pick it up) for improved accuracy.
To do this, and get an idea of the accuracy you can achieve using the PI as a local NTP server, see here
Add PPS on opin 18 to boot
sudo nano /boot/config.txt
Insert the line :-
dtoverlay=pps-gpio,gpiopin=18
As of 19 March 2015 the "pps-gpio" should already be in /etc/modules, if not add it in now
sudo nano /etc/modules
Add
pps-gpio
Save, close & reboot
sudo apt-get -y install gpsd gpsd-clients
sudo nano /etc/default/gpsd
ignore message about dpkg -configure make file look like this:
# Default settings for gpsd.
# Please do not edit this file directly – use `dpkg-reconfigure gpsd’ to
# change the options.
START_DAEMON=”true”
GPSD_OPTIONS=”-n -G”
DEVICES=”/dev/ttyAMA0?
USBAUTO=”false”
GPSD_SOCKET=”/var/run/gpsd.sock”
ctrl+x, y to save
restart
gpsmon