Getting GPS to work on a Raspberry PI

One of the tasks I want to use a Raspberry PI for is to take over the duties of an existing ITX based linux box running my weather station. Now in theory that should be pretty simple as the current setup uses pywws to connect to the station and as that’s written in python it should work.

Now the Raspberry PI has no onboard Real time clock – which means it needs to use an NTP server to get the time when it starts. Usually you would use the default settings and allow the PI to connect to thenet for it’s time. Now this is fine if you have a working net connection but what if you are not connected to the net? You might be in the field running the PI on batteries.

As the other projects I have lined up for it is to connect my Meade LX200GPS telescope to the local network or to work with my (in prototype) radio telescopes so having an accurate clock is going to be required.

Now the obvious solution here is to use GPS as a time source. GPS works by having a constellation of satellites in orbit and each one carries a highly accurate atomic clock & broadcast both their current position and the time. A GPS receiver then receives these signals and, as long as it has enough satellites and workout where you are by comparing the times from those clocks.

So this article shows how to use A GPS receiver with the Rasperry PI – although these instructions are not specific to the PI.

The hardware

For this experiment I’m using a USB GPS receiver from Maplin – product code A73KF. I bought this several months ago when they had it on special offer for £19.99 – it usually retails for £29.99.

Raspberry PI with the A73KF GPS receiver plugged in

Now it comes with a CD for Windows machines but we don’t need it – as the majority of GPS receivers I know of use serial & this is no exception. When plugged in it appears as a serial port.

Plug it in and run lsusb

pi@raspberrypi:~$ sudo lsusb
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

There the Prolific Technology entry is the GPS appearing as a serial port. If you look in /var/log/syslog you will also notice it will have created the port as /dev/ttyUSB0 as it’s the first serial port.

Using the PI as a GPS Receiver

Now the next step is to get the pi receiving data from the satellites. Now there is a suite of tools available for Linux called gpsd which we’ll install:

pi@raspberrypi:~$ sudo apt-get install gpsd gpsd-clients python-gps

Next we need to start the daemon:

pi@raspberrypi:~$ sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock

Ignore any messages from the console or in the log files, you may see it complaining about IPv6 but you can ignore that.

Viewing whats in the sky & your location

Now GPS doesn’t work indoors – as it needs a clear view of the sky so for this I’ve placed the PI on the window sill. Next I ssh into the pi and run cgps.

pi@raspberrypi:~$ cgps -s

The -s flag is there to tell the command not to write raw data to the screen as well as the processed data.

You should then get the following output:

┌───────────────────────────────────────────┐┌─────────────────────────────────┐
│    Time:       2012-06-18T15:05:10.0Z     ││PRN:   Elev:  Azim:  SNR:  Used: │
│    Latitude:    51.231848 N               ││  14    43    249    40      Y   │
│    Longitude:    0.514014 E               ││  25    75    283    37      Y   │
│    Altitude:   132.3 m                    ││   2    26    085    31      Y   │
│    Speed:      0.0 kph                    ││  12    56    070    18      Y   │
│    Heading:    0.0 deg (true)             ││   9    19    133    22      Y   │
│    Climb:      0.0 m/min                  ││  27    09    133    17      Y   │
│    Status:     3D FIX (1 secs)            ││   4    17    045    31      Y   │
│    GPS Type:                              ││  32    05    321    20      Y   │
│    Longitude Err:   +/- 8 m               ││  29    41    192    18      Y   │
│    Latitude Err:    +/- 9 m               ││  31    28    304    42      Y   │
│    Altitude Err:    +/- 27 m              ││                                 │
│    Course Err:      n/a                   ││                                 │
│    Speed Err:       +/- 68 kph            ││                                 │
│                                           ││                                 │
│                                           ││                                 │
│                                           ││                                 │
│                                           ││                                 │
│                                           ││                                 │
└───────────────────────────────────────────┘└─────────────────────────────────┘

Here you can see it’s receiving from 10 satellites and it has the time and your location. The 3D FIX section tells you it has enough data for a 3D fix on your location (i.e. altitude). The Err lines tell you the error in your position. If you leave it running you should see the Err values change every second or so.

Viewing GPS under X-Windows

Now above I showed how the GPS looks from an SSH connection but you can get a graphical display as well using the xgps client thats also been installed. Now if you have a monitor connected to the pi simply open a terminal and run xgps. However as I’ve not got a monitor against the window I’ve used ssh to connect to it from another machine. To get this to work you need to add -Y to the ssh command.

peter@somehost:~ $ ssh -Y pi@raspberrypi
pi@raspberrypi:~$ xgps

You should now get a window like the following open on your local machine – don’t worry if it takes a little while, it might take a second or two:

xgps running on a PI but being displayed on Mac OS-X

Setting the computer time using GPS

Now we have a working GPS we can now get the PI to use it for setting the time. To do this we need to configure ntp to use the GPS satellites as a time source. Now you should already have ntp installed but if not then you need to install it:

pi@raspberrypi:~$ sudo apt-get install ntp

Next you need to edit the file: /etc/ntp.conf and add a few lines to it defining the GPS. This can be either before or after the existing lines beginning with server:

# gps ntp
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

Now restart ntp:

pi@raspberrypi:~$ sudo service ntp restart

Now if you query the server you should after a while see it synchronize:

