Interfacing a USB GPS with an Arduino

Now that ERP1 is up and running, it needs to be able to fix its position and report this back over the wireless data link. I plan to develop a simple Kalman filter to estimate ERP’s position, but to do this, I need two things…..

(a) An Action Parameter. This will be in the form of a motion vector. Direction will come from a digital compass and Magnitude from a  wheel mounted optical encoder.

(b) Data Update. This will the estimated position of ERP1 obtained from an external fixing system such as the popular Global Positioning System (GPS).

GPS Constellation. Source : Wikipedia

GPS Constellation. Source : Wikipedia

The first step in this little project is to be able to stream GPS data to an Arduino, interpret the data (which typically is in the form of NMEA sentences), and then use the latitude and longitude coordinates in further computation.

To do this, I decided to use an old USB GPS unit I had lying around the house. We purchased this a few years ago to help us navigate on our road trips but the advent of smartphones with built-in GPS receivers soon relegated this little device to the “Gadget Graveyard”.

USB GPS

USB GPS

To be able to read data from this device into an Arduino, the Arduino must be capable of emulating a USB Host. To do this, I am using a USB Host Shield that I bought from ebay for US$11.

USB Shield to interface GPS with Arduino

USB Shield to interface GPS with Arduino

This USB shield connects to the Arduino using the ICSP headers located near the bottom of the board and talks to the Arduino using the SPI communications protocol. This means that all other pins on the Arduino (other than MISO, MOSI, and SCLK) are available for use.

USB Shield connected through ICSP headers

USB Shield connected through ICSP headers

I used Oleg Mazurov’s USB Shield Arduino Library to connect to the shield and I modified the code a little to stream incoming data into Mikal Hart’s GPS Parser Library, TinyGPS. Here is the crux of the code….


if(Pl.isReady()) {
/* reading the GPS */
if((long)(millis() - read_delay) >= 0L) {
read_delay += READ_DELAY;
rcode = Pl.RcvData(&rcvd, buf);
if(rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if(rcvd) { //more than zero bytes received

for(uint16_t i = 0; i < rcvd; i++) {

//Now send chars from buf[] into the TinyGPS parser...
if(gps1.encode(buf[i]))
{
GPSUpdated = true;
} else GPSUpdated = false;
//Print chars from buf[] directly to serial interface for debugging
//Serial.print((char)buf[i]);

}//for( uint16_t i=0; i < rcvd; i++...

}//if( rcvd
}//if( read_delay > millis()...
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
if(GPSUpdated = true)
{
gps1.f_get_position(&flat, &flon, &fix_age);
Serial.print("lat:");
Serial.print(flat);
Serial.print(",lon:");
Serial.println(flon);
}

Position information now streams continuously from the GPS device into the Arduino and I can use this for telemetry, Kalman filtering, cartography, estimating course and speed over ground, time & date, or any other application that uses GPS data.

Here is my youtube video of the project running on my laptop.

 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s