UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


guides:falcom_fsa03

Falcom FSA03

The Falcom FSA03

Overview

The Falcom FSA03 is an inexpensive Ublox 5 (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 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.h>
 
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<len; i++) {
		nss.print(MSG[i], BYTE);
		Serial.print(MSG[i], HEX);
	}
	Serial.println();
}
 
 
// Calculate expected UBX ACK packet and parse UBX response from GPS
boolean getUBX_ACK(uint8_t *MSG) {
	uint8_t b;
	uint8_t ackByteID = 0;
	uint8_t ackPacket[10];
	unsigned long startTime = millis();
	Serial.print(" * Reading ACK response: ");
 
	// Construct the expected ACK packet    
	ackPacket[0] = 0xB5;	// header
	ackPacket[1] = 0x62;	// header
	ackPacket[2] = 0x05;	// class
	ackPacket[3] = 0x01;	// id
	ackPacket[4] = 0x02;	// length
	ackPacket[5] = 0x00;
	ackPacket[6] = MSG[2];	// ACK class
	ackPacket[7] = MSG[3];	// ACK id
	ackPacket[8] = 0;		// CK_A
	ackPacket[9] = 0;		// CK_B
 
	// Calculate the checksums
	for (uint8_t i=2; i<8; i++) {
		ackPacket[8] = ackPacket[8] + ackPacket[i];
		ackPacket[9] = ackPacket[9] + ackPacket[8];
	}
 
	while (1) {
 
		// Test for success
		if (ackByteID > 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”.

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 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<CR><LF>
Field No.ExampleFormatNameUnitDescription
0$PUBXstring$PUBX-Message ID, UBX protocol header, proprietary sentence
100numericID-Propietary message identifier: 00
2081350.00hhmmss.sshhmmss.ss-UTC Time, Current time
34717.113210ddmm.mmmmLatitude-Latitude, Degrees + minutes, see Format description
4NcharacterN-N/S Indicator, N=north or S=south
500833.915187dddmm.mmmmLongitude-Longitude, Degrees + minutes, see Format description
6EcharacterE-E/W indicator, E=east or W=west
7546.589numericAltRefmAltitude above user datum ellipsoid.
8G3stringNavStat-Navigation Status - Example: G3 =Stand alone 3D solution, NF =No Fix
92.1numericHaccmHorizontal accuracy estimate.
102.0numericVaccmVertical accuracy estimate.
110.007numericSOGkm/hSpeed over ground
1277.52numericCOGdegreesCourse over ground
130.007numericVvelm/sVertical velocity, positive=downwards
14-numericageCsAge of most recent DGPS corrections, empty = none available
150.92numericHDOP-HDOP, Horizontal Dilution of Precision
161.19numericVDOP-VDOP, Vertical Dilution of Precision
170.77numericTDOP-TDOP, Time Dilution of Precision
189numericGU-Number of GPS satellites used in the navigation solution
190numericRU-Number of GLONASS satellites used in the navigation solution
200numericDR-DR used
21*5Bhexadecimalcs-Checksum
22-character<CR><LF>-Carriage Return and Line Feed

For details see page 52 of the UBX protocol specification “Proprietary Messages, UBX00”.

Modified TinyGPS

Here's a copy of the 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.

guides/falcom_fsa03.txt · Last modified: 2012/06/03 14:42 by upu