pi@raspberrypi:~$ ntpq -p
remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*ns1.luns.net.uk 33.117.170.50    2 u   54   64    7   65.454    2.666   5.800
+resntp-b-vip.lo 127.151.91.34    3 u   45   64   17   55.704   -5.169   8.482
+bart.nexellent. 194.242.34.149   2 u   17   64   17   76.585   -4.271  57.595
+v01.s01.be.it2g 193.190.230.65   2 u   20   64   37   86.464   -2.374 228.460
xSHM(0)          .NMEA.           0 l   11   16  377    0.000  144.714   3.026
SHM(1)          .PPS.            0 l    -   16    0    0.000    0.000   0.000

A couple of notes:

You might find that ntp doesn’t connect to the gps at first. It appears that it starts gpsd up without the link to the serial port. What I find I have to do is:

pi@raspberrypi:~$ sudo killall gpsd
pi@raspberrypi:~$ sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
pi@raspberrypi:~$ sudo service ntp restart

Once I’ve done this then after it gets a fix then it starts working. Sometimes running cgps and waiting for it to get a fix also fixes this.

I don’t know why this happens but it’s an issue I’ve yet to solve.

Author: petermount1

Prolific Open Source developer who also works in the online gaming industry during the day. Develops in Java, Go, Python & any other language as necessary. Still develops on retro machines like BBC Micro & Amiga A1200

