Go Down

Topic: has anyone succeeded with timeGPS from time library? (Read 2637 times) previous topic - next topic

ninja2

Dec 03, 2011, 12:58 am Last Edit: Dec 03, 2011, 01:04 am by ninja2 Reason: 1
I have a working Arduino Mega with LS00031 GPS that reports location and GPS time just fine, using tinyGPS.

I needed to convert UTC time from the GPS to local time, and the timeGPS example in the IDE seemed to offer exactly this, using functions and time_t from the time library. But it does not work for me so far, continually reporting the same time when I start it (7:37:12 8 Jan 2000 from memory) and incrementing the seconds from there.

Search reveals a few other people have had problems with timeGPS example.

Has anyone out there succeeded in getting timeGPS to work in this way?

Here's my code, main difference to timeGPS is I'm using Serial2 instead of softserial, plus I've added some reporting to try and debug the problem. It seems the GPS is not communicating over Serial2 because fix_age is reporting as a huge number. But Serial2 from GPS works fine in my other program
Quote

// based on TimeGPS.pde example

#define CJ_ID "CJ UTCa"

#include <Time.h>
#include <TinyGPS.h>

//#include <NewSoftHOST.h>  //http://arduiniana.org/libraries/newsoftserial/
// GPS and NewSoftSerial libraries are the work of Mikal Hart

#define HOST  Serial
#define HOST_BAUD_RATE 38400

#define GPS  Serial2
#define GPS_BAUD_RATE 57600

TinyGPS gps;
//NewSoftSerial GPS =  NewSoftSerial(3, 2);  // receive on pin 3

const int offset = 0;   // offset hours from gps time (UTC)
//const float offset = 10.5;   // offset hours from gps time (UTC)
time_t prevDisplay = 0; // when the digital clock was displayed

void setup()
{
 HOST.begin(HOST_BAUD_RATE);
 HOST.println(CJ_ID);
 GPS.begin(GPS_BAUD_RATE);
 HOST.println("Waiting for GPS time ... ");
 setSyncProvider(gpsTimeSync);
}

void loop() {
 processGpsBuffer();
 //while (GPS.available()) {gps.encode(GPS.read());} // process gps messages
 //if(timeStatus()!= timeNotSet)
 if(timeStatus()== timeSet)
   {if( now() != prevDisplay) //update the display only if the time has changed
      {prevDisplay = now();
       digitalClockDisplay();}
    }
 else
   {HOST.print("timeStatus: "); HOST.println(timeStatus());}
 delay(1000);  
 }

void digitalClockDisplay(){
 // digital clock display of the time
 HOST.print(hour());
 printDigits(minute());
 printDigits(second());
 HOST.print(" ");
 HOST.print(day());
 HOST.print(" ");
 HOST.print(month());
 HOST.print(" ");
 HOST.print(year());
 HOST.println();
}

void printDigits(int digits){
 // utility function for digital clock display: prints preceding colon and leading 0
 HOST.print(":");
 if(digits < 10)
   HOST.print('0');
 HOST.print(digits);
}

time_t gpsTimeSync(){
 //  returns time if avail from gps, else returns 0
 unsigned long fix_age = 0 ;
 gps.get_datetime(NULL,NULL, &fix_age);
 HOST.print("  Fix age: "); HOST.print(fix_age); HOST.println(" ms");
 unsigned long time_since_last_fix;
 return gpsTimeToArduinoTime(); // return time only if updated recently by gps  
//  if(fix_age < 1000)
//    return gpsTimeToArduinoTime(); // return time only if updated recently by gps  
//  return 0;
}

time_t gpsTimeToArduinoTime(){
 // returns time_t from gps date and time with the given offset hours
 tmElements_t tm;
 int year;
 gps.crack_datetime(&year, &tm.Month, &tm.Day, &tm.Hour, &tm.Minute, &tm.Second, NULL, NULL);
 tm.Year = year - 1970;
 time_t time = makeTime(tm);
 return time + (offset * SECS_PER_HOUR);
}

// processGpsBuffer. get characters from the GPS serial buffer and pass them to the gps object
bool processGpsBuffer(){
 while (GPS.available())
   {if (gps.encode(GPS.read())) return true;}
 return false;}





PaulS

Code: [Select]
  HOST.println("Waiting for GPS time ... ");
  setSyncProvider(gpsTimeSync);

The message being printed is wrong. The setSyncProvider() function does not force a sync. It simply defines the function to call when a sync is needed.

Quote
I have a working Arduino Mega with LS00031 GPS that reports location and GPS time just fine, using tinyGPS.

Does this code return GPS date and time correctly? Perhaps it's just that fix_age is not being computed correctly.

ninja2


The message being printed is wrong.

yes thanks, I wrote that some weeks back, when I knew lots less !

yes I have the GPS returning date and time coreectly with another program not using Time library and I'm trying to move to Time library as much as possible as I'll use much of it's functionality for sure.

I'm not sure if fix_age being wrong is the problem, or just a symptom. And even in my other working program fix_age is weird until GPS syncs up. The same issue is discussed on page 3 of this thread:
http://arduino.cc/forum/index.php/topic,66054.msg615299.html#msg615299

PaulS

Quote
And even in my other working program fix_age is weird until GPS syncs up.

Well, that is to be expected. Until the GPS is getting good data, it will hardly associate a valid date and time to the data. Without a valid date and time, the fix_age calculation will not be accurate.


ninja2

sure, but the elephant in the room is the question of whether fix_age is the problem or a symptom of the failure to sync

Docedison

The fix_age calculation is bad... A friend wrote a working version for me and I can post it but there's a lot of extra stuff about Temp, RH and Barometric pressure using a DHT22 and a BMP085 and it drives a 320 X 240 line GLCD with the UTFT library on a Mega 2560...

