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