# Got the LS20031 to play nice with TineGPS-NO check sum error

**URL:** <https://community.sparkfun.com/t/got-the-ls20031-to-play-nice-with-tinegps-no-check-sum-error/25930>\
**Category:** Development Boards\
**Created:** [January 29, 2013, 5:14pm UTC](https://community.sparkfun.com/t/got-the-ls20031-to-play-nice-with-tinegps-no-check-sum-error/25930 "2013-01-29T17:14:52Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![D9W](https://avatars.discourse-cdn.com/v4/letter/d/b5a626/32.png) [@D9W](https://community.sparkfun.com/u/D9W)\
**Post date:** [January 29, 2013, 5:14pm UTC](https://community.sparkfun.com/t/got-the-ls20031-to-play-nice-with-tinegps-no-check-sum-error/25930/1 "2013-01-29T17:14:52Z")

</div>

Got the LS20031 to play nice with TineGPS with NO check sum error

Here is the sketch that the LS20031 play nice with TinyGPS with no CheckSum errors for over 8 hours \>\>

You have to use a logic voltage converter between the to so you can communicate with the LS20031.

The logic voltage converter I am using is from [http://www.dsscircuits.com/i2c-level-converter.html](http://www.dsscircuits.com/i2c-level-converter.html).

The cool thing about using this one, is that it does not require pull up resistors on either side of the converter.

Also I have killed a number of the Mosfet voltage converters sitting on my desk. This one survived on my desk for over 6 months.

See [http://www.dsscircuits.com/images/schem … Wiring.pdf](http://www.dsscircuits.com/images/schematic/I2C%20Logic%20Level%20Converter%20Sample%20Wiring.pdf) for wiring Diagram.

```auto
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 4
 
 /*you need to go into Arduino -> Libraries-> SoftwareSerial-> SoftwareSerial.h and increase buffersize from 64 to 128. >>
       Open the file named "SoftwareSerial.h" in a text editor and scroll down to line 42, where you should see:
            #define _SS_MAX_RX_BUFF 64 // RX buffer size
       Increase the value 64, to a more reasonable 128 and then save the file. See Wayneholder web page for more information>>
       https://sites.google.com/site/wayneholder/self-driving-rc-car/navigating-with-gps
  */     
#define PMTK_SET_NMEA_UPDATE_HALF_HZ "$PMTK220,2000*1C\r\n" // Every 2000ms (0.5Hz)
#define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F\r\n" // Every 1000ms (1Hz)
#define PMTK_SET_NMEA_UPDATE_2HZ "$PMTK220,500*2B\r\n>" // Every 500ms (2Hz)
#define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C\r\n" // Every 200ms (5Hz)
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F\r\n" // Every 100ms (10Hz)
/* If the command is correct and executed, GPS module will output message $PMTK001,220,3*30<CR><LF>*/
#define PMTK_Set_NMEA_OUTPUT_GLL "$PMTK314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only GLL - Geographic position, latitude / longitude
#define PMTK_SET_NMEA_OUTPUT_RMC "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only RMC - Recommended minimum specific Loran-C data
#define PMTK_SET_NEMA_OUTPUT_VTG "$PMTK314,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only VTG - Track made good and ground speed
#define PMTK_SET_NEMA_OUTPUT_GGA "$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only GGA - Global Positioning System Fix Data
#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n" // turn on GPRMC and GPGGA ----- TinyGPS only uses these two, all others can be turned off
#define PMTK_SET_NMEA_OUTPUT_GSA "$PMTK314,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only GSA - GPS DOP and active satellites
#define PMTK_SET_NMEA_OUTPUT_GSV "$PMTK314,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n" // turn on only GSV - GPS Satellites in view
#define PMTK_SET_NEMA_OUTPUT_ZDA "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0*29\r\n" // turn on only ZDA - Date & Time - UTC, day, month, year, and local time zone.
#define PMTK_SET_NEMA_OUTPUT_RMCGAAGSA "$PMTK314,0,1,0,1,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0*2C\r\n" // RMC, GGA, GSA at 1Hz and GSV at 0.2Hz
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n" // turn on ALL THE DATA for the LS20031- except ZDA
#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n" // turn off output
/* If the command is correct and executed, GPS module will output message "$PMTK001,314,3*36<CR><LF>" See Flag upabove */
#define PMTK_Q_RELEASE "$PMTK605*31\r\n" /* Query FW release information -- MTK-3301s send firmware release name and version - Note: not sure of accuracy of this information */
  /* if the command is correct and executed, GPS module will output message example >> "$PMTK705,AXN_1.30,29BF,MC-1513,*0E"
     Data field >> "$PMTK705,ReleaseStr,Mod eID,,*0E"
     ReleaseSTr: Firmware release name & version
     ModelID: Model ID  
  */  
/*
 Demonstration sketch for Adafruit i2c/SPI LCD backpack
 using MCP23008 I2C expander - NOTE at this time all LCD functions have been REM out
 ( http://www.ladyada.net/products/i2cspilcdbackpack/index.html )

 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * 5V to Arduino 5V pin
 * GND to Arduino GND pin
 * CLK to Analog #5
 * DAT to Analog #4
*/

// include the library code:
#include <Wire.h>
//#include <LiquidTWI.h>

// Connect via i2c, default address #0 (A0-A2 not jumpered)
// LiquidTWI lcd(0);
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   57600-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
*/

TinyGPS gps;
SoftwareSerial nss(rxPin, txPin);

static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial.begin(115200);
  nss.begin(57600); // LS20031 baud- 57600
  while (!nss.available()){}
  nss.print(PMTK_SET_NMEA_OUTPUT_RMCGGA); // $GPxxx Messages
  nss.print(PMTK_SET_NMEA_UPDATE_1HZ); // messages 1 times a second
  nss.print(PMTK_Q_RELEASE);
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
  Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum");
  Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail");
  Serial.println("--------------------------------------------------------------------------------------------------------------------------------------");
 // set up the LCD's number of rows and columns: 
  //lcd.begin(16, 2);
  // Print a message to the LCD.
  //lcd.print("hello, world!");
}

void loop()
{
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  // lcd.setCursor(0, 1);
  bool newdata = false;
  unsigned long start = millis();
  // lcd.print(start/1000);
  // Every second we print an update
  while (millis() - start < 1000)
  {
    if (feedgps())
      newdata = true;
  }
  
  gpsdump(gps);
  //lcd.setBacklight(HIGH);
}

static void gpsdump(TinyGPS &gps)
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  
  Serial.print(" "); 
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
 //lcd.setCursor(0, 2); lcd.print("Satellites: "); lcd.print(gps.satellites());lcd.print(".");
  feedgps();

  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

  print_date(gps);

  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "***" : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "***" : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, " *******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz); feedgps();
}

static void print_float(float val, float invalid, int len, int prec)
{
  char sz[32];
  if (val == invalid){
    strcpy(sz, " *******");
    sz[len] = 0;
        if (len > 0) 
          sz[len-1] = ' ';
    for (int i=7; i<len; ++i)
        sz[i] = ' ';
    Serial.print(sz);
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1);
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(" ");
  }
  feedgps();
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print(" **************");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz); //lcd.setCursor(0, 1); lcd.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  feedgps();
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  feedgps();
}

static bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}

```
