I found that the phone apps that I used to track my walking did not always reliably record my position, track, or time. I decided to build a gps tracker running on a Raspberry Pi to, hopfully, do a better job. My tracker prototypes write nmea data to a file for processing later. There is no live position display, yet.
The first prototype was a Pi 2 with a USB GPS dongle and gpsd. It worked.
The next, and current, prototype is a Pi Zero W, an Adafruit Ultimate GPS HAT for Raspberry Pi, a reboot or shutdown switch, a tri-colour LED, is that and my own scripts (no gpsd).
GPS units typically output strings of nmea formatted text. I use some venerable command line text processing tools, and a little python, to process this text, write it to a file, and light an LED to display the fix status.
The scripts do what I intend, but these may not be good examples of how to program, or how to choose filenames! I wanted to script using existing command line text processing tools. I write this some months after writing the scripts. These scripts and how these interact may reveal some of the development steps I took: these might need refining.
The scripts communicate via files and file contents.
I use GPXSee to visualize the nmea data files.
Files:
gpsstatus.log
Each line: date and time, a comma, a status integer that can be 0,1, or 2.
gpsstatus.fix
A single integer that can be 0,1,2.
gpsdate.log
The gps date.
gpslogfile.log
Filename of the current file of gps data.
gps-[datetime].nmea
A file of gps data in nmea format.
crontab entries
@reboot ~/gpslogger/initializeserial.sh
@reboot ~/gpslogger/loggermonitor.sh
@reboot ~/gpslogger/gpsstartlogging.sh
@reboot ~/fixtest.py
At each boot crontab runs each script. Some loop forever, or continue forever.
Scripts
initializeserial.sh
1 2 3 |
|
Runs once to initilize the ADAFRUIT ULTIMATE GPS HAT as Adafruit recommend.
loggermonitor.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
- Nothing happend so far so:
- Write a date and time, and a status of 0 to gpsstatus.log.
- Write 0 to gpsstatus.fix.
- Read the last line of yet another file, gpslogfile.log and use awk to put 2 fields from the line in the variable LASTTAIL.
- We wait for 10 seconds.
- Start the loop until the end of time!
- Read the last line of gpslogfile.log again and use awk to put 2 fields from the line in the variable THISTAIL.
- Compare THISTAIL with LASTTAIL. If these are different it means that we are logging gps data, good!
- Make LASTTAIL the same as THISTAIL.
- Append contents of THISTAIL to gpsstatus.log
- Overwrite gpsstatus.fix with the current fix status.
- If THISTAIL and LASTTAIL are identical then we:
- Write a date and time, and a status of 0 to gpsstatus.log.
- Write 0 to gpsstatus.fix.
- Keep looping forever.
gpsstartlogging.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
- Waits for an RMC nmea string and extracts the date.
- Write the date to gpsdate.log, but I cannot remember why!
- Waits for a GGA nmea stirng and extracts the time.
- Builds the gpslog file filename using the RMC date and GGA time.
- Write the filename to gpslogfile.log.
- Appends (writes) received GGA nmea strings to the .nmea file. This last process continues until shutdown, reboot, or the end of time, whichever is sooner. The process continues because
/dev/serial0
is a stream of data andcat
will keep processing the stream until it receives an EOF (end of file).
fixtest.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
The clue is in the name of this script; just a test script.
- The function
getfixstatus():
reads and returns the status of the fix from gpsstatus.fix.- If that fails then we return a fix status of 0: no fix.
- Loops until forever:
- Blinks an LED of colour Green (fix), Blue (dgps fix), or Red (no fix)
- Sleeps for 5 seconds to save power.
I used some of the commented out instructions to debug the script. I use a tri-colour LED to display fix status, but this script would also work for 3 individual LEDs.
gpsstoplogging.sh
1 2 3 4 |
|
Not the most elegant of solutions, but it stops my running scripts.