This is an old revision of the document!
This is the typical protocol used by UKHAS members to transmit GPS data balloon to ground on the unlicensed bands, although any custom data may be tacked onto the end of the string.
This doesn't have to be strictly adhered to, since we can easily set up different rules via dl-fldigi's ability to automatically configure itself (upon request).
$$<CALL SIGN>,<COUNTER D>,<TIME HH:MM:SS>,<LATITUDE DD.DDDDDD>,<LONGITUDE DD.DDDDDD>,<ALTITUDE METRES MMMMM>,<O SPEED KM/H DDDD.DD>,<O BEARING DDD.DD>,<O TEMPERATURE INTERNAL C D.DD>,<O TEMPERATURE EXTERNAL C D.DD>,<O TEMPERATURE CAMERA C D.DD>,<O BAROMETRIC PRESSURE hPa(millibars)>,<O CUSTOM DATA>*<CHECKSUM><NEWLINE>
$$ALIEN1,1,12:13:11,50.904072,00.026106,09001,temperature: 14
$$icarus,12342,12:34:17,52.345645,-1.02342,10232,21.35,192.3,15.4,-22.34,-18.27,1232
$$icarus,12342,12:34:17,52.345645,-1.02342,10232,21.35,192.3,15.4,-22.34,-18.27,1232,Blah;Blah;Blah*00
Usage example for the below two functions
#include <stdio.h> #include <stdint.h> #include <string.h> char s[100]; void make_string(struct information i) { char checksum[10]; snprintf(s, sizeof(s), "$$MYPAYLOAD,%i,%s,%s", i->num, i->gps.lat, i->gps.lon); snprintf(checksum, sizeof(checksum), "*%04X\n", gps_CRC16_checksum(s)); // or snprintf(checksum, sizeof(checksum), "*%02X\n", gps_xor_checksum(s)); // It would be much more efficient to use the return value of snprintf here, rather than strlen if (strlen(s) > sizeof(s) - 4 - 1) { // Don't overflow the buffer. You should have made it bigger. return; } // Also copy checksum's terminating \0 (hence the +1). memcpy(s + strlen(s), checksum, strlen(checksum) + 1); }
Useful code to calculate NMEA xor checksum
#include <stdio.h> #include <stdint.h> #include <string.h> uint8_t gps_xor_checksum(char *string) { size_t i; uint8_t XOR; uint8_t c; XOR = 0; // Calculate checksum ignoring the first two $s for (i = 2; i < strlen(string); i++) { c = string[i]; XOR ^= c; } return XOR; }
Useful code to calculate CRC16_CCITT checksum on the AVR
#include <stdio.h> #include <stdint.h> #include <util/crc16.h> #include <string.h> uint16_t gps_CRC16_checksum (char *string) { size_t i; uint16_t crc; uint8_t c; crc = 0xFFFF; // Calculate checksum ignoring the first two $s for (i = 2; i < strlen(string); i++) { c = string[i]; crc = _crc_xmodem_update (crc, c); } return crc; }