Introduction
This page is a tutorial I wrote to document the Lightweight Simple GPS Logger I use with my FPV racing mini-quad drone. The modules run at 3.3V and run independently of other systems on the drone (electrically isolated). This allows it to be installed and removed quickly and easily.
Physically, the finished design is 35mm x 24mm x 15mm without the battery and weighs 10.1 grams. The battery weighs an additional 18.4 grams as shown below.
Measurements with my DMM indicate that the entire system draws between 40-45 mA from the battery. This suggests that with the 300mAh battery at full capacity, it could conservatively run for upward of 6 hours. This is far more than the time I can fly my mini-quad with all of its flight batteries!
Ingredients (Parts)
Data Logging
U-blox NEO-6M Module
The u-blox NEO-6M is a 50 channel GPS receiver with the following specifications:
- 27s cold start time to first fix time
- 5 Hz update frequency
- 0.1 m/s velocity accuracy up to 500 m/s
- 0.5 deg heading accuracy
- 2.5 m horizontal accuracy
- 50 km service ceiling
I used a GY-NEO6MV2 module like these ones on eBay
This module allows a VCC of up to 5V, but the serial levels are not officially rated as 5V tolerant so serial transmitted to it should be at 3.3V.
SparkFun OpenLog
The OpenLog is a serial logging device. Basically, any serial data you send it will be stored on its microSD card. At its core, it is a standard Arduino which can be reprogrammed via an FTDI module, meaning that the logging can be conditional if desired. Its specifications are as follows:
- 3.3V - 12V VCC (recommended 3.3V - 5V)
- logs to microSD FAT16/32 cards up to 64GB
- Serial command interface
- configurable baud rates (up to 115200bps)
- preprogrammed ATmega328 and bootloader
- two LEDs indicate writing status
- 2mA idle, 6mA at maximum recording rate
I bought a clone of this on eBay and was left very disappointed as it didn’t work at all. I subsequently bought and am using an authentic module (DEV-137) available at SparkFun here
MicroSD Card
Any microSD card will work. Choose a large enough size (max 64GB) to store the data for the time period required and format it with FAT16/32.
Power
There are many options to power these modules. I used an adjustable voltage module with a LiPo battery as follows.
3.3V Regulator
This regulator is a buck converter with adjustable voltage output like these ones on eBay Once set via the potentiometer, this produces a constant 3.3V output from an input voltage between roughly 5V and 20V.
Battery
I used a small 2 cell (2S) LiPo battery I had on hand. It is available from HobbyKing here.
A 2 cell LiPo outputs voltages from around 8.4V (4.2V per cell) and down as
low as 6V when completely empty.
I would advise not to run the battery lower
than 6.6V (3.3V per cell) to avoid damaging the battery.
Software Configuration
U-blox GPS
The u-blox module was connected to a PC via an FTDI breakout similar to this on from SparkFun In the u-blox software, u-center the following were configured (hint: open the correct panel with F9):
- “Port 1” serial baud rate was set to 38400
- update frequency was set to 2 Hz
- all NMEA messages were disabled OTHER THAN:
- $GPRMC
- $GPGGA
- $GPGSV
- $GPGLL
- $GPVTG
I recommend this page for information on NMEA message structures.
OpenLog
The OpenLog is configured by powering the module with 3.3V and ground pins with the FAT formatted microSD card inserted.
Next, the microSD can be viewed on a computer and the config.txt file will have been created.
All that was modified was the baud rate, giving a config.txt file as follows:
38400,26,3,0,1,1,0
baud,escape,esc#,mode,verb,echo,ignoreRX
Assembly
The modules were wired as shown in the following image:
Here’s some photos showing how I soldered and mounted the modules using double sided tape:
Use
Step 1: Apply power... Thats it!
Once the power is applied, all messages from the GPS are saved onto the microSD card. The LEDs on the OpenLog indicate “serial-data received” and “writing to microSD”. Once the GPS has a fix, it’s LED will flash. whilst it gains its first fix, it’s LED will be solid and it will still send serial messages but they will be sparsely populated.
Simply remove the power when finished!
Post Processing
NMEA Data
An excerpt of the data seen in the 4S section of the flight in the below video is available here.
Data Processing
In order to make the NMEA data useful, I wrote a small script which turns the TXT file into a CSV.
An example of the output (with some columns removed for brevity) can be found here.
The script uses a library called micropyGPS which I grabbed from bsdz’s branch.
# pip install git+https://github.com/bsdz/micropyGPS.git
import sys
import time
from micropyGPS import MicropyGPS
inputFile = sys.argv[1] # eg: LOG00001.TXT
outputCSV = inputFile.split(".")[0]+'.csv' # eg: LOG00001.csv
print("Input: " + inputFile)
print("Output: " + outputCSV)
fix_type_decode = ["","NO FIX","2D FIX","3D FIX"]
my_gps = MicropyGPS()
lastTime = 0
print("Processing...")
with open(outputCSV, 'w') as out_file:
# -- writing CSV header row --
out_file.write('DATE,TIME,SECS,LAT,LONG,"ALT\n(metres)",')
out_file.write('"COURSE\n(deg, True)","GND SPEED\n(km/hr)",')
# remove following line if using standard library...
out_file.write('"LOCAL MAG VARIATION (deg, True)",')
out_file.write('NUMBER SATS,FIX TYPE,HOR DOP,VERT DOP,POS DOP\n')
# -- process the log file line by line --
with open(inputFile) as fp:
for line in fp:
for x in line:
# -- update the GPS object with the NMEA data --
my_gps.update(x)
# -- writing to CSV if required --
isNew = (lastTime != my_gps.timestamp)
haveFix = (fix_type_decode[my_gps.fix_type] != "NO FIX")
if isNew and haveFix:
# -- saving a line to CSV. --
out_file.write(my_gps.date_string('s_dmy') + ",")
out_file.write(str(my_gps.timestamp[0]) + ":")
out_file.write(str(my_gps.timestamp[1]) + ",")
out_file.write(str(my_gps.timestamp[2]) + ",")
out_file.write(my_gps.latitude_string() + ",")
out_file.write(my_gps.longitude_string() + ",")
out_file.write(str(my_gps.altitude) + ",")
out_file.write(str(my_gps.course) + ",")
out_file.write(str(my_gps.speed[2]) + ",")
# remove following line if using standard library...
out_file.write(str(my_gps.mag_variation) + ",")
out_file.write(str(my_gps.satellites_in_use) + ",")
out_file.write(fix_type_decode[my_gps.fix_type] + ",")
out_file.write(str(my_gps.hdop) + ",")
out_file.write(str(my_gps.vdop) + ",")
out_file.write(str(my_gps.pdop) + "\n")
lastTime = my_gps.timestamp
print("Done!")
I made a minor modification the micropyGPS library, to enable the local magnetic variation to be saved form the $GPRMC NMEA message. I’ve added the modified library file to the project repository. If you don’t require this information, remove the lines indicated from the file above.
Example: FPV Racing Mini-Quad
I enjoy flying my mini-quad and I have wondered what speeds it achieves. This is how I use this module to answer this question.
Mounting
I designed a simple 3D printed mount which suits my mini-quad as follows. It isn’t immensely strong, but my intention is to only fit the GPS for straight line speed tests so it shouldn’t need to withstand huge crashes (famous last words?).
These are some photos of it fitted to my mini-quad:
Result
From one test flying session, I’ve found that with the type of flying I do and the setup I use, the normal maximum speeds the mini-quad does is around 110 km/hr.
As expected the data indicates that in my case, my maximum speed and average speed are impacted by the cell-count of the flight battery; increasing with more cells. The data was quite usable, buit I did find an obvious spike (around 29 seconds in the video below).
Below is a video of the test flights with logged speed overlaid.
More information
I have found that with this CSV, the recorded track can be overlayed on
a Google Map via the GPS Visualizerwebsite.
The code could easily be modified to produce a GPX data file or KML for use with Google Earth.