Author(s): Paul Brown

Even though your computer does not come with its own GPS, you can hack one onto it using a mobile phone. Although, it does take quite a bit of fiddling.

There is plenty of literature online on how to connect a GPS device to a computer. But normally the devices covered are exclusively GPSs, that is, something you would probably have to go out of your way to buy.

What you don't find so much information about is how to use what you have at hand, namely, your regular phone. However; it can be done. It is a bit hacky, but it works.

On Your Laptop

Linux comes with a daemon called gpsd [1] that can process the information delivered by a GPS device. Although gpsd is usually started and stopped with systemd (and is usually launched at boot), you'll be running it by hand. The reason is again the hackiness of the solution, due to processing data coming from a GPS device not on board or that is not connected over a serial or USB port, which is what gpsd usually expects. (See the "NMEA" box.)

NMEA GPS devices deliver information in the shape of National Marine Electronics Association (NMEA) packages. These packages that conform to the NMEA's 0183 or 2000 standards contain all the data you need to position a GPS device on the Earth's surface. NMEA packages contain "sentences" that look like this: GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A An NMEA sentence can contain data on the device's altitude, latitude, longitude, and speed. It also indicates the time of the reading at the beginning of the sentence and a checksum at the end. This helps identify broken or partially received sentences. Most programs and programming libraries used for positioning parse NMEA packages and sentences automatically. This means you usually won't need to write any code to turn the raw NMEA data into something usable.

gpsd is available in most, if not all, distributions. On Debian and its derivatives, it is installed with:

apt-get install gpsd

If you are on Ubuntu, Raspbian, or something similar, you may have to add sudo to the preceding instruction.

Be that as it may, this command will install (and run) the GPS daemon and install several utilities such as gpsmon and gpspipe .

The first thing you want to do is stop the systemd gpsd services. As explained previously, you want to run gpsd with your own parameters. You can later work your special configuration into the systemd version, but for now, run these two instructions to free up the gpsd service and the port on which it listens.

systemctl stop gpsd systemctl stop gpsd.socket

If this doesn't do the trick, check what systemd is running with:

systemctl | grep gpsd

and stop whichever service shows up there.

You may have to remove the /var/run/gpsd.sock file as well (you will have to do that with sudo ) if you are going to run gpsd as a regular user.

On Your Phone

On your phone, you need an app that shares your GPS data over a network. There are some quite fancy proprietary programs out there, but, unless you go for the "premium" version, they are usually addled with ads and bloat.

Fortunately, there is a very simple option created by Tiago Koji Castro Shibata that you can get from the Google Play app store [2] or download and compile yourself from the author's GitHub page [3]. When you run it, it looks like Figure 1.

Figure 1: A simple GPS client that allows you to share data with your computer.

Configuring the app is simplicity itself: Input your laptop's IP. Choose a port to which to forward the information. Press the Start button. The end.

Connecting Both

Back on your laptop, check that your IP corresponds to what you input on the mobile app and run the gpsd daemon from a terminal window:

gpsd -N upd://*:<port>

What you are doing here is polling information from a phone, any phone, on the port you established on the app. To all practical effects, your phone is acting like a server.

For example, if you are connecting to an app configured as shown in Figure 1, you would run:

gpsd -N upd://*:29998

The -N parameter lets you run gpsd without it going into the background. Once you are happy that everything works as it should, you can run gpsd without it.

As for why "any" phone and not your own specific phone, that's because, in theory you could select a specific source on the network by passing your phone's IP to gpsd , like so:

gpsd -N udp://<phone's IP>:<port>

However this did not work for me. The only way gpsd managed to pick up the server on our phone was by using the catch-all * . This shouldn't be a big problem: Pick an atypical and unique port, and it is unlikely that gpsd will poll anything that isn't the device you want it to poll.

Now move around with your phone, preferably near a window, to try and capture some coordinates. Then open another terminal window and run gpsmon .

The gpsmon utility does what it says on the box: It monitors GPS input. Without any parameters, it monitors what gpsd is receiving, but it can also monitor a stream of GPS data from other sources, including the Internet. Its text-based interface shows information on the satellites in view (the GSV section in Figure 2), data which provides 3D location and accuracy (the GGA section), and so on.

Figure 2: The gpsmon utility shows you GPS in action.

A healthy GPS connection will look like Figure 2. If you see something different, wait a while to see if the stream starts, or move your phone to a location where it can "see" satellites, near or outside a window. If that doesn't work, restart gpsd , gpsmon , the app on your phone, or all three. GPS is a fickle beast and breaks a lot. If you have followed the instructions above, at some point you will get a signal, and the stream of data will begin.

This is all very well if you are at home and running stuff over the local network, but you would usually want to use your GPS-enabled system when you are out and about. What then? Use your phone as a WiFi hotspot (Figure 3)! Just because your phone is the hotspot, it doesn't mean it cannot stream GPS data to your laptop.

Figure 3: Activate the Mobile Wi-Fi hotspot feature on your phone and take your GPS rig on the road.

Activate Mobile Wi-Fi hotspot from Settings | Wireless & networks | More | Tethering & mobile hotspot on your phone, connect to your phone's network from your laptop, and your computer will be assigned an IP that is something like 192.168.43.X (for the record, phones usually adopt 192.168.43.1 as their IP when acting as a hotspot). Use that with your Android GPS client, and you will be able to take your GPS experiment out and about.

A final gpsd tool to be aware of is gpspipe . At its simplest, gpspipe takes a parameter that tells it which format to use and just dumps the stream from gpsd to the standard output:

gpspipe -r

will stream raw NMEA sentences to the terminal, while

gpspipe -w

sends native gpsd sentences (see Listing 1).

Listing 1 gpspipe -w output {"class":"TPV","device":"udp://*:29998","mode":3,"time":"2018-03-11T09:21:21.000Z","ept":0.005,"lat":36.736763683,"lon":-4.381267583,"alt":149.000,"epv":20.700,"track":0.0000,"speed":0.000} {"class":"SKY","device":"udp://*:29998","vdop":0.90,"hdop":1.50,"pdop":1.70,"satellites":[{"PRN":7,"el":26,"az":45,"ss":45,"used":false},{"PRN":13,"el":45,"az":298,"ss":24,"used":false},{"PRN":28,"el":35,"az":113,"ss":18,"used":false},{"PRN":30,"el":51,"az":46,"ss":38,"used":false}, ... ]}

gpspipe can also output to a file using the -o parameter, be sent to the background as a daemon ( -d ), or send data to a serial device ( -s ).

You could use gpspipe to send all the information to a file and keep track of a trip or a run. In the case of a run, you could also see the terrain's profile and figure out how much you climbed, since the NMEA sentences also include the altitude at any given point in your route.

I could end the article right here. You have connected your phone; you can use its GPS on your laptop or on a single board computer such as the Raspberry Pi; and you have learned how to store the data. With that alone, you can carry out a bunch of cool projects. None of which, useful as they may be, will be very visually appealing.

So let's make a graphical map-tracking application instead.