Monday, January 10, 2011

GpsArduino

I also wanted to provide an example of how to connect the EM-406A GPS module to the Arduino Uno.

The setup is pretty easy and equal to the setup which was used for the GpsSPOT experiment. You only have to connect the respective ports of the Arduino board.

This is a simplified schematic of the connections which have to be made:

The source code was a little bit trickier to figure out. Since the module works with a baud rate of 4800 bits per second, you have to consider appropriate delays before reading the next bit. Because we read one bit at a time, we have to use bit shifting to get the whole byte which can be translated to a character via an Ascii-table. Note that I only implemented the GPPGA format in this example.

The data is transmitted via the serial port to the PC. You can use Hyperterminal to display the data. Just configure the port where your Arduino is connected to and set a baud rate of 9600. The data is displayed in a comma seperated format which could be parsed.

Source code:

#include <string.h>

#define bit4800Delay 200
#define halfBit4800Delay 100

byte rx = 4;
byte tx = 2;

void setup() {
  //reads EM-406A tx line
  pinMode(rx,INPUT);
  //writes to EM-406A rx line
  pinMode(tx,OUTPUT);
  //if rx of the EM-406A is not used it must be set to high
  digitalWrite(tx,HIGH);
 
  //init serial port to write output to terminal
  Serial.begin(9600);
 
  //init done, flash LED
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); 
  delay(500);            
  digitalWrite(13, LOW);
}

byte readByte()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit4800Delay);
    for (int offset = 0; offset < 8; offset++) {
    delayMicroseconds(bit4800Delay);
    val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit4800Delay);
    delayMicroseconds(bit4800Delay);
    return val;
  }
}

String getGPGGAMessage() {
  char val;
  String message = "";
  byte thresholdCounter = 0;
  while (thresholdCounter < 10) {
    val = readByte();
    if (val == '\n') {
      if (message.startsWith("$GPGGA")) {
        return message;
      } else {
        thresholdCounter++;
        message = "";
      }
    } else {
    // recover from bad read .. reset
      if (val == '$') {
       message = "";
      }
      message += (char) val;
    }
  }
  return "";
}

void loop() {
  Serial.println(getGPGGAMessage());
}
 
And here we go with a little demonstration: