====== uBlox NEO-6Q / uBlox MAX-6Q ====== ===== Overview ===== The uBLOX NEO-6Q/MAX-6Q are the sucessor to the uBLOX 5 module used in the Falcom FSA-03. They are 50 channel GPS in a 16 x 12.2 x 2.4mm (NEO) 9.7 x 10.1 x 2.4mm (MAX) package. They are rated up to 50,000 meters (164,000 feet) altitude in flight mode. They are an inexpensive module with good performance. The chip is shielded though normal precautions with regards to ESD should be observed. Data sheet is available [[http://www.u-blox.ch/images/downloads/Product_Docs/NEO-6_ProductSummary_%28GPS.G6-HW-09003%29.pdf|here]]. **WARNING : uBLOX 6 Chips are rated at 3.3v so you can't just plug this into an 5V Arduino board or a PC serial connection as these run at 5V.** You can purchase a seperate level converter from [[http://www.sparkfun.com/products/8745|Sparkfun]] or use a breakout with the integral level converter available from [[https://store.uputronics.com|Uputronics]]. The MAX-6 Chip, Sarantel antenna and populated breakout boards can be purchased from [[https://store.uputronics.com|Uputronics]]. ===== Hardware ===== Unlike the Falcom FSA03 these units are just supplied as a standalone surface mount chip without an antenna. To use it you will need to use a breakout board/design your own board. If you want to integrate the units into your own design both modules and antennas are in [[https://www.dropbox.com/s/qytveix714ocw11/Ava.lbr|Ava.lbr]]. ===== Software Serial Configuration Example ===== All commands the same as the uBLOX5 documented by Jcoxon in the [[guides:falcom_fsa03|Falcom FSA03]] guide.The following code has been updated to reflect the changes to Software Serial in Arduino. The uBLOX 6 modules do seem particularly sensitive to timing issues on Software Serial therefore its recommended you use the hardware UARTS on the Arduino for the GPS. Tested in Arduino 1.0.1 : /* GPS Level Convertor Board Test Script 03/05/2012 2E0UPU This example connects the GPS via Software Serial. Initialise the GPS Module in Flight Mode and then echo's out the NMEA Data to the Arduinos onboard Serial port. This example code is in the public domain. Additional Code by J Coxon (http://ukhas.org.uk/guides:falcom_fsa03) */ #include SoftwareSerial GPS(4, 5); byte gps_set_sucess = 0 ; void setup() { GPS.begin(9600); // START OUR SERIAL DEBUG PORT Serial.begin(9600); Serial.println("GPS Level Convertor Board Test Script"); Serial.println("03/06/2012 2E0UPU"); Serial.println("Initialising...."); // // THE FOLLOWING COMMAND SWITCHES MODULE TO 4800 BAUD // THEN SWITCHES THE SOFTWARE SERIAL TO 4,800 BAUD // GPS.print("$PUBX,41,1,0007,0003,4800,0*13\r\n"); GPS.begin(4800); GPS.flush(); // THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT Serial.println("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 }; while(!gps_set_sucess) { sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setNav); } gps_set_sucess=0; // THE FOLLOWING COMMANDS DO WHAT THE $PUBX ONES DO BUT WITH CONFIRMATION // UNCOMMENT AS NEEDED /* Serial.println("Switching off NMEA GLL: "); uint8_t setGLL[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B }; while(!gps_set_sucess) { sendUBX(setGLL, sizeof(setGLL)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGLL); } gps_set_sucess=0; Serial.println("Switching off NMEA GSA: "); uint8_t setGSA[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32 }; while(!gps_set_sucess) { sendUBX(setGSA, sizeof(setGSA)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGSA); } gps_set_sucess=0; Serial.println("Switching off NMEA GSV: "); uint8_t setGSV[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39 }; while(!gps_set_sucess) { sendUBX(setGSV, sizeof(setGSV)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGSV); } gps_set_sucess=0; 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 }; while(!gps_set_sucess) { sendUBX(setRMC, sizeof(setRMC)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setRMC); } */ } void loop() { while(1) { if(GPS.available()) { // THIS IS THE MAIN LOOP JUST READS IN FROM THE GPS SERIAL AND ECHOS OUT TO THE ARDUINO SERIAL. Serial.write(GPS.read()); } } } // 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 (GPS.available()) { b = GPS.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 } } } } ===== Hardware Serial Configuration Example ===== You will need : 1 x Arduino Board\\ 1 x ublox MAX6 Breakout (Level Converted if using 5V Arduino)(UB6)\\ 1 x UM232 Serial UART Development Module or equivalent.\\ Connect UB6 5V on the board to 5V on the Arduino\\ Connect UB6 GND on the board to GND on the Arduino\\ Connect UB6 RX on the board to pin 1 TX\\ Connect UB6 TX on the board to pin 0 RX\\ Connect UM232R pin DB0 to pin 4 on the Arduino\\ Connect UM232R pin DB1 to pin 5 on the Arduino\\ Connect UM232R pin GND to GND on the Arduino\\ /* GPS Level Convertor Board Test Script 03/05/2012 2E0UPU Initialise the GPS Module in Flight Mode and then echoes out the NMEA Data to the Software Serial. This example code is in the public domain. Additional Code by J Coxon (http://ukhas.org.uk/guides:falcom_fsa03) */ #include SoftwareSerial mySerial(4, 5); byte gps_set_sucess = 0 ; void setup() { mySerial.begin(9600); Serial.begin(9600); mySerial.println("GPS Level Convertor Board Test Script"); mySerial.println("03/06/2012 2E0UPU"); mySerial.println("Initialising...."); // THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT mySerial.println("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 }; while(!gps_set_sucess) { sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setNav); } gps_set_sucess=0; // THE FOLLOWING COMMANDS DO WHAT THE $PUBX ONES DO BUT WITH CONFIRMATION /* debug.println("Switching off NMEA GLL: "); uint8_t setGLL[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B }; while(!gps_set_sucess) { sendUBX(setGLL, sizeof(setGLL)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGLL); } gps_set_sucess=0; debug.println("Switching off NMEA GSA: "); uint8_t setGSA[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32 }; while(!gps_set_sucess) { sendUBX(setGSA, sizeof(setGSA)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGSA); } gps_set_sucess=0; debug.println("Switching off NMEA GSV: "); uint8_t setGSV[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39 }; while(!gps_set_sucess) { sendUBX(setGSV, sizeof(setGSV)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setGSV); } gps_set_sucess=0; debug.print("Switching off NMEA RMC: "); uint8_t setRMC[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40 }; while(!gps_set_sucess) { sendUBX(setRMC, sizeof(setRMC)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setRMC); } gps_set_sucess=0; debug.print("Switching off NMEA VTG: "); uint8_t setVTG[] = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46 }; while(!gps_set_sucess) { sendUBX(setVTG, sizeof(setRMC)/sizeof(uint8_t)); gps_set_sucess=getUBX_ACK(setVTG); } */ } void loop() { while(1) { if(Serial.available() > 0) { char inByte = Serial.read(); mySerial.write(inByte); } } } // 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! mySerial.println(" (SUCCESS!)"); return true; } // Timeout if no valid response in 3 seconds if (millis() - startTime > 3000) { mySerial.println(" (FAILED!)"); return false; } // Make sure data is available to read if (Serial.available()) { b = Serial.read(); // Check that bytes arrive in sequence as per expected ACK packet if (b == ackPacket[ackByteID]) { ackByteID++; mySerial.print(b, HEX); } else { ackByteID = 0; // Reset and look again, invalid order } } } } ==== 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 uBLOX6 modules don't have any RAM or flash memory, its RAM must be buffered by a backup battery to retain settings or use external 1-Wire Flash module(see data sheets). As 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, uBLOX6 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 previous code sample section for more information. ==== Polling the module ==== Ublox6 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". You can use a modified version of the [[http://arduiniana.org/libraries/tinygps/|TinyGPS]] library to parse PUBX sentences – [[https://github.com/x-f/TinyGPS_UBX|TinyGPS_UBX]]. ===== Images ====== uBLOX NEO-6 : {{:guides:ublox.jpg?400|}} uBLOX MAX-6 : {{:guides:crw_7240-500x500.png?400|}} ===== Troubleshooting ===== ==== No Response From GPS ==== * Check power, measure VCC and GND. * Run above scripts, check that you get SUCCESS on ACKs. ==== No time updated or GPS fix ==== * Hook up the module to a 3.3v FTDI with the corresponding wires (TX,RX,VCC,GND) * Start up uBlox u-center [[http://www.u-blox.com/en/evaluation-tools-a-software/u-center/u-center.html]]