While there are programs like
gpsd in the OpenWrt repository for interfacing with GPS receivers, sometimes you may be limited to a program that can only parse raw NMEA 0183 data over a serial port. This article will show you how to share your GPS receiver's raw NMEA sentences with one of these outdated programs, such as Microsoft MapPoint.
For single users, the use of the
ser2net-package already contained in the OpenWrt repository may prove more useful for this application. We are specifically talking about sharing the data in read-only mode with multiple clients.
You'll need an OpenWrt device with a compatible serial, UART, or USB port that allows for communication with your GPS receiver. It's helpful to have a use for raw NMEA data as well, otherwise you wouldn't be reading this.
netcat(Busybox's nc will not listen on ports)
coreutils-stty(Setting speed on serial ports)
For your client machine, you'll need a virtual serial port software. Perle has no cost software to do this on virtually every operating system and can be found here: TruePort.
GPS receivers have a whole handful of sentences they provide, however all of the location data is contained within the GPGGA string. You need to know and/or configure the frequency of this string (once a second, twice a second…) and if possible disable the other sentences. Garmin provides software to do this with their units available at their website.
You can also test the frequency of your unit by running this, assuming your unit is at /dev/ttyS0:
stty -F /dev/ttyS0 4800 sane cat /dev/ttyS0
Run this for a period of time (10 seconds?) and count the number of GPGGA strings, divide by the seconds and you'll have your frequency.
This requires at least three shell scripts; one to read raw data, one to clean the data, and one additional script for every client that you want to connect.
The first script reads the raw GPS data to a file in /tmp:
#!/bin/sh stty -F /dev/ttyS0 4800 sane cat /dev/ttyS0 > /tmp/gpsdata-raw.txt
This file cannot be fed directly into netcat because our software wants CRLF and this only provides LF. Therefore, we have to clean this data into something that other machines will like. Assuming our GPS is only providing GPGGA sentences at a frequency of once per second, the following code will work:
#!/bin/sh ## make sure raw data is being collected while [ ! -e /tmp/gpsdata-raw.txt ] do sleep 1 done while true do tail -n5 /tmp/gpsdata-raw.txt | grep -v "^$" | tail -n1 | tr '\n' '\r' >> /tmp/gpsdata-clean.txt echo -n -e '\n' >> /tmp/gpsdata-clean.txt sleep 1 done
If your GPS is outputting more than GPGGA, increase the count on the first tail so that it includes the last GPGGA sentence and add a grep GPGGA in there. If you're getting GPGGA twice a second instead of once, increase the second tail count to 2 so that it doesn't miss any. If you're getting it every other second, increase your sleep count. There's no need to repeat sentences and we don't want to miss any.
Finally, we need to make this data available to outside users. This is done with a netcat loop. Pick arbitrary TCP port numbers to serve the data on; I am using 2001, 2002…
#!/bin/sh ## wait for data to become available while [ ! -e /tmp/gpsdata-clean.txt ] do sleep 1 done while true do /usr/bin/tail -f /tmp/gpsdata-clean.txt | netcat -l -p 2001 done
The loop is necessary because netcat exits when the socket is closed. Also, this version of netcat does not have the ability to continue listening after a connection is made, which is why I recommend creating an instance of the above script for every client you intend on connecting, on different port numbers. I did not take precautions about what address netcat binds to, and if you're concerned about someone randomly connecting in and seeing where you are located, then please edit this page to reflect proper address binding.
Finally, after making your scripts executable, make them start on boot:
/etc/rc.local (add these lines before 'exit 0')
/root/gpspullraw.sh & /root/gpscleanraw.sh & /root/gps2001.sh &
This procedure was created on Windows 7 x64, though I'm relatively confident it is identical across platforms.
You should now have a serial port spitting out GPS data from your OpenWrt box! Let your mapping program know.
/tmpand may crash when you run out of ramdisk. I designed this for an implementation that wouldn't stay on for more than a couple of days at a time. In case you need to truncate and restart your scripts after some time, use