135 thoughts on “Getting GPS to work on a Raspberry PI”

  1. Hi, great post thanks. Your using a GPS receiver – can you suggest any products that send and receive?

  2. I am currently developing for ST-22 GPS module attached via UART. Should work the same way (using /dev/ttyAMAO), but unfortunately gpsd doesn’t support the Skytraq binary protocol, which i need to edit some config. But I can switch to NMEA after configuring, so it should work just fine.
    This module is small (2cmx2cm) and lightweight (9 gr), cheap (20€) and energy-efficient (~50mA@5V) and it can be directly attached to Pi without any TTL voltage changes.
    I’ll report if I get it up and running.

    1. Thanks yes it would be interesting as I have noticed that there are some cheap modules around. Not sure if it’s the same module but did see one for less than £10 a few weeks ago.

      One tip, the gpio lines on the pi is 3v3 not 5v TTL but I’ve not yet got around to that side of things yet.

      1. Thats the nice thing about this module: Vcc is best for Pi (5V), but logic levels are 3,3V (at least it says HIGH=min. 2,9V)
        Some other modules I found had a rather high power consumption or a much higher price. A £10 module would be great anyway!

  3. Great Post! But i’m having a slight issue. I’m using that exact same gps receiver as you on a raspberry pi. However, I can’t get any of the gpsd clients to work, they all report “NO FIX”. If I use gpscat the coordinates are displayed. The blue LED light is flashing.

    Why might this be?

      1. Ok, I was going to take a look when I got home.

        It sounds like a similar issue I mentioned at the end of the article. I’ve still not figured that one out yet.

      2. See Adafruit explanation of gps pi hat : Raspbian Jessie systemd service fix
        Note if you’re using the Raspbian Jessie or later release you’ll need to disable a systemd service that gpsd installs. This service has systemd listen on a local socket and run gpsd when clients connect to it, however it will also interfere with other gpsd instances that are manually run (like in this guide). You will need to disable the gpsd systemd service by running the following commands:

        Download file Copy Code
        sudo systemctl stop gpsd.socket
        sudo systemctl disable gpsd.socket
        Should you ever want to enable the default gpsd systemd service you can run these commands to restore it (but remember the rest of the steps in this guide won’t work!):

        Download file Copy Code
        sudo systemctl enable gpsd.socket
        sudo systemctl start gpsd.socket

  4. Is it possible to use the data from the USB unit to be used my own software such as use the height and co-ordinates?

    1. yes you can. All that xgps or cgps does is read from the receiver. The receiver simply appears to the pi as a serial port so your own software simply needs to connect to the port & read from it.

      Although I’ve not used it myself (yet) there is a python library for doing this (it’s installed as part of this article) but parsing standard nmea strings isn’t that difficult either – I did that once about 10 years ago in java.

  5. I was just joking with a friend that a NTS server could not only be made with any old computer that could take a GPS but probably even a Raspberry-PI; then I used Google searching on Raspberry-Pi UPS & GPS. Wow!

    Is the time available to a millisecond or less? What OS do you have on your Pi?

    1. First when I wrote that article it was the original debian flash image but I’m now using raspian but it should work fine as is.

      As for millisecond or less, the gps receiver used is a standard consumer unit which appears as a serial port to the pi so it’s limited by that so it wont be that accurate but close.

      Saying that it is possible to get that resolution & the pi comes into its own here as you can get gps receivers in component form which you could build a unit for under £15. On ebay theres a UK seller (Brighton) selling some gps receiver chips for £5. These chips support SPI so you can get the pi to talk directly with the receiver. With that and a little programming you could then get millisecond accuracy.

      1. Thanks, I’m in the US and my PI has not yet been shipped. I bought a Globalsat BU353 which I managed to get working on my macAIr under Mountain Lion with Globalsat’s driver – inside my house! Today I got it working on a work HP notebook that I have “repurposed” to Ubuntu 10.10. It was a snap following your directions to get it working (after I took it outside).

    2. Acording to data sheet, my GPS module gives a signal with 0,3µs accuracy on one pin (“1PPS”). We could just use this signal and ignore the normal GPS data (after we read out the time once). So I think the Pi should be able to achieve <1ms…

      1. Yes, exactly, you’ll need to break out the pps signal so your ntpd can be told via gpsd when the second changes. Otherwise it could be any time within a fairly large window which can vary quite a bit because of other things happening on the USB. Perhaps you could use one of the gpios on the raspberrypi – as peter says thats the way to go.

      2. Unfortunately, I somehow killed my GPS device before I could get any useful results, so this is paused until I can afford a new one.
        I used a connector for parallel port on ATX mainboards and soldered the needed pins to the GPS device, because this connector had exactly 13×2 pins. I just took a random GPIO pin and connected it to 1PPS for later use. Until I get this to work I’ll just use the time given in the NMEA packages.
        I think I have a rather small delay, because I’m not using any USB devices and even plan to deactivate the USB/LAN chip to save some more energy.

  6. I have same module from Maplin and have tried all your steps. It all works up until the ntpq results. Its just not getting data from the gpsd side I think. Tried restarting gpsd and ntp etc and tried wheezy and Adafruits distro, both give same results. Still its kept me busy for a Sunday evening.

    1. Did you try to get a gps fix first?

      I remember having to run cgps briefly until it got a fix then it worked.

      The article was done on wheezy but I’m going to redo it on raspian soon – don’t see any reason it wont work.

  7. Yes gps fix side works fine, it would make a nice gps display/logger.
    I assume the problem lies in ntp getting the data from the shared memory port.
    I have a serial gps with a 1pps output somewhere and when I find it will try that on the gpio port.

  8. hi
    great article. how stable does NTP report this to be as a reference clock? I can see you have added a fudge factor of 183 milliseconds in an attempt to line the source up with internet sources. I guess the dongle outputs the serial data somewhat late, which is not a problem in itself, but the stability of that latency is critical. the would you have any thoughts on how stable this really is? my guess is the dongle will have hiccups when constellations change, causing delays in the nmea output, which in turn make ntp somewhat unstable.
    I am yet to get my hands on my pi, but cant wait to give this a spin

  9. Awesome post and had me up and running very quickly. One question: I need to run the 3 reset commands after I boot the Pi. I’m very new to Linux and I’d like to add these commands to a startup script. I think I need to create the script in /etc/init.d/ folder. I need the script to run after the daemon for gpsd has been initialised, but where do I find the boot order? In old school windows/DOS it would be something like autoexec.bat.

  10. Thankyou for the walkthorugh, I got mine working no worries, just a tip, run a script on startup to call /etc/init.d/startup.sh with “gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock” in it and it works first time everytime 😉 Keep up the good work! Cheers Bj

  11. Hello Peter,
    I am using Holux M 215 gps (10c4:ea60 Cygnal Integrated Products, Inc. CP210x Composite Device)

    when I run cgps -s, I get GPS timeout message.\
    since my gps shows up as /dev/gps0 I have tried to change to
    sudo gpsd /dev/gps0 -F /var/run/gpsd.sock
    but no result either.
    any ideas what could be wrong?
    thanks
    Szekla

  12. Oct 8 18:52:43 raspberrypi gpsd[315]: gpsd:ERROR: /dev/ttyUSB0: device activation failed.
    Oct 8 18:52:43 raspberrypi gpsd[315]: gpsd:ERROR: device open failed: Permission denied – retrying read-only
    Oct 8 18:52:43 raspberrypi gpsd[315]: gpsd:ERROR: read-only device open failed: Permission denied
    Oct 8 18:52:43 raspberrypi gpsd[315]: gpsd:ERROR: /dev/ttyUSB0: device activation failed.

    I get the above.

    And when I type ‘lsusb’ I get the following.

    Bus 001 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

    And nothing works….

    1. The problem are the privileges on /dev/ttyUSB0.
      I have added chmod 666 /dev/ttyUSB0 to the start procedure in /etc/init.d/gpsd.
      The gps now works immediately after a reboot.

    1. When I’ve used the receiver I’ve always have had the gps plugged in before powering the pi up so I’ve not tried to get gpsd to run only when it’s plugged in.

  13. You should remove the ntp instructions, ntp is not using your gps for time. ntpd is using ns1.luna for the time. Your GPS is marked as a false ticker (hence the x) and your PPS signal is unreachable (0 in reach column). I’m not sure why you have the PPS signal marked as prefer?

    1. Also why did you set time1 to 0.183? Did you copy instructions from a sure gps tutorial?Or did you verify that 0.183 was the proper calibration offset?

      1. 0.183 was used mainly due to that value being used by most other available examples in setting up gpsd.

        Now that value might simply be one that’s been reused for that same reason although one does mention its for the NMEA 183 standard, coincedence?

    2. Yes when I did this I actually did it with no ntp instructions & with the gps line first. When the gps line was first it actually had the ntp instructions marked with an x.

      What’s in the article is what I had at the time when I wrote it but you’re right about removing the ntp instructions.

  14. Hello,

    and thanks for the tutorial, I get to the point in the tutorial where I
    type in

    “cgps -s”

    I get the error “cgps: no gpsd running or network
    error: -4, can’t create socket”

    I am accessing the pi using ssh from Ubuntu 12.04 (Debian GNU/Linux wheezy/sid)

    If I type “gpsmon /dev/ttyUSB0” I get data from the gps below (not quite close enough to the window at times)

    /dev/ttyUSB0 9600 8N1 Garmin Serial binary> Time:
    1970-01-01T00:00:00(null +— Position —++—- Satellite ——+ ¦
    Fix: no fix ¦¦Ch PRN Az El SNR ST¦ ¦ Lat: -41.35342¦¦ 0 1 291 21 -1.0 0¦
    ¦ Lon: 173.18456¦¦ 1 11 303 5 -1.0 0¦ ¦ Alt: 61.56m¦¦ 2 14 91 25 -1.0 0¦
    ¦ Speed: 0.0m/s¦¦ 3 16 2 14 -1.0 0¦ ¦ Climb: 0.0m/s¦¦ 4 20 237 42 -1.0
    0¦ ¦ Leap: 16sec ¦¦ 5 22 32 7 -1.0 0¦ ¦ epe: nanm ¦¦ 6 23 250 21 -1.0 0¦
    ¦ eph: nanm ¦¦ 7 25 133 23 -1.0 0¦ ¦ epv: nanm ¦¦ 8 30 21 42 -1.0 0¦ +–
    ID 51 (0x33) +¦ 9 31 144 73 -1.0 0¦ ¦10 32 265 71 -1.0 0¦
    ¦11 255 0 0 0.0 0¦ +— ID 114 (0x72) —+

    would you have any idea on the “can’t create socket error” ?

    regards

    Carlito

  15. I have a device producing Trimble TSIP format output, but it doesn’t produce any results from the cgps -s command. All the fields are blank and the command times out after a few seconds. The GPS works on a Windows PC in Trimble studio. Do I need to do anything to tell gpsd to look for TSIP messages, or set baud rate of whatever (yes, it’s over USB). My USB lists as:

    pi@raspberrypi ~ $ sudo lsusb
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
    Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
    Bus 001 Device 005: ID 04d8:00df Microchip Technology, Inc.

    and the GPS is plugged into the lower USB socket. I can’t see a reference to /dev/ttyUSB0 in the log, but I do see a reference to ttyACM0:

    I’m very new to this, so please forgive me if these are obvious questions!

    Thanks, David

      1. I find that I need to enter the command:

        sudo gpsd /dev/ttyACM0 -n -F /var/run/gpsd.sock

        once per boot to get gpsd started. How can I automate this – something to do with /etc/init.d I know, but precisely what should I eidt and how? I have virtually no knowledge of Linux but I have managed to get NTP/PPS working thanks to notes on the Web). I also need to know how to get ntpd to auto-start – I seem to have lost that when installing the re-compiled version.

        Thanks.

  16. OK, so I found dpkg-reconfigure, and now gpsd starts at boot, but I still need to run cgps -s before NTP will detect the GPS (type 28 driver).

  17. Most USb GPS dongles do not connect the 1PPS to any of the appropriate lines in the UART-USB chip so they are strictly NEMA devices if left unmodified. In theory one could connect a tiny wire from the appropriate wire on the GPS module to the appropriate line on the UART to USB chip so that the emulation of a serial port device would include the DCD or similar 1PPS signal. But the accuracy of the timing would still be dependent on the latency of the USB connection which would mean not so great. Has anybody been able to utilize a kernel 1PPS on the Raspberry Pi? That would be very nice because the inexpensive RPI is fast enough to be a nice NTP server. You could disconnect the GPS chip from the UART-USB and connect the GPS directly to the RPI through the UART interface for the ASCII and use a GPIO for the 1pps

      1. Nice article. I was going to try a dedicated gps receiver rather than a usb one (actually ordered some prototyping boards for the rpi on ebay yesterday).

        One thing, you have a section about the time being 16 seconds out – a coincidence that GPST is 16 seconds ahead of UTC perhaps?

      2. Thanks for your comments. The only problem with the USB device appears to be initial recognition, and if you have Internet NTP servers for the coarse seconds then the PPS is recognised and used to discipline the NTP server. The u-blox device which is serial rather than USB serial showed some slight oscillations during initial tests which I need to investigate further, but it still well within 10 microseconds.

        Yes, the 16 seconds is because the Trimble device has no battery backup, and starts emitting GPS seconds rather than UTC. Only once enough information has been downloaded from the GPS satellites does it discover what the GPST-UTC offset actually is, and only then does it send out UTC. I believe that gpsd is supposed to detect this by not filling in the shared memory until the value of (GPST-UTC) is greater than 10 seconds. I’ll clarify that section.

  18. Hi, I have the same GPS as you (£25). I am having problems with the first step. I havnt used any of this stuff before and only used windows. I have downloaded gspd software and put it on a usb memory stick and it is connected to the internet. When i first started it did some processing lines then asked if i wanted to use up some space on the SD card it then said problem connecting to websites. so after then connection to the internet it comes up with E: error. any ideas? where do i put the dowloaded files? (taken from here http://download.savannah.gnu.org/releases/gpsd/ and using the latest update)

    Any ideas?

    Ben

  19. First, all of you, thank you for all of your help. I’m having the permissions problem (my NTP is not seeing my NMEA GPS and the gpsd > ntp connection is sometimes working but more often is failing to be seen) and I’m not sure if the suggestion here to change the permissions of the /dev/tty* file is the correct one.

    GPSd drops privileges to the “nobody” group after it starts and the /dev/gps0 symlink created by gpsd is owned (on my raspbian/raspberry pi) by root with a group of root while the ttyUSB0 device is owned by root but its group is the dialout group. I think this issue may be behind some of the issues people are having. I wonder what the gpsd developers and the debian package maintainer would say was the best approach?

  20. I tried what you suggested above and it works fine, however as soon as I disconnect the ethernet cable to the internet ntp dies.

    Ideally I’d like to be able to get time and 1pps from the gps and run the pi standalone…

    any ideas what I need to do to fix this?

    1. Sorry for the late reply, I’ve been on holiday.

      I’ll take a look at the ethernet issue at some point over the weekend although one thing to try is to comment out the remote ntp servers from the config (which I left in in the article) and leave just the gps – that’s what I’m going to try.

      As for the 1pps, from what I’ve since found out most usb sticks don’t have it although for some it’s a case of soldering a wire to the usb serial port so that the 1pps is carried over one of the serial control lines. Again I’ve not had time to work on that one (yet) but might be a solution.

      1. if anyone else is trying to set system time from gps standalone (in python) this worked for me…

        credit goes to n sweeting at raspberrpi.org and you can download it from http://code.google.com/p/gpstime/

        import os
        import sys
        import time
        from gps import *

        print ‘Attempting to access GPS time…’

        try:
        gpsd = gps(mode=WATCH_ENABLE)
        except:
        print ‘No GPS connection present. TIME NOT SET.’
        sys.exit()

        while True:
        gpsd.next()
        if gpsd.utc != None and gpsd.utc != ”:
        gpstime = gpsd.utc[0:4] + gpsd.utc[5:7] + gpsd.utc[8:10] + ‘ ‘ + gpsd.utc[11:19]
        print ‘Setting system time to GPS time…’
        os.system(‘sudo date –set=”%s”‘ % gpstime)
        print ‘System time set.’
        sys.exit()
        time.sleep(1)

    2. Nigel, perhaps you could post your ntp.conf for us to check? You certainly /should/ be able to do what you want, but I can’t test it here as my terminal connection to the Pi is via Ethernet!

      1. David, Peter

        thanks for your replies – you have to comment out the lines in ntp.conf (which I guess make it look at the ethernet port..)

        #server 0.debian.pool.ntp.org iburst
        #server 1.debian.pool.ntp.org iburst
        #server 2.debian.pool.ntp.org iburst
        #server 3.debian.pool.ntp.org iburst

        then I get:

        root@raspberrypi:/home/pi# sudo ntpq -p
        remote refid st t when poll reach delay offset jitter
        ==============================================================================
        SHM(0) .NMEA. 0 l – 64 0 0.000 0.000 0.000
        root@raspberrypi:/home/pi#

        I am not trying to use the 1pps as my gps does not have one…

      2. David – sorry I haven’t deliberately been ignoring you but the start of the year has been busy. regards Nigel

        here it is:

        # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

        driftfile /var/lib/ntp/ntp.drift

        # Enable this if you want statistics to be logged.
        #statsdir /var/log/ntpstats/

        statistics loopstats peerstats clockstats
        filegen loopstats file loopstats type day enable
        filegen peerstats file peerstats type day enable
        filegen clockstats file clockstats type day enable

        # You do need to talk to an NTP server or two (or three).
        #server ntp.your-provider.example

        # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
        # pick a different set every time it starts up. Please consider joining the
        # pool:

        #comment out internet servers so it picks up the gps only…
        #server 0.debian.pool.ntp.org iburst
        #server 1.debian.pool.ntp.org iburst
        #server 2.debian.pool.ntp.org iburst
        #server 3.debian.pool.ntp.org iburst

        # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
        # details. The web page
        # might also be helpful.
        #
        # Note that “restrict” applies to both servers and clients, so a configuration
        # that might be intended to block requests from certain clients could also end
        # up blocking replies from your own upstream servers.

        # By default, exchange time with everybody, but don’t allow configuration.
        restrict -4 default kod notrap nomodify nopeer noquery
        restrict -6 default kod notrap nomodify nopeer noquery

        # Local users may interrogate the ntp server more closely.
        restrict 127.0.0.1
        restrict ::1

        # Clients from this (example!) subnet have unlimited access, but only if
        # cryptographically authenticated.
        #restrict 192.168.123.0 mask 255.255.255.0 notrust

        # If you want to provide time to your local subnet, change the next line.
        # (Again, the address is an example only.)
        #broadcast 192.168.123.255

        # If you want to listen to time broadcasts on your local subnet, de-comment the
        # next lines. Please do this only if you trust everybody on the network!
        #disable auth
        #broadcastclient

        #gps ntp server…
        server 127.127.28.0 minipoll 4
        fudge 127.127.28.0 time1 0.183 refid NMEA

    1. Not off hand, when I ran those commands it worked. Are there any other errors happening? For example take a look at /var/log/syslog or /var/log/messages and see if anything stands out.

      What I’m thinking is that perhaps there’s a problem between the RPi and the GPS – I have heard of issues with either too much power being drainded from the rpi or the reverse, a powered usb hub is used but it leaks some power back to the RPi – I think that shows up in syslog as Error 71 from the USB modules?

      1. Thanks for your answer. In fact, I was using the wrong version of cgps. It’s working perfectly now, thanks to your tutorial!

  21. Thanks for this great article.
    It works just as expected here.
    One question though. Is it possible to retrieve atomic data from the GPS with cgps or one of the other utilities?
    I only need the Latitude, and Longitude, and i need my own software to read these information’s, when they are needed.

  22. Fantastic post – i have this working on my RPi with a Globosat BU-353.

    I had to kill gpsd and restart to get ntp working as you said – but other than that all perfect!

  23. Peter, I’m a complete “noob” as far as Linux and the Pi are concerned, and I am trying all of the USB devices that we have with the Pi! We have a GPS Tracker 1-gotU GT-200e from Maplin UK (A47JU) which we use when out and about. I Just used your instructions, connected the device, and lo and behold I see all the data in cgps and all the satellites in xgps – wonderful; thank you so much! Unfortunately gpsd appears to stop after around 5 mins, nevertheless I shall derive a lot of enjoyment playing with the device now.

    1. How long do you leave it running? It could take a while before the receiver picks up enough GPS satellites for it to get a position so until then it would show N/A.

  24. great job … i am currently working on a car tracking system and needed to know if it is possible to track my car using a GPS module connected to a Raspi ??

  25. Hi very nice tutorial, thanks. But How to i change the baundrate? my GPS receiver uses 38400 and if I’m using the ” cat /dev/ttyUSB0″ i get on weird characters on terminal. Thanks in advance.

  26. Hi, i found a strange problem with raspberrypi and gpsd, i got a fix with a suitable position, but a wrong date in 1993 – 20 years ago.

    {“class”:”TPV”,”tag”:”MID2″,”device”:”/dev/ttyUSB0″,”mode”:3,”time”:”1993-10-25T09:45:37.000Z”,”ept”:0.005,”lat”:53.557053675,”lon”:9.925919621,”alt”:55.225,”epx”:10.803,”epy”:11.938,”epv”:35.729,”track”:17.7708,”speed”:0.494,”climb”:-0.814,”eps”:23.88}

    I used a lot of time to understand this, the same device worked fine in other linuxboxes.

    Rootcause and solution:
    The raspberry has – as everyone knows 🙂 no rtc, so it is possible that it runs on a totaly wrong date/time.
    GPS had a week number rollover in 1993 (its like the year 2000 issue, but for gps receivers).

    So, if the local time on the raspberry is set to the actual year before starting the gpsd (e.g. date -s “20013-06-10” in the gpsd start script) it gets the right date/time from the gps and everything is fine.

    *peuch*

    1. Good spot. I’ve not noticed it as my PI’s seem to start with a recent date whenever I start them so they’ve always been post rollover.

      The rollover is due to the GPS week number being 10 bits (e.g. 1024 weeks) and the last time was 1999 and the next one in 2019.

      1. With Raspbian, there is a file /etc/fake-hwclock.data which has the current data and time, updated every so often. I understand that file is used early in the boot process to initialise the system time. There are a few folk reporting GPS issues, with receivers with various firmware, when the date gets within 500, 512 or 768 weeks of a roll-over event. Having a Internet pool servers should help resolve any ambiguity.

      2. Yes, as long as that file’s contents is within range of a roll-over event then it should be fine.

        Under normal use using an ntp server would then bring it into sync but that’s not possible if there’s no network connection – which was one of the reasons of using GPS instead.

  27. I’m using the same GPS receiver as this for a project. I only need/want the GPGGA and GPRMC sentences fromt the receiver but I’m having trouble configuring it. Do you know if it’s possible to configure this particular receiver using the PMTK commands? Or is there any other way for me to only get the GPGGA and GPRMC sentences?

  28. Newbie question :
    I have connected a Navibe GM720 gps dongle, and followed this tutorial step by step, but it doesn’t woek with cgps; However, my dongle is detected
    >lsusb

    Bus 001 Device 010: ID 067b: 2303 Prolific Technology, Inc. PL2303 Serial Port.
    I guess i have to configure the virtual serial port in order it works with cgps, but I don’t know how to do it.
    thank you for toutr help,

  29. hi all,

    I am designing a GPS tracker which will be used to get a distance between two point. I am using Arch linux arm for raspberry pi model b. I am planning to get the data in a file every second and use lat and long parameter to calculate distance with hoversine formula.
    my main problem is how to get the data in file instead of gui

    Thanks in advance

  30. Thanks for this, just got myself a Pi B+ and a NS-100S for this very thing but I am having some problems.

    It appears that the ntpd demon is not getting time from the GPS dongle. when I enter a ‘ntpq -p’ I get

    root@raspberrypi:/var/log/ntpstats# ntpq -p
    remote refid st t when poll reach delay offset jitter
    ==============================================================================
    SHM(0) .NMEA. 0 l – 16 0 0.000 0.000 0.000
    SHM(1) .PPS. 0 l – 16 0 0.000 0.000 0.000

    From a ‘ntpq > as’ command I get:
    root@raspberrypi:/var/log/ntpstats# ntpq
    ntpq> as

    ind assid status conf reach auth condition last_event cnt
    ===========================================================
    1 16239 802b yes no none reject clock_alarm 2
    2 16240 802b yes no none reject clock_alarm 2

    My ntpd.conf is:

    # Configuration for USB GPS NTP
    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

    Output from cgps -s shows that I have 10 gps locks, a 3D FIX (9 secs) etc.

    I just have no idea, I’m bashingmy head in to figure this out.

  31. i’m also playing with some GPS receivers on my RPi connected directly to the GPIO pins (using 3.3V, ground and RX).
    the first chip is a Ublox AMY6M chip and i get a fast connection with 4-5 satelites (57600bps UBX binary).
    the second chip is a “telit J-N3 flash” running at 9600bps and sending a SiRF binary. i also got the cgps running, i get 10 good satelites, but at the end in the “USED” line, they al say “N”.
    i don’t get a fix, not a clock, really notthing at al in the other fields. also tryed in XGPS but same problem. 10 good visible satellites, not one is used and i don’t get a fix.

    anybody any ideas?

  32. Peter – I am having trouble using the shared memory feature of GPSD to supply coarse time to the Pi. I am successfully using PPS for precise seconds. My goal is to make a standalone NTP server for LAN use only (no internet access to external servers or server pool).

    GPSD appears to be running fine, as is PPS. I see the appropriate GPSD output using cgsp -s and gpsmon. I have the North American server pool setup in ntp.conf.

    When I install the GPSD SHM driver (.28.0) with prefer option in ntp.conf, restart ntp service and then run ntpq -p, I see the offset and other data but nothing in column 1 (although I am not sure if anything should be there). The PPS shows correct data with “o” in column 1.

    Now, if I comment out the other servers (server 0.north-america.pool.ntp.org and so on).and restart ntp service, then neither PPS nor GPSD show any data in the query, only zeroes. In other words, without those external servers, NTP is not working as standalone.

    I have searched and searched but cannot find any troubleshooting info that helps me locate the problem and hope someone here can help me resolve it. Thanks

  33. Thank you for this instructive tutorial. I am new to Linux and to RPi and have been beating my head against both as I climb the fairly steep learning curve %^)

    With this article, I was finally able to get gpsd, gpsmon, and cgps all running on the RPi (192.168.1.41) hosting the USB-connected uBlox 6 GPS engine. I can open any number of terminal windows now and run multiple copies of gpsmon, allowing me to validate that gpsd supports multiple clients. That is great.

    What I have not been able to do is get gpsmon running on a second RPi (192.168.1.236) to connect successfully to the gpsd on the first unit and display the gps data. I get the following error message when trying:

    pi@piaware ~ $ gpsmon 192.168.1.236
    gpsmon: connection failure on 192.168.1.236:2947, error -6 = can’t connect to host/port pair.

    Any ideas what I’m doing wrong?

    Cheers – Jon

  34. Thanks for the tutorial. Following your instructions I managed to get the USB GPS receiver to work with the PI 2 and I can get a fix using xgps. I was wondering if you could point me to a tutorial that would help me make a python program that would make use of the information being received from the receiver. My ultimate goal is to make it transmit the co-ordinates via http requests, but for now it would be enough to just get the program to display the latitude and longitude on screen. Thanks!

  35. Hi– thank you for the tutorial. I am having trouble launching the display for xgps. Whenever I try i get

    /usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:57: GtkWarning: could not open display
    warnings.warn(str(e), _gtk.Warning)
    /usr/bin/xgps:444: Warning: invalid (NULL) pointer instance
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    /usr/bin/xgps:444: Warning: g_signal_connect_data: assertion ‘G_TYPE_CHECK_INSTANCE (instance)’ failed
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    /usr/bin/xgps:445: GtkWarning: IA__gdk_screen_get_display: assertion ‘GDK_IS_SCREEN (screen)’ failed
    if not self.window.get_display():
    Traceback (most recent call last):
    File “/usr/bin/xgps”, line 860, in
    base = Base(deg_type=degreefmt)
    File “/usr/bin/xgps”, line 446, in __init__
    raise Exception(“Can’t open display”)
    Exception: Can’t open display

    Anyone possibly know what the problem might be? i have no problem launching cgps.

    Thanks!

    1. How are you connecting to your pi? Is it from the command line? It sounds like you’re connecting to either a remote PI using ssh or you are running it on the pi as root but connected to the desktop as the pi user.

      If it’s ssh from another pi/linux box, try adding -Y to the ssh command line, i.e.: ssh -Y user@host – then it will create a tunnel for xwindows to work.

      If it’s from the command line try using gksudo instead, then it’ll run xgps as root but still give it access to the local xwindows session.

      Peter

      1. I am connected remotely, and I did add -Y (i also used pgrep -fl ssh to double check it worked) but still no success. Any other suggestions?

        Thanks again!

  36. Thank you for the very good article. I found that on a RaspberryPi model B, with a Globalsat BU-353S4 I had to manually specify the USB device before gpsd would start correctly using dpkg-reconfigure gpsd. Also, as noted in previous comments, PPS does not work at all on GU-353S4. Once I manually specified /dev/ttyUSB0 in dpkg-reconfigure all worked perfectly.

  37. Dear Peter Mount,
    Using your blog entries, I tried to synchronize my Raspberry Pi’s time clock to GPS based time in a location where no internet connection was available (foxtrot map tracking software on battery). After adding the requisite lines of code to
    /etc/ntp.conf
    my Pi did not time synch despite an active gpsd including satellite ‘fixes’.
    The following day I turned on a portable router before booting the Pi. The Pi auto connects to this router. After booting, the Pi, the desktop time was found to be in synch with GPS time (adjusted to EST) after several hours of being powered down. Booting the Pi with the router turned off did not time synch with GPS based time until a router (2 were tried) assigned a DHCP provided ip# to the Pi. Once networked by DHCP, the time synchronized quickly with GPS.
    The presence of a networked router (portable or AC powered – but internet isolated) with the Pi is essential for the time synchronization with GPS when satellites are detected by gpsd.

    Regards,
    Bob Eisenman
    Salem, Massachusetts
    *****from blog*****
    Next you need to edit the file: /etc/ntp.conf and add a few lines to it defining the GPS.
    # gps ntp
    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
    Now restart ntp:

      1. Hi Mr. Reeve,

        My current working GPS time setup and requirements are fairly simple. I use a BU-353 USB plugged into a Pi B+ running Raspbian Jessie. My gpsd configuration mimics yours (reeve pdf description) but Jessie requires that the file be edited manually.
        Instead of trying to edit the ntp.conf file as indicated in either your PDF or the Peter Mount blog , I run a Python script which acquires and sets sysyem time to UTC time from gpsd data. In Jessie the old ‘raspi-config’ file is replaced with a desktop gui from which the user time zone is entered. Assuming the user has already set the timezone , running the command
        python gpstime.py
        from SSH acquires UTC time. After a short delay the desktop time display changes to the correct GPS time for the local timezone, initially synched to UTC.
        ******
        I use the Python program ‘gpstime.py’

        https://code.google.com/p/gpstime/

        Including the -u option to set UTC time first :

        os.system(‘sudo date -u –set=”%s”‘ % gpstime)

        After a short pause the desktop’s local timezone gpstime correctly displays
        EST (assuming EST is set as the local time in Raspberry Config)

        gpstime.py is available by download from:
        https://code.google.com/p/gpstime/

        ****
        Regards,
        Bob Eisenman

  38. Hi, great post, iam now feeling curious about how to get these values by using a python program, like continuously reading them and print them in python

  39. great post,now i feel curious of how to read these information desperately using python for printing or whatever?

  40. One thing worth noting – probably blindingly obvious but rarely written down is that if you are using a USB GPS you can always use a USB to USB extension cable to get the ‘GPS Dongle’ somewhere where it has a clear view of the sky.
    With a HAT or similar you will need a GPS patch antenna/ aerial and possibly an adaptor socket depending on the connections.

  41. For those of us using GPS for precision timing, what USB GPS can you recommend where the PPS (pulse per second – typically on the DCD line) signal is correctly carried over USB? The polled nature of USB likely rules it out for any precision timing application in any case. For me, the 5m cable on the GPS puck works better than a 5m USB extension.

  42. Pingback: GPS | PiStuffing
  43. I’m working on a Raspberry Pi 3 and installed the adafruit gps module.
    Everythink is working fine, except that I must start the gps service from the commandline.
    Is it possible to write a script that it starts when the Raspberry Pi is starting up?
    The following line of code:
    sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
    I have placed it in the rc.local file at the end, but that doesn’t start the service.
    Thank you for your reply.
    Yvonne

  44. for ublox 7 type:
    Make sure Linux enumerated it:
    $ dmesg | grep u-blox
    [506639.825916] usb 3-1: Product: u-blox 7 – GPS/GNSS Receiver
    [506639.825921] usb 3-1: Manufacturer: u-blox AG – http://www.u-blox.com
    See what serial port it’s on:
    $ dmesg | grep “USB ACM”
    [506640.648297] cdc_acm 3-1:1.0: ttyACM0: USB ACM device
    Edit /etc/default/gpsd to change the device port; like this:
    DEVICES=”/dev/ttyACM0″
    Restart gpsd:
    $ service gpsd restart
    You should be able to see data using cgps:
    $ cgps -s
    If not, you may not have a lock yet (green LED blinks in lock). See if you at least have GPS data:
    $ cat /dev/ttyACM0
    You should see NMEA sentences like $GPRMC

  45. Hello! Great walk through. I was curious to know if there is a way to log the gps location to a file during the open run time. Any advice or suggestions is greatly appreciated as I am extremely new to coding and working with a Raspberry Pi.

  46. Help me i,m getting Bellow Err……..

    pi@raspberrypi:~ $ cgps -s
    cgps: GPS timeout
    pi@raspberrypi:~ $ cgps -s
    lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
    x Time: xxPRN: Elev: Azim: SNR: Used: x
    x Latitude: xx x
    x Longitude: xx x
    x Altitude: xx x
    x Speed: xx x
    x Heading: xx x
    x Climb: xx x
    x Status: xx x
    x Longitude Err: xx x
    x Latitude Err: xx x
    x Altitude Err: xx x
    x Course Err: xx x
    x Speed Err: xx x
    x Time offset: xx x
    x Grid Square: xx x
    mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

  47. It worked with a GlobalSat BU-353 S4 receiver for me, will the time difference according to cgps always be something on the order of 1.5 seconds despite a good view of the sky?

    1. Not 100% but it depends on how old or new your receiver is.

      A “new” receiver might be about slightly out of sync until it receives the UTC offset message for the first time – so some can be 1s out at first if they don’t know of the leap second added 4 years ago. Once it’s had that message then it should be closer to real time – in reality GPS time is 18s ahead of UTC as GPS doesn’t use leap seconds.

      That would account for 1s but not certain of the other .5s. Only thing I can say is keep it running for a few hours and see how it goes.

      A similar things happens with the satellite orbits. As they change or new satellites are deployed the receivers need to know about them so every so often they get updates with any relevant changes.

      I’ve been playing with an ESP32 based GPS unit this week (whilst testing LoRa) & that’s what I’ve been doing, keeping the receiver in a window so it sees as many satellites it can & get the latest details.

  48. Hello I have a situation with my ham radio Icom9700 With getting a GPS receiver that will send data to my data port via a 2.5 mm plug. Is this possible? The data being sent will get it from the sat’s and it will be my call letters, lon, lat and my grid location also the distance from my station to the one I am talking with. via D Star (digital voice.

Leave a reply to Emily Cancel reply