User Tools

Site Tools


frontpage:levelconvertor

ublox Max-6 With Level Converter

The uBLOX MAX-6 board with integral level converter is ideal for connecting directly to 5v Arduino without the need for additional power supplies or level conversion circuitry. It has an onboard regulator to ensure the ublox MAX-6 module gets the current it needs to operate correctly.

Below is example code and hardware connections to get it working using Software Serial and the hardware UART.

Please note this :

I STRONGLY advise against the use of Software Serial in conjunction with the ublox MAX-6 modules. They seem extremely sensitive to timing on the serial port and I've had intermittent results at 9,600 baud via software serial.

Code Examples below have been tested in Arduino 1.0.1.

Example Using Software Serial

Introduction

As discussed ublox modules seem to be sensitive to timing so to get this to work reliably I've had to reduce the baud rate to 4800. Even at 4800 I've noted intermittent issues, your mileage may vary. You can configure the GPS module using either $PUBX commands or using binary commands. The binary commands, though more complex, do acknowledge the command. To see how to get these commands read the u-blox 6 Receiver Description and Protocol Specification or see the article on using u-Center to get the commands.

Hardware Setup

You will need :

1 x 5V Arduino Board
1 x HAB Supplies ublox MAX6 Breakout
4 x Wires

Connect 5V on the board to 5V on the Arduino
Connect GND on the board to GND on the Arduino
Connect RX on the board to pin 4
Connect TX on the board to pin 5

Software Setup

/*
 GPS Level Convertor Board Test Script
 03/05/2012 2E0UPU
 For use with the HAB Supplies Level Convertor Board
 http://ava.upuaut.net/store
 
 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.h>
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<len; i++) {
    GPS.write(MSG[i]);
    Serial.print(MSG[i], HEX);
  }
  GPS.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 (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
      }
 
    }
  }
}

Once loaded up open your serial monitor and you should see NMEA output similar to below :

This indicates the GPS module is working, as it begins to recieve a signal you'll see the (UTC) time appear followed by location information shortly afterwards depending on view of the sky. From here I would disconnect the Arduino serial monitor and open ucenter, select the relevant serial port and watch as it locates satellites etc.

Example Using Hardware Serial

Introduction

This is the preferred method of connection and is set to 9,600 baud by default. As you are using the Arduino on board UART for the GPS you will need to debug via Software Serial, requiring the use of another serial port on the PC. I recommend the UM232R Serial UART Development Module.

Hardware Setup

You will need :

1 x 5V Arduino Board
1 x HAB Supplies ublox MAX6 Breakout (HSM6BO)
1 x UM232 Serial UART Development Module or equivalent.

Connect HSM6BO 5V on the board to 5V on the Arduino
Connect HSM6BO GND on the board to GND on the Arduino
Connect HSM6BO RX on the board to pin 1 TX
Connect HSM6BO 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

When done it should look like this (Click for bigger) :

I would ascertain what COM port your UM232R is on before proceeding. You can open this port in any serial program like hyperterminal or PuTTY.

Software Setup

/*
  GPS Level Convertor Board Test Script
  03/05/2012 2E0UPU
  For use with the HAB Supplies Level Convertor Board
  http://ava.upuaut.net/store
 
  Initialise the GPS Module in Flight Mode and then echo's 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.h>
 
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<len; i++) {
    Serial.write(MSG[i]);
    mySerial.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();
  mySerial.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!
      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
      }
 
    }
  }
}

Load this code up and if everything is wired correctly you should start to see the NMEA output in your terminal window. As before at this point you can close your terminal program down and open the uBlox u-Center, point it at the COM port of the UM232 and away you go.

frontpage/levelconvertor.txt · Last modified: 2013/04/07 14:36 by admin