TinyGPS and hardware serial?

Hey, thanx. I should have realized that. But, for one run through of loop there will be valid data.

Good point. I'll have to rethink.

Sembazuru:

[quote author=Nick Gammon link=topic=174454.msg1295695#msg1295695 date=1372392589]
The way I read the library code, each time you call encode() you get back true or false. If true, the last character you supplied resulted in a valid fix. Then next time through the loop it won't be valid (it only just started a new sentence) and thus it will be false again. So when you get true you get "new information" when you get back false it is "nothing ready yet".

Hey, thanx. I should have realized that. But, for one run through of loop there will be valid data.

Good point. I'll have to rethink.
[/quote]

Actually, thinking about it, after one epoch (may be several sentences, depending on the configuration of the GPS) is read in, there will most likely be some quiet time from the GPS until the next sentence is started. That quiet time from the GPS will result in quite a few iterations through loop() where the flag will continue to be true. (It doesn't try to send anything to .encode() unless there is something available on the serial port.)

It would be an interesting experiment to pretend like the Serial Monitor is a GPS and feed it valid sentences (I've got a megabytes of them lying around my HDD from GPS testing at work), seeing if the return from .encode() goes back to false on subsequent sentences after 1 good one. Unfortunately I'm in the middle of a move and both my UNOs are packed. I probably wouldn't be able to run this test until after the 4th (and maybe not until the week after depending on how long it takes to unpack).

I don't think so, although I haven't tested it.

The thing that triggers the "line complete" (eg. newline character) means that it resets its internal state to "start of new line". It doesn't require a new (additional) character to do that, just the final one from the old line.

Docedison:
There is another issue it can take up to 10 minutes depending on location, GPS doesn't work indoors as well as outside with a clear view of the sky. It can take as much as 10 minutes to update the ephemeris in the GPS receiver so seeing no data usually means not enough data yet for a position fix .

Such is the expected effect of working with GPS devices. Most modern GPSs will hold on to the ephemeris data until it expires, and continually refreshes it while in operation. So, once you get one good fix, reacquisition is relatively quick unless the GPS has been off for a while or has moved several miles while off. (I forget off the top of my head how long and/or how far the limits are while off. Could be different depending on the GPS device.) That said, I haven't looked at the datasheet for the AdaFruit Ultimate GPS to see how it handles reacquisition on bootup.

I use GPS receivers for time standards in several of my projects along with the Time Library... The TimeGPS sketch doesn't work though. I had a friend re-write it so that it works
Mikal Harts TinyGPS12 has a sketch called test_with_gps_device.pde and I've attached it. I didn't make the changes for a Mega's serial ports however. It is really trivial. The sketch works well and was a big part of the re-written TimeGPS sketch. I know the sketch works, I've used it many times in learning about GPS receivers. I also added a windows program that will display GPS data from a GPS receiver connected to a computer via an USB to TTL serial adapter.
The U-Center software is available as a free download from the U-Blox website and it's data display is really interesting. Also to give you an idea of how well your device is working.

Doc

Nifty, I'll have to check out that windows program at some point. I'll see how it compares to Ashtech Evaluate.

Sembazuru:

RudiAhlers:
Thanx, I understand what you're saying (and what PaulS said), but how do I configure the Arduino to get the data in on pins 16 & 17?

I'm not trying to be unkind, but I don't think you are understanding what PaulS and I are saying. I don't have a Mega, but aren't pins 16 & 17 Serial2? Access Serial2 just like any other serial device.

Looking at other GPS libraries, I see some use "Adafruit_GPS GPS(&Serial2);" to tell the Arduino where the GPS data comes from.

But the difference here is TinyGPS doesn't access any external ports. You have to do that yourself in your code. So you would do a Serial2.read() to a buffer variable (datatype char or larger) and then pass that variable to TinyGPS's method .encode(). Keep doing this until the .encode() method returns a true. You have to do the communication with the GPS device yourself in your sketch. I suppose you could skip the buffer variable entirely by putting the serial read inside the method, but then it would probably be best to use a flag variable for the return of the encode method.

Something like (untested code here, I have neither a Mega nor a GPS shield):

#include <TinyGPS.h>

TinyGPS gps;
boolean validGPS = false;

void setup()
{
  Serial2.begin(9600); // or what ever the GPS's baudrate is
}

void loop()
{
  if (Serial2.available())
  {
    validGPS = gps.encode(Serial2.read());
  }
  if (validGPS)
  {
    // TinyGPS has told us we have received a valid GPS fix. We can now query it for position/course/time/etc. information.
  }
}




Note, even with a good GPS fix, it will take several loops through loop() to fetch a full NMEA sentence. This is good because it allows the sketch to do OtherThings<sup>tm</sup> while it waits for GPS fix. An example of non-blocking code. ;)



> I'm using a SIM900 GSM shield on Serial1, and had to "hard code" the Serial1 interface in the GSM.cpp file. The developer has given some clear instructions on how to do that, but I can't figure out how to do something similar with TinyGPS. 
> 
> I'm using a MEGA 2560, with a Adafruit Ultimate GPS breakout V3 on Serial2, and a IComsat GMS shield on Serial1



As long as the GPS unit on the Adafruit breakout sends standard $GPRMC and/or $GPGGA sentences, it should work with TinyGPS. (I expect that it does, but may need some configuration first. I really don't know it's default state.)

Don't forget to test where the GPS can actually get a fix. TinyGPS ignores NMEA sentences that don't indicate a fix. (i.e. even if the NMEA sentence is properly formed, if the GPS is reporting in those sentences that there is no GPS fix then TinyGPS will ignore that sentence. If it's important to your project, don't forget to keep an eye on fix_age.

Thank you. I suspect there's a problem somewhere but don't yet know what / where. As a test, I connected the GPS (Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates [PA1616S] : ID 746 : $29.95 : Adafruit Industries, Unique & fun DIY electronics and kits) to an Arduino NANO, on ports RX0 and TX0, and also 2 & 3 (D2 & D3?), and tried the sample code from the TinyGPS V12 zip file.
This didn't give me any output on the Serial Monitor either.

There's an "Active Antenna" (GPS Antenna - External Active Antenna - 3-5V 28dB 5 Meter SMA : ID 960 : $19.95 : Adafruit Industries, Unique & fun DIY electronics and kits) connected to it which is outside, and has been outside for a few days now. The backup battery is also in place.

The following sketch does give some output, but there's no output when trying the TinyGPS examples.

void setup(){}
void loop(){}

Here's the output from the Serial Monitor:

$GPRMC,082757.000,A,2615.xx40,S,02819.xx56,E,0.01,205.46,xx0613,,,A78
$GPRMC,082758.000,A,2615.xx40,S,02819.xx56,E,0.00,205.46,xx0613,,,A
76
$GPRMC,082759.000,A,2615.xx40,S,02819.xx56,E,0.02,205.46,xx0613,,,A75
$GPRMC,082800.000,A,2615.xx40,S,02819.xx56,E,0.01,205.46,xx0613,,,A
75
$GPRMC,082801.000,A,2615.xx40,S,02819.xx56,E,0.01,205.46,xx0613,,,A*74

P.S. I put the "xx" in for privacy reasons.

Docedison:
There is another issue it can take up to 10 minutes depending on location, GPS doesn't work indoors as well as outside with a clear view of the sky. It can take as much as 10 minutes to update the ephemeris in the GPS receiver so seeing no data usually means not enough data yet for a position fix . I use GPS receivers for time standards in several of my projects along with the Time Library... The TimeGPS sketch doesn't work though. I had a friend re-write it so that it works
Mikal Harts TinyGPS12 has a sketch called test_with_gps_device.pde and I've attached it. I didn't make the changes for a Mega's serial ports however. It is really trivial. The sketch works well and was a big part of the re-written TimeGPS sketch. I know the sketch works, I've used it many times in learning about GPS receivers. I also added a windows program that will display GPS data from a GPS receiver connected to a computer via an USB to TTL serial adapter.
The U-Center software is available as a free download from the U-Blox website and it's data display is really interesting. Also to give you an idea of how well your device is working.

Doc

I ran the attached sketch, modified to use Pins 10 & 11 (with Softserial) for about 40 minutes now and still don't get any GPS data on the Serial Monitor.
The "Fix" LED blinks very slowly, which means it has a fix (according to the documentation).

This is the output on the Serial Monitor:

**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90138 0 3003
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90197 0 3091
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90255 0 3179
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90313 0 3255
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90372 0 3325
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90430 0 3401
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 90489 0 3494

I ran the attached sketch, modified to use Pins 10 & 11 (with Softserial) for about 40 minutes now and still don't get any GPS data on the Serial Monitor.

Post a picture of how the GPS IS connected.

Stop using SoftwareSerial when you have 4 hardware serial ports on the Mega.

SoftwareSerial was also a cause for consternation in my project as well as it Will drop or mangle a character once in a while. When I switched to a Mega most problems went away. Is it possible that you have RX connected to RX and TX connected to...? That will also give you the results you report. GPS_RX must connect to Mega_TX and GPS_TX must connect to Mega_RX. Where Mega_RX is serial1,2,3 same for TX.
There is a serial0 but that is also the data connection to the usb converter and as such restricted to talking to the serial monitor or programming via the bootloader.
If you need it I can modify the two or three places where serial is mentioned in the sketch I did and enclosed it. It's untested both my Mega's are busy but the changes are just to assign serial data to a specific hardware port instead of an object.
One last thing, Verify both GPS connections and speed. The Ucenter thing comes with instructions, You can get them from the U-Blox webpage.

Doc

Mega_test_with_gps_device.ino (5.22 KB)

PaulS:

I ran the attached sketch, modified to use Pins 10 & 11 (with Softserial) for about 40 minutes now and still don't get any GPS data on the Serial Monitor.

Post a picture of how the GPS IS connected.

Stop using SoftwareSerial when you have 4 hardware serial ports on the Mega.

I'm trying to simplify things to make sure the GPS is working and responding properly. Right now I have the GPS connected to a NANO, with the GPS's RX going to D3 and TX going to D2, using the following sketch:

#include <SoftwareSerial.h>

#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
 4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
 */

TinyGPS gps;
SoftwareSerial nss(2, 3);

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(4800);

  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("--------------------------------------------------------------------------------------------------------------------------------------");
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every second we print an update
  while (millis() - start < 1000)
  {
    if (feedgps())
      newdata = true;
  }

  gpsdump(gps);
}

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;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  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);
  }
  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;
}

