GPS over I2C!


We’ve written a simple I2C interface for I2GPS (available for sale here). If you’ve ever combined GPS to Arduino you have probably used TinyGPS by Mikal Hart.  We use it too and we love it.

When you want to incorporate GPS into a larger project a couple of issues arise that I2GPS solves.  The first issue is that the GPS object must constantly be “fed” new data.  This leads to ubiquitous calls to gps.feed() throughout the code.  If you have other time critical functions (like updating an LED matrix), the juggling of tasks can get overly complex.  The second is the size of the code can cramp the size of your main program.  We ran into both of these problems with ClockTHREEjr.

I2GPS solves these problems with by offloading the memory and processing burden to a second processor.  The I2GPS slave code needs only to read the GPS, and respond to I2C requests to data.

I’ve modeled the interface after the DS3231, the real time clock included with I2GPS, the same clock as the Chronodot from Macetech.  So from the client side, things look a lot like reading the Chronodot.  Here is a snippet of client code (not updated).  The DS3231 is still available though the I2C interface.

// read 32 bytes from address 0, store in "gps_data" byte array
  gps_raw_read((uint8_t)0, (uint8_t)32, gps_data);

// Parse response
  Serial.print("UNIX TIME:");
  Serial.println(unserialize_ulong(gps_data+0));
  Serial.print("LAT:");
  Serial.print(unserialize_long(gps_data+4));
  Serial.println(" 1/1000th DEG");
  Serial.print("LON:");
  Serial.print(unserialize_long(gps_data+8));
  Serial.println(" 1/1000th DEG");
  Serial.print("ALT:");
  Serial.print(unserialize_long(gps_data+12));
  Serial.println(" CM");

Wall clock time is also available starting at address 0x1C.

gps_raw_read(0x1C, 6, ymdhms);

Serial.print("CALENDAR TIME:");
Serial.print(ymdhms[1], DEC); // Month
Serial.print("/");       
Serial.print(ymdhms[2], DEC); // Day
Serial.print("/");
Serial.print(ymdhms[0], DEC); // Year

Serial.print(" ");
Serial.print(ymdhms[3], DEC); // Hour
Serial.print(":");
Serial.print(ymdhms[4], DEC); // Minute
Serial.print(":");
Serial.print(ymdhms[5], DEC); // Second
Serial.println("");

The I2GPS has several physical interface options. Shown above is the “Buckler” (small shield) interface that plugs directly into the analog side of the Arduino.

The complete data structure memory map is available as a google spreadsheet (for the latest) or below in static html.  I’ve put a couple of field to log the state of analog and digital pins, but supporting code has not been implemented yet.  Available data include: unix time (and wall clock time), latitude, longitude, altitude, course, speed, fix age.

 

Leave a Reply