Need help with TinyGPS

Hi there its me again with still my reverse geocache project. This time I would like to add an additional feature. I want a comparison between the current date and a preset date. If it is in the future, I would like to display the remaining days. Sofern far I added crack_time and was able to display the current date, but I was not able to show the remaining days. Sometimes it also shows 01/01/2000 which I guess is due to an old gps age?

I am also not sure if I used the right format for my DATE_TO_START. According to the TinyGPS Library it is ddmmyyyy.

Hope you guys can help me again as you did with my previous noob questions.

My changes are highlighted in bold:

#include <PWMServo.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>

// -------------------------------------------------------------------
static const int   SERVO_CLOSED_ANGLE = 90;    // degrees (0-180)
static const int   SERVO_OPEN_ANGLE = 165;     // degrees (0-180)
static const float DEST_LATITUDE = 47.000000;  // degrees (-90 to 90)
static const float DEST_LONGITUDE = 9.000000; // degrees (-180 to 180)
static const int   RADIUS = 500;              // meters
static const int DEF_ATTEMPT_MAX = 50;
[b]static const int DATE_TO_START = 25012021;   // date to start ddmmyyyy[/b]

// -------------------------------------------------------------------

/* Fixed values should not need changing */
static const int EEPROM_OFFSET = 100;
static const int   LCD_CONTRAST = 20;          // (0-255)

/* Pin assignments */
static const int GPS_RX_PIN = 4, GPS_TX_PIN = 3; // GPS
static const int LCD_ENABLE_PIN = 7, LCD_RS_PIN = 5, LCD_RW_PIN = 8; // LCD
static const int LCD_DB4_PIN = 14, LCD_DB5_PIN = 15, LCD_DB6_PIN = 16, LCD_DB7_PIN = 17;
static const int LCD_CONTRAST_PIN = 6; 
static const int POLOLU_SWITCH_PIN = 12; // Pololu switch control
static const int SERVO_CONTROL_PIN = 9; // Servo control
static const int LED_PIN = 2; // The button LED
static const int PIEZO_PIN = 11; // Piezo buzzer outlet

/* The basic objects needed */
static SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
static LiquidCrystal lcd(LCD_RS_PIN, LCD_RW_PIN, LCD_ENABLE_PIN, LCD_DB4_PIN, LCD_DB5_PIN, LCD_DB6_PIN, LCD_DB7_PIN);
static TinyGPS tinyGps; 
static int attemptCounter;
static PWMServo servo;