The output is still the same:

**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4374 0 715
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4455 0 728
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4536 0 741
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4617 0 753
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4698 0 767
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4779 0 781
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4860 0 795
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 4941 0 810
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 5022 0 825

Swapping the RX & TX pins around doesn't help either.

I'm trying to simplify things to make sure the GPS is working and responding properly. Right now I have the GPS connected to a NANO, with the GPS's RX going to D3 and TX going to D2, using the following sketch:

Possibly a dumb question, but you also connected ground, right?

PaulS:

I'm trying to simplify things to make sure the GPS is working and responding properly. Right now I have the GPS connected to a NANO, with the GPS's RX going to D3 and TX going to D2, using the following sketch:

Possibly a dumb question, but you also connected ground, right?

Yes, it's grounded.

The NANO is in a breaboard and "share" the side power rails with the GPS. i.e. there's a black cable coming from GND on the GPS to the blue line in the breadboard, and a jumper to the nano's GND pin. A red wire is connected from the GPS's VIN pin to the red line in the breadboard, and a jumper to the NANO's 5V pin.
Then I have a black wire coming from the GPS's RX pin, into the NANO's D3 pin, and a green wire from the GPS's TX pin to the Nano's D2 pin

Another dumb question, you have verified that your sketches are using the correct baud rate for how your GPS module is configured?