Doc
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

ghlawrence2000

Code: [Select]
//------------------------------------------------------------------------------
void serialEvent2() {
  unsigned long date,time, fix_age;
  while (Serial2.available()) {
    gps.encode(Serial2.read());
  }
  gps.get_datetime(&date, &time, &fix_age);
  if (fix_age>1000) {
    gpsfix=false;
    digitalWrite(led, LOW);
  }
  else {
    digitalWrite(led, HIGH);
    gpsfix=true;
  }
}
// /////////////////////////////////////////////////////////////////////////////


Works for me, fix_age is typically 200-300 worst I have seen is about 600.

Regards,

Graham


Docedison

Nice looking fragment.. IT fits in this? :
Code: [Select]
/*
* TimeGPS.pde
* example code illustrating time synced from a GPS
*
*/

#include <Time.h>
#include <TinyGPS.h>       //http://arduiniana.org/libraries/TinyGPS/
#include <NewSoftSerial.h>  //http://arduiniana.org/libraries/newsoftserial/
// GPS and NewSoftSerial libraries are the work of Mikal Hart

TinyGPS gps;
NewSoftSerial serial_gps =  NewSoftSerial(3, 2);  // receive on pin 3

const int offset = 1;   // offset hours from gps time (UTC)
time_t prevDisplay = 0; // when the digital clock was displayed

void setup()
{
  Serial.begin(9600);
  serial_gps.begin(4800);
  Serial.println("Waiting for GPS time ... ");
  setSyncProvider(gpsTimeSync);
}

void loop()
{
  while (serial_gps.available())
  {
    gps.encode(serial_gps.read()); // process gps messages
  }
  if(timeStatus()!= timeNotSet)
  {
     if( now() != prevDisplay) //update the display only if the time has changed
     {
       prevDisplay = now();
       digitalClockDisplay(); 
     }
  }
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
/*------------------------------(This was the bad... but the real error is elsewhere (.h or .cpp?)---------------------*/
/*----------------------------------(Is this what your code fragment replaces...?)-------------------------*/
time_t gpsTimeSync(){
  //  returns time if avail from gps, else returns 0
  unsigned long fix_age = 0 ;
  gps.get_datetime(NULL,NULL, &fix_age);
  unsigned long time_since_last_fix;
  if(fix_age < 1000)
    return gpsTimeToArduinoTime(); // return time only if updated recently by gps 
  return 0;
}

time_t gpsTimeToArduinoTime(){
  // returns time_t from gps date and time with the given offset hours
  tmElements_t tm;
  int year;
  gps.crack_datetime(&year, &tm.Month, &tm.Day, &tm.Hour, &tm.Minute, &tm.Second, NULL, NULL);
  tm.Year = year - 1970;
  time_t time = makeTime(tm);
  return time + (offset * SECS_PER_HOUR);
}


Doc
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

ghlawrence2000

#9
Sep 26, 2013, 02:28 am Last Edit: Sep 26, 2013, 02:41 am by ghlawrence2000 Reason: 1
oops, not exactly!! Sorry...

However, give this a whirl?

Code: [Select]
/*
* TimeGPS.pde
* example code illustrating time synced from a GPS
*
*/

#include <Time.h>
#include <TinyGPS.h>       //http://arduiniana.org/libraries/TinyGPS/
//#include <NewSoftSerial.h>  //http://arduiniana.org/libraries/newsoftserial/
#include <HardwareSerial.h>

// GPS and NewSoftSerial libraries are the work of Mikal Hart

TinyGPS gps;
#define serial_gps Serial2

const int offset = 1;   // offset hours from gps time (UTC)
time_t prevDisplay = 0; // when the digital clock was displayed

//------------------------------------------------------------------------------
void serialEvent2() {
 while (serial_gps.available()) {
   gps.encode(serial_gps.read());
 }
}
// /////////////////////////////////////////////////////////////////////////////

void setup()
{
 Serial.begin(9600);
 serial_gps.begin(4800);
 Serial.println("Waiting for GPS time ... ");
 setSyncProvider(getTimeFunction);
 setSyncInterval(120); // Get time every 2 minutes
}

void loop()
{
 if(timeStatus()!= timeNotSet)
 {
   if( now() != prevDisplay) //update the display only if the time has changed
   {
     prevDisplay = now();
     digitalClockDisplay();  
   }
 }
 else
 {
   getTimeFunction();
 }
}

void digitalClockDisplay(){
 // digital clock display of the time
 Serial.print(hour());
 printDigits(minute());
 printDigits(second());
 Serial.print(" ");
 Serial.print(day());
 Serial.print(" ");
 Serial.print(month());
 Serial.print(" ");
 Serial.print(year());
 Serial.println();
}

void printDigits(int digits){
 // utility function for digital clock display: prints preceding colon and leading 0
 Serial.print(":");
 if(digits < 10)
   Serial.print('0');
 Serial.print(digits);
}

time_t getTimeFunction()
{
 unsigned long age;
 int Year;
 byte Month, Day, Hour, Minute, Second;
 gps.crack_datetime(&Year, &Month, &Day, &Hour, &Minute, &Second, NULL, &age);
 Serial.println(age);
 if (age < 200) {
   // set the Time to the latest GPS reading if less then 0.2 seconds old
   setTime(Hour, Minute, Second, Day, Month, Year);
   adjustTime(offset * SECS_PER_HOUR);
   return now();
 }
 else return 0;
}


Typical serial monitor output for me looks like this.....

Code: [Select]
4294967295
4294967295
4294967295
4294967295
4294967295
112
117
122
128
133
138
143
148
154
159
164
169
174
180
185
190
195
200
1:22:30 26 9 2013
1:22:31 26 9 2013


Hope this helps

Graham

Go Up