/* The Arduino setup() function */
void setup()
{
  /* Uncomment this code if you want to reset the attempt counter. */
  /*
    EEPROM.write(EEPROM_OFFSET, 0);
    exit(0);
  */

  /* First, make sure Pololu switch pin is OUTPUT and LOW */
  pinMode(POLOLU_SWITCH_PIN, OUTPUT);
  digitalWrite(POLOLU_SWITCH_PIN, LOW);

  /* attach servo motor */
  servo.attach(SERVO_CONTROL_PIN);

  /* establish a debug session with a host computer */
  Serial.begin(115200);

  /* establish communications with the GPS module */
  ss.begin(4800);

  /* set the LCD contrast value */
  pinMode(LCD_CONTRAST_PIN, OUTPUT);
  analogWrite(LCD_CONTRAST_PIN, LCD_CONTRAST);

  /* establish communication with 8x2 LCD */
  lcd.begin(8, 2); // this for an 8x2 LCD -- adjust as needed 
  
  /* turn on the LED in the button */
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  /* make sure motorized latch is closed */
  servo.write(SERVO_CLOSED_ANGLE); 
  
  /* read the attempt counter from the EEPROM */
  attemptCounter = EEPROM.read(EEPROM_OFFSET);
  if (attemptCounter == 0xFF) // brand new EEPROM?
    attemptCounter = 0;

  /* increment it with each run */
  ++attemptCounter;

  /* Greeting */
  Msg(lcd, "Welcome", "to your", 2000);
  Msg(lcd, "puzzle", "box!", 2000);

  /* Game over? */
  if (attemptCounter >= DEF_ATTEMPT_MAX)
  {
    Msg(lcd, "Sorry!", "No more", 2000);
    Msg(lcd, "attempts", "allowed!", 2000);
    PowerOff();
  }

  /* Print out the attempt counter */
  Msg(lcd, "This is", "attempt", 2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(attemptCounter);
  lcd.print(" of "); 
  lcd.print(DEF_ATTEMPT_MAX);
  delay(2000);

  /* Save the new attempt counter */
  EEPROM.write(EEPROM_OFFSET, attemptCounter);

  Msg(lcd, "Seeking", "Signal...", 0);
}

/* The Arduino loop() function */
void loop()
{
  /* Has a valid NMEA sentence been parsed? */
  if (ss.available() && tinyGps.encode(ss.read()))
  {
    float lat, lon;
    unsigned long fixAge;

[b]/* Here is my modification */[/b]
[b]
[/b]
[b]  int year;[/b]
[b]  byte month, day, hour, minute, second, hundredths;[/b]
[b]  [/b]
[b]  tinyGps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &fixAge);[/b]
[b]
[/b]
[b]    /* Have we established our location? */[/b]
[b]    tinyGps.f_get_position(&lat, &lon, &fixAge);[/b]
[b]    if (fixAge != TinyGPS::GPS_INVALID_AGE)[/b]
    {
      /* We got a fix! */
      Chirp(true);

[b]/* Here is my modification */[/b]
[b]
[/b]
[b]      if (&year, &month, &day < DATE_TO_START){[/b]
[b]        char sz[32];[/b]
[b]        sprintf(sz, "%02d/%02d/%02d" - DATE_TO_START,[/b]
[b]        day, month, year);[/b]
[b]        Msg(lcd, sz "days","remaining", 5000);[/b]
[b]        PowerOff();[/b]
[b]      }[/b]

      else
      {      

      /* Calculate the distance to the destination */
      float distance_meters = TinyGPS::distance_between(lat, lon, DEST_LATITUDE, DEST_LONGITUDE);

      /* Are we close?? */
      if (distance_meters <= RADIUS)
      {
        Msg(lcd, "Access", "granted!", 2000);
        servo.write(SERVO_OPEN_ANGLE);
      }

      /* Nope.  Print the distance. */
      else
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Distance");
        lcd.setCursor(0, 1);
        if (distance_meters < 1000)
        {
          lcd.print((int)distance_meters);
          lcd.print(" m.");
        }

        else
        {
          lcd.print((int)(distance_meters / 1000));
          lcd.print(" km.");
        }
        delay(4000);
        Msg(lcd, "Access", "Denied!", 2000);
      }
}
      PowerOff();
    }
  }

  /* Turn off after 5 minutes */
  if (millis() >= 300000)
    PowerOff();
}

/* Called to shut off the system using the Pololu switch */
void PowerOff()
{
  Chirp(false);
  Msg(lcd, "Powering", "Off!", 2000);
  lcd.clear(); 
}

So far I got it to work as I wanted. The only issue now is the correct date. It seems that the gps receives 01/01/2000 as current date and only sometimes the correct date.

Maybe there is a way to fix that issue?

My current changes:

static const int   YEAR_TO_START = 2021;      // year to start yyyy
static const int   MONTH_TO_START = 01;     // month to start mm
static const int   DAY_TO_START = 28;       // day to start dd
  if (ss.available() && tinyGps.encode(ss.read()))
  {

    float lat, lon;
    unsigned long fixAge;

    int year;
    byte month, day, hour, minute, second, hundredths;
    
  
    tinyGps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &fixAge);
  
    tinyGps.f_get_position(&lat, &lon);

    if (fixAge != TinyGPS::GPS_INVALID_DATE)
    
    if (fixAge != TinyGPS::GPS_INVALID_AGE)
    {
      digitalWrite(LED_PIN, HIGH);
      //Chirp(true);


      char sz[32];
        sprintf(sz, "    %02d/%02d/%02d    ",
        DAY_TO_START - day, MONTH_TO_START - month, YEAR_TO_START - year);
        Msg(lcd, sz,"Tage/Monate/Jahre", 5000);
        Msg(lcd, sz,"   zu frueh!   ", 5000);
        PowerOff();

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.