SparkFun Forums 

Where electronics enthusiasts find answers.

Tips and questions relating to the GPS modules from SFE
By D9W
#154816
Hi,
Just wanted to pass this on for those who really want to see all the outputs of their LS20031.
I know this is over kill, but if you really want to see what your GPS can spit out try this.

As I have been pointing out elsewhere, you will need some form of Voltage Logic Converter between your GPS and your Arduino.
Sparkfun has a few Logic converters. But I seem to have the gift of static and killed the ones I had. But the one in the sketch from dsscircuits.com { http://www.dsscircuits.com/i2c-level-converter.html }
I have done my level best to kill it, but it's still working despite my best efforts. It's so easy to wire you don't really have to think about it when you do it (it also does voltage conversion for I2C). Also the TXS-0102 uses one-shots which means your 5V side sees cleaner output- no voltage dips or spikes to confuse your Arduino- and you don't have to use pesky pull-up resistors which causes other problems (see dsscircuits.com explanation{ http://www.dsscircuits.com/articles/eff ... stors.html }) .

If you have questions about wiring see >> http://www.dsscircuits.com/images/schem ... Wiring.pdf

Also, if you try the PMTK_SET_NMEA_OUTPUT_ALLDATA2 you’re going to want to wire it like in the Sparkfun Tutorial’s QUICK TEST { http://www.sparkfun.com/tutorials/176 }. You will want to use the SECOND PROGRAM with this and you will want to REM (//) out everything to do with SoftwareSerial. IF you have the datasheet for your LS20031 Ver 1.3 don’t be surprised that not everything that get’s output is in the datasheet. That’s why I added all the comments. Also, I have no clue as to what the PMTK_Q_RELEASE output means.

And YES- there are two version of the loop. One needs to be REM-ed out for it to work correctly. Again this is AS-IS, this sketch is for you to play with. Just be WARNED that if you change the baud rate, you could get yourself into a headache, and I am not responsible to get you out of it. It took me three hours to get the Arduino IDE back talking correctly to the GPS. You were WARNED- Do one thing at a time.

The First Program in the loop does need SoftwareSerial so you will need to remove all the // that has to do with SoftwareSerial, and it just there to let you see that TinyGPS does work.
Code: Select all
/*
Purpose of this sketch(program) is to test communications between LS20031 and the Arduino UNO.
 Note: Not sure as to why but sometimes it takes unplugging the Uno from power supply and USB cable to get correct results.
       Also circuit diagram represents what get's grouped together, not actual diagram.
       
       Plus, 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
            
The LS20031 circuit:
  • GPS Pin 5 :(left-most when viewed from above) : No connection (or ground)
  • GPS Pin 4 : to Arduino ground (GND) pin
  • GPS Pin 3 TX : to Logic Converter 2L
  • GPS Pin 2 RX : to Logic Converter 1L
  • GPS Pin 1 :(right-most when viewed from above) to Arduino 3.3V pin

The Logic Level Converter: (from DSSCircutis.com -I2C Level Converter- YES! it does UART (Push Pull) communications AND No need for external pullup resistors! -if you use this one!) 
 See Text on Logic Level Converter break out board to identify correct pin. Datasheet for TXS0102 >> http://dsscircuits.com/i2c-level-converter.html
  • GND  Pin to : Arduino ground (GND) pin
  • 1H   Pin to : Digital Pin 4 on Arduino
  • 2H   Pin to : Digital Pin 3 on Arduino
  • VccH Pin to : Arduino 5V Pin

  • VccL Pin to : Arduino 3.3V pin
  • 1L   Pin to : LS0031 RX pin 2 (Viewing from right to left see- http://www.sparkfun.com/tutorial/AG_LS20031_GPS/ls20031_annotated_pins_normal.jpg ) 
  • 2L   Pin to:  LS0021 TX pin 3 (Viewing from right to left)
  • OE   Pin to : Arduino 5V Pin
  
The Pins used on the Arduino UNO: 
  • RX is digital pin 4 (connect to TX of other device)
  • TX is digital pin 3 (connect to RX of other device)

 The template for this sketch came from >>
   SoftwareSerialExample by Tom Igoe
   based on Mikal Hart's example
   And modified by Blacklab1 1/08/2013.
 
 Note: Ideas for this sketch comes from Wayneholder - https://sites.google.com/site/wayneholder/
       and LadyAda web Tutorial >> http://learn.adafruit.com/adafruit-ultimate-gps/overview
       Thank you both for your hard work.
 This example code is in the public domain.
 */
#include <TinyGPS.h>
// different commands to set the update rate from once a second (1 Hz) to 10 times a second (10Hz)
#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>
   Flag: '0' = Invalid Packet
         '1' = Unsupported packedt type
         '2' = Valid packet, but action failed
         '3' = Valid packet, and action succeeded
*/

#define PMTK_SET_BAUD_115200 "$PMTK251,115200*1F\r\n" // dont mess with any of these unless you know what your doing
#define PMTK_SET_BAUD_57600  "$PMTK251,57600*2C\r\n"  // if you do change these you have to use the last working baud rate 
#define PMTK_SET_BAUD_9600   "$PMTK251,9600*17\r\n"   // to communicate with LS20031 then change back to desired setting
#define PMTK_SET_BAUD_4800   "$PMTK251,4800*14\r\n"   //

#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_ALLDATA2  "$PMTK314,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1*29\r\n" //
#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
  
  LS20031 uses the following Protocall >> GLL, RMC, VTG, GGA, GSA, GSV, ZDA supported NMEA messages
  
  Location:             Decription:
      0  NMEA_SEN_GLL,   // GPGLL interval - Geographic Position - Latitude longitude    
      1  NMEA_SEN_RMC,   // GPRMC interval - Recommended Minimum Specific GNSS Sentence
      2  NMEA_SEN_VTG,   // GPVTG interval - Course Over Ground and Ground Speed
      3  NMEA_SEN_GGA,   // GPGGA interval - GPS Fix Data
      4  NMEA_SEN_GSA,   // GPGSA interval - GNSS DOPS and Active Satellites
      5  NMEA_SEN_GSV,   // GPGSV interval - GNSS Satellites in View
      6  NMEA_SEN_GRS,   // GPGRS interval - GNSS Range Residuals
      7  NMEA_SEN_GST,   // GPGST interval - GNSS Pseudorange Errors Statistics
      13 NMEA_SEN_MALM, // PMTKALM interval - GPS almanac information
      14 NMEA_SEN_MEPH, // PMTKEPH interval - GPS ephmeris information
      15 NMEA_SEN_MDGP, // PMTKDGP interval - GPS differential correction information
      16 NMEA_SEN_MDBG, // PMTKDBG interval – MTK debug information
      17 NMEA_Sen_ZDA,  // ZDA - Date & time -- $GPZDA,hhmmss.ss,xx,xx,xxxx,xx,xx See  http://aprs.gids.nl/nmea/ >> Note: LS20031 seems not to know TimeZones.
                                                hhmmss.ss = UTC 
                                                xx = Day, 01 to 31
                                                xx = Month, 01 to 12
                                                xxxx = Year
                                                xx = Local zone description, 00 to +/- 13 hours
                                                xx = Local zone minutes description (same sign as hours) 
      18 NMEA_SEN_MCHN, // PMTKCHN interval – GPS channel status ---- info here >> http://snoob-community.wikispaces.com/PMTKCHN
                           decoding >>  $PMTKCHN,aabbc,...*XX\r\n
                                                 aa => SVid: Space Vehicle Id
                                                   bb => SNR: Signal to Noise Ratio
                                                     c => Status:
                                                          • 0 == Idle
                                                          • 1 == Searching
                                                          • 2 == Tracking
                                                          
  Example location:  0,1,2,3,4,5, , , , , , , , , , , ,17,18*??\r\n" for the LS20031
           "$PMTK314,0,1,0,1,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0*2C\r\n" --- MTK NMEA checksum calculator -> http://www.hhhh.org/wiml/proj/nmeaxor.html
          Supported Frequency Setting
                  0 - Disabled or not supported sentence
                  1 - Output once every one position fix
                  2 - Output once every two position fixes
                  3 - Output once every three position fixes
                  4 - Output once every four position fixes
                  5 - Output once every five position fixes
           You can also restore the system default setting via issue: "$PMTK314,-1*04\r\n"
   */

#define PMTK_SET_SABS_INTERGITY_ON   "$PMTK319,1*24\r\n" //
#define PMTK_SET_SBAS_TEST_ON        "$PMTK319,0*25\r\n" //
#define PMTK_SET_WAAS_ENABLE         "$PMTK313,1*2E\r\n" // Enable to search a SBAS satellite--tells the receiver to search for a satellite that supports the Satellite-Based Augmentation System(SBAS)
#define PMTK_SET_WAAS_DISABLE        "$PMTK313,0*2F\r\n" // Disable SBAS satellite
#define PMTK_SET_DGPS_SBAS_ON        "$PMTK301,2*2E\r\n" // Enable WAAS as DGPS Source-- enables the receiver to use this information to correct the GPS fix into a DGPS fix.
                                                         // '0': No DGPS source
                                                         // '1': RTCM
                                                         // '2': 'WAAS'
/*  Note from Wayneholds web site:
    There are some fine points here, too:
      •Some receivers, such as those based on the MediaTek chip set can only make use of the WAAS correction information if the receiver is set to an update rate of 5 Hz, or less.  
          I found this tidbit buried inside a spec sheet after spending countless hours trying to figure out why I could not get a DGPS lock at the 10 Hz rate one of my receivers is capable of working at. 
      •Some receivers, such as ones based on the SkyTraq Venus chip set require that commands be send in a binary format rather than a text-based format.
   Therefore, I strongly recommend that you spend some time getting familiar with the specifications and features available for your GPS module and that you experiment with, 
   and test your receiver before you dismiss it as defective, as I did initially.  Hopefully, much of what I explaining in this section will be applicable to you, but your mileage may still vary.
*/
#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  
  */
 
#include <SoftwareSerial.h>
#define RxPIN 3
#define TxPIN 4
TinyGPS gps;
SoftwareSerial GpsSerial(RxPIN, TxPIN); 

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  Serial.println("Start");
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.println("Goodnight moon!");
  
  // set the data rate for the SoftwareSerial port
  // 9600 NMEA is the default baud rate for MTK - some use 4800
  // LS20031 uses 57600
  GpsSerial.begin(57600); //Adafruit- 9600, Sparkfun- 57600
  
  GpsSerial.print(PMTK_SET_NMEA_OUTPUT_ALLDATA2); // $GPxxx Messages
  GpsSerial.print(PMTK_SET_NMEA_UPDATE_1HZ);     // messages 1 times a second
  GpsSerial.print(PMTK_Q_RELEASE);
      
}

void loop(){ // run over and over
     // FIRST PROGRAM -----------------------
     /*while (GpsSerial.available()){ 
       unsigned char cc = GpsSerial.read();
       if (gps.encode(cc)) {
          float flat, flon;
          unsigned long age;
          gps.f_get_position(&flat, &flon, &age);
          Serial.print("Lat: ");
          Serial.print(flat);
          Serial.print(", Long: ");
          Serial.print(flon);
          Serial.print(", age: ");
          Serial.println(age);
      }
   }*/
   // SECOND PROGRAM ---------------------
   if (GpsSerial.available())
    Serial.write(GpsSerial.read());
   if (Serial.available())
    GpsSerial.write(Serial.read());
   
}