====== Falcom FSA03 ====== {{guides:fsa03module.jpg|The Falcom FSA03}} ===== Overview ===== The [[http://www.falcom.de/products/gps-modules/fsa03/|Falcom FSA03]] is an inexpensive Ublox 5 ([[http://www.u-blox.com/en/gps-chips/stand-alone-gps-chips/u-blox-5-chipset-ubx-g5010.html|UBX-G5010]]) GPS module with a small footprint which featuring the Sarantel quadrifilar helix antenna. Although still available this unit is end of life. Ublox modules are capable of operating above 60,000 feet, provided they are configured and placed in airborne mode. The FSA03 does not include any EEPROM or Flash memory, and as such is unable to retain settings unless its RAM is buffered by backup battery. The module should be programmed with UBX whenever power has been lost to place it in airborne mode. Some FSA03 modules have been found to have a default baud rate of 9600, whilst others have a default baud rate of 38400, which may be difficult to parse if not using a UART (ie software serial). ===== Hardware ===== Given its unshielded board, the FSA03 is likely to be quite sensitive to ESD - the datasheet suggests it be treated as '**extremely sensitive to ESD**'. It's probably a good idea to solder the module last, and avoid touching the exposed board where possible. The datasheet is somewhat ambiguous regarding signals/tracks on the host board underneath the FSA03, mentioning '**Note: no ground under the component**' - it's not clear (to me at least) whether this refers to the fact that the underside of the module isn't grounded, or is a warning not to place any ground planes or tracks below the module (on the host board). The FSA03 provides a 1 Pulse-Per-Second output synchronised to UTC on its TM pin - this is often used as an indicator light for the module obtaining lock, but it's not entirely accurate - the 1PPS output will continue for some time even if the module loses lock, so long as it thinks its internal RTC is accurate. The module draws around 40mA typically, though upto 100mA when acquiring lock. The antenna on this module appears to be slightly wobbly and this may be one of the causes of the module not getting a lock for long periods of time. It's recommended that you secure it (perhaps with glue) in a position that works. ===== Configuration ===== The FSA03 is primarily configured through Ublox's binary protocol (UBX), though some parameters can be altered using NMEA sentences. The [[http://www.u-blox.com/images/downloads/Product_Docs/u-blox5_Protocol_Specifications%28GPS.G5-X-07036%29.pdf|UBX protocol specification]] covers configuring the module. ==== Common UBX commands decoded directly from u-center ==== ====== CONFIG NAV MODE (Airbone < 1g) + (Auto 2D/3D) ====== 09:37:25 SEND B5 62 06 24 24 00 FF FF 06 03 00 00 00 00 10 27 // Set Navigation Engine Settings SEND 00 00 05 00 FA 00 FA 00 64 00 2C 01 00 00 00 00 SEND 00 00 00 00 00 00 00 00 00 00 16 DC 09:37:25 RECV B5 62 05 01 02 00 06 24 32 5B // Message Acknowledged ====== SBAS DISABLE ====== 10:09:35 SEND B5 62 06 16 08 00 00 07 03 00 51 08 00 00 87 29 // Set SBAS Settings 10:09:35 RECV B5 62 05 01 02 00 06 16 24 4D // Message Acknowledged ====== SBAS - EGNOS - FOR EU ====== 10:01:18 SEND B5 62 06 16 08 00 01 07 03 00 51 08 00 00 88 31 // Set EGNOS 10:01:18 RECV B5 62 05 01 02 00 06 16 24 4D // Message Acknowledged ====== DISABLE GPGGA ON ALL PORTS ====== 10:34:44 SEND B5 62 06 01 08 00 F0 00 00 00 00 00 00 01 00 24 // Set Message Rate on all I/O ports 10:34:44 RECV B5 62 05 01 02 00 06 01 0F 38 // Message Acknowledged ====== DISABLE GPGLL ON ALL PORTS ====== 10:37:37 SEND B5 62 06 01 08 00 F0 01 00 00 00 00 00 01 01 2B 10:37:37 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPGSA ON ALL PORTS ====== 10:39:18 SEND B5 62 06 01 08 00 F0 02 00 00 00 00 00 01 02 32 10:39:18 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPGSV ON ALL PORTS ====== 10:40:33 SEND B5 62 06 01 08 00 F0 03 00 00 00 00 00 01 03 39 10:40:33 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPRMC ON ALL PORTS ====== 10:41:59 SEND B5 62 06 01 08 00 F0 04 00 00 00 00 00 01 04 40 10:41:59 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPVTG ON ALL PORTS ====== 10:43:06 SEND B5 62 06 01 08 00 F0 05 00 00 00 00 00 01 05 47 10:43:06 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPGRS ON ALL PORTS ====== 10:44:06 SEND B5 62 06 01 08 00 F0 06 00 00 00 00 00 00 05 4D 10:44:06 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPGST ON ALL PORTS ====== 10:44:57 SEND B5 62 06 01 08 00 F0 07 00 00 00 00 00 00 06 54 10:44:57 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPZDA ON ALL PORTS ====== 10:45:41 SEND B5 62 06 01 08 00 F0 08 00 00 00 00 00 00 07 5B 10:45:41 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPGBS ON ALL PORTS ====== 10:46:26 SEND B5 62 06 01 08 00 F0 09 00 00 00 00 00 00 08 62 10:46:26 RECV B5 62 05 01 02 00 06 01 0F 38 ====== DISABLE GPDTM ON ALL PORTS ====== 10:47:07 SEND B5 62 06 01 08 00 F0 0A 00 00 00 00 00 00 09 69 10:47:07 RECV B5 62 05 01 02 00 06 01 0F 38 ====== START GPS ====== 09:47:29 SEND B5 62 06 04 04 00 00 00 09 00 17 76 // Hotstart 09:47:29 RECV 24 47 50 54 58 54 2C 30 31 2C 30 31 2C 30 32 2C // $GPTXT,01,01,02, RECV 53 74 61 72 74 69 6E 67 20 47 50 53 2A 30 39 0D 0A // Starting GPS*09 09:47:29 RECV B5 62 05 01 02 00 06 04 12 3B // Message Acknowledged ====== STOP GPS ====== 09:47:29 SEND B5 62 06 04 04 00 00 00 08 00 16 74 // Stop 09:47:29 RECV 24 47 50 54 58 54 2C 30 31 2C 30 31 2C 30 32 2C // $GPTXT,01,01,02, RECV 53 74 6F 70 70 69 6E 67 20 47 50 53 2A 30 31 0D 0A // Stopping GPS*01 09:47:29 RECV B5 62 05 01 02 00 06 04 12 3B // Message Acknowledged ====== MAX PERFORMANCE MODE ====== 11:21:00 SEND B5 62 06 11 02 00 00 00 19 81 // Max. performance mode 11:21:00 RECV B5 62 05 01 02 00 06 11 1F 48 // Message Acknowledged ====== ECO MODE ====== 11:19:38 SEND B5 62 06 11 02 00 00 04 1D 85 // Eco mode 11:19:38 RECV B5 62 05 01 02 00 06 11 1F 48 // Message Acknowledged ===== CONFIG DATUM ====== 09:31:57 SEND B5 62 06 06 02 00 48 00 56 DA // Set Standard Datum, 0x48 for GR, Change to yours. 09:31:57 RECV B5 62 05 01 02 00 06 06 14 3D // Message Acknowledged ===== Baud rate to 4800 ===== 09:33:45 SEND B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 C0 12 // Set 4800 SEND 00 00 03 00 03 00 00 00 00 00 CB C4 09:33:45 RECV B5 62 05 01 02 00 06 00 25 8D // Message Acknowledged ==== Sample code ==== // This code gives an example of configuring an FSA03 connected to a software serial port on an Arduino #include NewSoftSerial nss(2, 3); // GPS Tx output is connected to Arduino input on pin 2 // GPS Rx input is connected to Arduino output on pin 3 byte navmode = 99; void setup() { // Start up serial ports nss.begin(38400); Serial.begin(115200); // used for debug ouput delay(2000); // Give the GPS time to come boot // Lower the baud rate to 9600 from 38.4k Serial.print("Setting uBlox port mode: "); uint8_t setPort[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x95}; sendUBX(setPort, sizeof(setPort)/sizeof(uint8_t)); // Switch baud rates on the software serial Serial.println("Switching to 9600b GPS serial"); nss.begin(9600); delay(1000); // Set the navigation mode (Airborne, 1G) Serial.print("Setting uBlox nav mode: "); uint8_t setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC}; sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t)); getUBX_ACK(setNav); // Switch off GLL Serial.print("Switching off NMEA GLL: "); uint8_t setGLL[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B }; sendUBX(setGLL, sizeof(setGLL)/sizeof(uint8_t)); getUBX_ACK(setGLL); // Switch off GSA Serial.print("Switching off NMEA GSA: "); uint8_t setGSA[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32 }; sendUBX(setGSA, sizeof(setGSA)/sizeof(uint8_t)); getUBX_ACK(setGSA); // Switch off GSV Serial.print("Switching off NMEA GSV: "); uint8_t setGSV[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39 }; sendUBX(setGSV, sizeof(setGSV)/sizeof(uint8_t)); getUBX_ACK(setGSV); // Switch off RMC Serial.print("Switching off NMEA RMC: "); uint8_t setRMC[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40 }; sendUBX(setRMC, sizeof(setRMC)/sizeof(uint8_t)); getUBX_ACK(setRMC); } // Dump bytes to debug as they appear void loop() { if (nss.available()) { Serial.print(nss.read(), BYTE); } } // Send a byte array of UBX protocol to the GPS void sendUBX(uint8_t *MSG, uint8_t len) { for(int i=0; i 9) { // All packets in order! Serial.println(" (SUCCESS!)"); return true; } // Timeout if no valid response in 3 seconds if (millis() - startTime > 3000) { Serial.println(" (FAILED!)"); return false; } // Make sure data is available to read if (nss.available()) { b = nss.read(); // Check that bytes arrive in sequence as per expected ACK packet if (b == ackPacket[ackByteID]) { ackByteID++; Serial.print(b, HEX); } else { ackByteID = 0; // Reset and look again, invalid order } } } } //Function to poll the NAV5 status of a Ublox GPS module (5/6) //Sends a UBX command (requires the function sendUBX()) and waits 3 seconds // for a reply from the module. The then isolates the byte which contains // the information regarding the NAV5 mode, // 0 = Pedestrian mode (default, will not work above 12km) // 6 = Airborne 1G (works up to 50km altitude) //Adapted by jcoxon from getUBX_ACK() from the example code on UKHAS wiki // http://wiki.ukhas.org.uk/guides:falcom_fsa03 boolean checkNAV(){ uint8_t b, bytePos = 0; uint8_t getNAV5[] = { 0xB5, 0x62, 0x06, 0x24, 0x00, 0x00, 0x2A, 0x84 }; //Poll NAV5 status nss.flush(); unsigned long startTime = millis(); sendUBX(getNAV5, sizeof(getNAV5)/sizeof(uint8_t)); while (1) { // Make sure data is available to read if (nss.available()) { b = nss.read(); if(bytePos == 8){ navmode = b; return true; } bytePos++; } // Timeout if no valid response in 3 seconds if (millis() - startTime > 3000) { navmode = 0; return false; } } } ==== NMEA ==== If you only need to turn of the sentances then you can just use NMEA commands: // Turning off all GPS NMEA strings apart from GPGGA on the uBlox modules Serial.print("$PUBX,40,GLL,0,0,0,0*5C\r\n"); Serial.print("$PUBX,40,ZDA,0,0,0,0*44\r\n"); Serial.print("$PUBX,40,VTG,0,0,0,0*5E\r\n"); Serial.print("$PUBX,40,GSV,0,0,0,0*59\r\n"); Serial.print("$PUBX,40,GSA,0,0,0,0*4E\r\n"); Serial.print("$PUBX,40,RMC,0,0,0,0*47\r\n"); ==== Saving your settings ==== As the FSA03 doesn't have any RAM or flash memory, its RAM must be buffered by a backup battery to retain settings. So long as the backup battery remains in place, you can can save your settings as per page 99 of the UBX protocol specification "Clear, Save and Load configurations". ===== Navigation data ===== By default, FSA03 modules are configured to output several NMEA sentences including GPRMC, GPGGA & GPVTG. Of these, GPGGA is the most useful for high altitute balloon applications as it contains altitude data. Un-necessary sentences can be disabled, see the [[guides:falcom_fsa03:#configuration|configuration]] section for more information. ==== Polling the module ==== Ublox 5 based GPS modules implement a proprietary NMEA extension in the form of a polled sentence which reports all navigation parameters of interest (to us at least) in a single sentence when requested. Using this provides advantages in that you can request an update exactly when you need it, and you only need to parse one specific sentence to capture latitude, longitude, altitude, speed, course, etc. For those using a SoftwareSerial library, this method fixes the buffer overrun issues. To use the sentence firstly disable any GPS sentences which are currently switched on: Serial.println("$PUBX,40,GLL,0,0,0,0*5C"); Serial.println("$PUBX,40,GGA,0,0,0,0*5A"); Serial.println("$PUBX,40,GSA,0,0,0,0*4E"); Serial.println("$PUBX,40,RMC,0,0,0,0*47"); Serial.println("$PUBX,40,GSV,0,0,0,0*59"); Serial.println("$PUBX,40,VTG,0,0,0,0*5E"); The sentence can be requested by sending the string "$PUBX,00*33": Serial.println("$PUBX,00*33"); The module responds (within 1 second) with the current navigation data in the following format: $PUBX,00,hhmmss.ss,Latitude,N,Longitude,E,AltRef,NavStat,Hacc,Vacc,SOG,COG,Vvel,ageC,HDOP,VDOP,TDOP,GU,RU,DR,*cs ^Field No.^Example^Format^Name^Unit^Description^ |0|$PUBX|string|$PUBX|-|Message ID, UBX protocol header, proprietary sentence| |1|00|numeric|ID|-|Propietary message identifier: 00| |2|081350.00|hhmmss.ss|hhmmss.ss|-|UTC Time, Current time| |3|4717.113210|ddmm.mmmm|Latitude|-|Latitude, Degrees + minutes, see Format description| |4|N|character|N|-|N/S Indicator, N=north or S=south| |5|00833.915187|dddmm.mmmm|Longitude|-|Longitude, Degrees + minutes, see Format description| |6|E|character|E|-|E/W indicator, E=east or W=west| |7|546.589|numeric|AltRef|m|Altitude above user datum ellipsoid.| |8|G3|string|NavStat|-|Navigation Status - Example: G3 =Stand alone 3D solution, NF =No Fix| |9|2.1|numeric|Hacc|m|Horizontal accuracy estimate.| |10|2.0|numeric|Vacc|m|Vertical accuracy estimate.| |11|0.007|numeric|SOG|km/h|Speed over ground| |12|77.52|numeric|COG|degrees|Course over ground| |13|0.007|numeric|Vvel|m/s|Vertical velocity, positive=downwards| |14|-|numeric|ageC|s|Age of most recent DGPS corrections, empty = none available| |15|0.92|numeric|HDOP|-|HDOP, Horizontal Dilution of Precision| |16|1.19|numeric|VDOP|-|VDOP, Vertical Dilution of Precision| |17|0.77|numeric|TDOP|-|TDOP, Time Dilution of Precision| |18|9|numeric|GU|-|Number of GPS satellites used in the navigation solution| |19|0|numeric|RU|-|Number of GLONASS satellites used in the navigation solution| |20|0|numeric|DR|-|DR used| |21|*5B|hexadecimal|cs|-|Checksum| |22|-|character||-|Carriage Return and Line Feed| For details see page 52 of the UBX protocol specification "Proprietary Messages, UBX00". ==== Modified TinyGPS ==== {{code:tinygps.zip|Here's}} a copy of the [[http://arduiniana.org/libraries/tinygps/|TinyGPS]] library by Mikal Hart modified to decode the polled Ublox sentence containing everything likely to be needed for high altitude ballooning. A new method sats() has been added, which will return the number of GPS satellites currently being tracked by the module.