refreshing data from GPS shield problem

Hi all. I am using a dexter industries arduino shield on my duemilanove. For the time being i am just trying to acquire velocity. The problem i am having, is the arduino will display my current velocity for a short amount of time (1 second or so) then display zero knots/MPH for a longer period of time (5-10 seconds or so) and it just continues this loop. I believe the problem is i am not refreshing the GPS data properly but with the example code that was included with the library, i am having trouble figuring out how to do so.

here is the shield i have:
http://dexterindustries.com/Arduino-GPS_Shield.html

here is the library and examples:

Here is the code i am running:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address


#include "string.h"
#include "ctype.h"
#include "SoftwareSerial.h"
#include "dGPS.h"

// Software serial TX & RX Pins for the GPS module
// Initiate the software serial connection


float desLat=0;                   //Destination Latitude filled by user in Serial Monitor Box
float desLon=0;                   //Destination Longitude filled by user in Serial Monitor Box
dGPS dgps = dGPS();               // Construct dGPS class

float MPH = 0;
float KNOTS = 0;

void setup() 
{
  
  Serial.end();                  // Close any previously established connections
  Serial.begin(9600);            // Serial output back to computer.  On.
  dgps.init();                   // Run initialization routine for dGPS.
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Loading...");
  delay(1000);
    

}

void loop() 
{
                                                                                //[i]sounds simple enough but its not doing what this comment says[/i]
  dgps.update(desLat, desLon);                  // Calling this updates the GPS data.  The data in dGPS variables stays the same unless
                                                                                // this function is called.  When this function is called, the data is updated.
  
  Serial.print("Knots: ");
  Serial.print(dgps.Vel(), 6);                           // Velocity, in knots.
  
  KNOTS = dgps.Vel();
  MPH = (KNOTS)*1.15;                                
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("MPH: ");
  lcd.print(MPH);
  
  lcd.setCursor(0,1);
  lcd.print("Knots: ");
  lcd.print(dgps.Vel());
  delay(2000);                                  // i included this per dexter industries request, they seemed to think i was polling for data
}                                                             // faster than the gps module could supply. I didnt think that was the problem, but tried
                                                              // anyway. All it did was hold the current reading a little longer before reading zero again.

Thanks in advanced

The problem i am having, is the arduino will display my current velocity for a short amount of time (1 second or so) then display zero knots/MPH for a longer period of time (5-10 seconds or so) and it just continues this loop.

Is your GPS actually moving ?

GPS velocity calculations are not particularly reliable, particularly if you are moving slowly. The purpose of GPS is to determine your position. It can only estimate your velocity by interpolating between successive position estimates.

And please don't use upper case for variable names. It's confusing. Use upper case for #define values and similar things.

Thanks for the reply, yes my gps shield is moving (in a car) and when i get a reading it is very close to the car's speedometer at the time. However, for my project, i dont need a great deal of accuracy, i just need to know if the vehicle is moving over 10mph or not.

How are you actually connecting the arduino to the gps ?

michinyon:
How are you actually connecting the arduino to the gps ?

It is a shield, so its just stacked on the arduino headers. Its run using a software serial connection off pins 3 and 4

well I am expecting to see some sort of initialisation of the softwareserial somewhere, it must be buried in the library somewhere.

If it is telling you the correct velocity some of the time, then it is probably working.

Your expectations of how consistent the gps velocity calculations are, may be too great.

Assuming it is not obstructed, the gps should be recalculating its position every second, or more often. The website for your module suggests up to ten times a second. Your gps works in quite a different way to the way that nearly everybody else does it. I am not familiar with that library.

I would remove that delay(2000). That is stopping your arduino, and it is going to disrupt the process of the library code getting the data from the gps chip.

But without the delay, your loop() function will run too fast.

What you have to do, is print the data, then find the time now ( use millis() ), and then calculate the time 2000 ms into the future, and then let loop( ) run and run, and each cycle of loop, check millis again, until it reaches the time you calculated, and then print the data again. This will allow the dpgs object to update itself, but not try to print too much.

Thanks for the reply, I tried that and still couldnt figure it out. Its something in their library i believe. So i used the tinyGPS library that's floating around. Changed my software serial pins to 3 and 4 and baud to 9600 and got it up and running no problem :slight_smile:

It updates once a second, which is fine for what im doing, and reads within 1mph of my garmin gps. The speedo is broken in my car, so thats all i have to go off of .

So if anyone else is having the same issue with the dexter industries shield, download the tinyGPS library here:

-switch the software serial pins from (4,3) to (3,4)
-set softwareserial baud to 9600 instead of 4800

and this library will work with this shield.

heres what i added to the example code to print MPH to my 16x2 i2c LCD. I didnt bother deleting the extra code i wasnt using.

#include <SoftwareSerial.h>

#include <TinyGPS.h>
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



/* 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 4(rx) and 3(tx).
*/


float mph = 0;
float kmh = 0;

TinyGPS gps;
SoftwareSerial ss(3, 4);

static void smartdelay(unsigned long ms);
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);
  lcd.begin(16,2);
  
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  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("-------------------------------------------------------------------------------------------------------------------------------------");

  ss.begin(9600);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double 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, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 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);
  
  kmh = gps.f_speed_kmph();
  mph = kmh * .62;
  lcd.setCursor(1,0);
  lcd.print("MPH: ");
  lcd.print(mph,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 ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), 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();
  
  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

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

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

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] : ' ');
  smartdelay(0);
}