Sembazuru:
Another dumb question, you have verified that your sketches are using the correct baud rate for how your GPS module is configured?

Thanx, this solved the puzzle!
I honestly didn't look into that, since most examples use 115200. This GPS's baud rate is 9600 (took some google searching to find it). And it's working fine now, thank you :slight_smile:

hai
I am using arduino mega.. I downloaded and paste the tinygps library in arduino library folder.but when programming the tinygps header file is not highlighted...is there any way...??

is there any way

The syntax color means nothing. It is what the compiler says that matters.

thanq for the reply

but it shows "tinygps. .there is no file or directory "like errors

but it shows "tinygps. .there is no file or directory "like errors

We don't deal with paraphrased error messages. They are text. Text can be copied and pasted, really easily.

It sounds, though, like you have not downloaded and properly installed the TinyGPS (or TinyGPS++) library.

thanq for ur reply..
After i reinstalled the library its shows an error that"no known conversion for arguments 1 from to char..

RudiAhlers:
Thanx, this solved the puzzle!
I honestly didn't look into that, since most examples use 115200. This GPS's baud rate is 9600 (took some google searching to find it). And it's working fine now, thank you :slight_smile:

Hi i have similar issue of what you encountered, so far there is no luck in resolving.

I'm using a GPS Module Sklab skg13bl + Arduino Uno board

skg13bl has a TTL pins i'm using those to get the TX and RX and connected to D2 & D3 of Arduino uno also the 3rd pin on GND is connected to Arudino GND.

i could see the gps receiver receiving signals, green lights starts blinking after the gps fix.

but i get the same data,

**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 74253 0 16
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 74645 0 16
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 74922 0 16
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 75147 0 16
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 75542 0 16
**** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 75822 0 16

akku_123:
thanq for ur reply..
After i reinstalled the library its shows an error that"no known conversion for arguments 1 from to char..

It shows the line number in the code that you didn't post that generated the error, too.

Show ALL of your code and ALL of the error message(s).