This is an old revision of the document!
Table of Contents
Common Coding Errors
Ensuring your payload is fully tested for the following errors will maximise your chances of a recovery. There are a number of common and avoidable errors in code that can result in inaccurate information being uploaded to the tracker. The image below is an example of a payload which had both padding and a meridian error. The main cause of these issues is the conversion from a floating point value to a string for transmission. Below we will go through the issues and explain how to avoid them.
Coordinates and Floating Points
With limited memory on a typical microcontroller, the printf() series of functions in AVR Libc (used by Arduino) do not by default support printing of floating point values using the %f operator. Although versions with float support can be used they require a significant amount of memory, sometimes more than the program itself. Because of this it is common to divide up a floating point value into two integers and print it with two %i operators. A typical example might be:
char s[30]; float lat = 54.4566; int i1 = lat; // == 54 int i2 = (lat - i1) * 10000; // == 4566 snprintf(s, 30, "%i.%i", i1, i2); // == "54.4566"
This code will work most of the time, but it contains two important errors.
Padding Issues
The padding error will appear when the floating point value is below 0.1, so a float of 54.0055 will get split into 54 and 55, and the resulting string will contain “54.55” instead of 54.0055. To correctly print this the second integer must be zero padded to the correct number of decimal places:
snprintf(s, 30, "%i.%04i", i1, i2);
In our example we are using four decimal places, so %04i will ensure that the second integer (55) is printed as “0055” giving a final correct result of “54.0055”.
Overflow Issues
Overflow issues in conversion of float to string i.e 51.82181 overflows to 51.16645
Note on Arduino int can only hold a number up to 32768 so when converting the decimal part of the above into an integer value you should be using the long data type.
Example code :
long LATITUDE_DECIMAL = LATITUDE_MINUTES * 1000000L / 60 + LATITUDE_SECONDS * 1000000L / 3600;
Then in sprintf use %06li to avoid the padding issues discussed above.
Prime Meridian
In the UK and especially with our launch sites located around Cambridge the Prime Meridian comes into play. This is the 0' line of Longitude where the values of longitude go from east to west, or in decimal form from positive to negative.
This is fairly easy to code for but it should be checked. The tracker does accept a + in front of location information.
Equatorial
Theoretical Equatorial not really an issue but work mentioning for our Kenyan viewers.
Negative Altitudes
Not so much a bug but it's advised you use a data type that can handle negative numbers for the altitude. Occasionally the GPS can report negative altitudes on the ground, if you're using an unsigned integer this overflows. As an example -4 meters would become 65531 meters. Impressive but we wouldn't be able to accept this as a record :)
Testing Your Payload
Checking the Tracker can Decode Your Telemetry Strings
Simulating a Flight
There are a number of ways to simulate a flight. In this example we replace the GPS with a Windows PC running TroSys GPS and playing back an actual flight that crossed the prime meridian. For this example you'll need some sort of serial break out. I used an UM232R.
You will need to get the free version of Tro Sys Gps Simulator Free.
You can download the sample data here :icarus_nmea_data_sample.zip
Connect your FT232 up to the PC and check the port number assigned in device manager. You may need to force it to use COM1 - 4 as the software won't select higher numbered COM ports.This can be done under Device Manager → Properties on the port, Port settings then advanced. Connect the RXD and TXD to your flight computer in place of the GPS. You can use this code to check its working, load this code on the Arduino, open the Serial Monitor, then open the UM232R via hyperterm or similar. If you type on the hyperterm it should appear in the Serial Monitor window :
#include <ctype.h> #include <string.h> #include <SoftwareSerial.h> int COUNT=0; byte GPS_TX=3; //GPS TX PIN byte GPS_RX=4; //GPS RX PIN SoftwareSerial GPS = SoftwareSerial(GPS_TX, GPS_RX); char SS_IN_BYTE; void setup() { pinMode(GPS_TX, INPUT); pinMode(GPS_RX, OUTPUT); GPS.begin(4800); // Amend Baud Rate as suits Serial.begin(9600); Serial.println("Serial Echo Utility"); } void loop() { while(1) { char SS_IN_BYTE = GPS.read(); Serial.print(SS_IN_BYTE); } }
Once this is working open up TroSys GPS Simulator. Select log file playback. Select the relevant file and click load file.Set the delay b/w sentences as appropriate. Configure the COM port settings as appropriate and click Connect. Once done you can now hit Send. This should play the log back to your project and simulate a flight.
There is also some software for doing this from various linux OS's
GPSgen and GPS emulate written by Steve Randall with a couple of minor modifications by Robert Harrison
Compile up the C programs
GPSgen takes a KML file and converts it to nema GPS strings.
./GPSgen < test.kml > test.gps
GPSemulate takes a GPS file and send the data out every second like a GPS device does
./GPSemulate < test.gps > /dev/ttyUSB0
Obviously you need to set up the ttyUSB0 device to the correct baud rate this can be done using
stty -F /dev/ttyUSB0 4800