Here is my code thus far:
-I briefly had a Chronodot connected so some code is present/commented from that. I would like to use the Chronodot and see if I can synch up the square wave pin to the GPS PPS pin. This would allow me to continue to "blink" accurately even if the GPS lost signal. Any code examples would be great.
-I have a 20x4 LCD screen connected and use it for debugging. I realize it is quite slow and serial comments will not be in the final version as this needs to be quick.
//#include <Adafruit_MCP23008.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Time.h>
#include <TinyGPS.h> // http://arduiniana.org/libraries/TinyGPS/
#include <SoftwareSerial.h>
#include <DS1307RTC.h>
SoftwareSerial SerialGPS = SoftwareSerial(8, 7); //TX,RX
TinyGPS gps;
LiquidCrystal lcd(0);
// Offset hours from gps time (UTC)
//const int offset = 1; // Central European Time
//const int offset = -5; // Eastern Standard Time (USA)
//const int offset = -4; // Eastern Daylight Time (USA)
//const int offset = -8; // Pacific Standard Time (USA)
//const int offset = -7; // Pacific Daylight Time (USA)
const int offset = -6; //timezone where I am
tmElements_t tm; //makes the makeTime function work I think (anyone?)
time_t prevDisplay = 0; // when the digital clock was displayed
unsigned long beginTime = 0; //result of the beginTime function which determines UNIX start time
unsigned long countTime = 0; //result of the countTime function which determines next ledAstate change
volatile unsigned long indexTime = 0; //used for pps_interrupt function (not in use)
volatile unsigned long pps_start_ms; //used for pps_interrupt function (not in use)
//Handles reults from GPS date/time crack
unsigned long age;
int Year;
byte Month, Day, Hour, Minute, Second, Hundredths;
//Used for blinking the light in ledFunction. Will be for driving a MOSFET in final version.
byte ledAstate = HIGH;
byte ledAprevious = HIGH;
const byte ledApin = 13;
const int onTime = 4; //time in seconds the MOSFET will be "ON". User input between 0-10 in final version.
const int offTime = 2; //time in seconds the MOSFET will be "OFF". User input between 0-10 in final version.
const int beginHour = 7; //24 hour reference (7 = 7am) for calculating beging UNIX time to feed the beginTime function. User input final version.
void pps_interrupt() {
//Here is the interrupt from the PPS pin on the GPS. I know I am catching the interrupt properly as I have tested it, however I am just not sure what code to insert here to synch the clock to the GPS PPS. I have tried stuff like setTime = now() +1... I can see a few approaches to this but I would like some help with the best/better solution. I am sure there is an existing example code somewhere, but I have either not been able to find it.//
}
void setup()
{
Serial.begin(115200);
SerialGPS.begin(9600);
// setSyncProvider(RTC.get); // the function to get the time from the RTC
// if (timeStatus() != timeSet)
// Serial.println("Unable to sync with the RTC");
// else
// Serial.println("RTC has set the system time");
pinMode(ledApin, OUTPUT);
digitalWrite(ledApin, HIGH);
pinMode(2, INPUT);
attachInterrupt(0, pps_interrupt, RISING);
// set up the LCD's number of rows and columns:
lcd.begin(20, 4);
lcd.setBacklight(HIGH);
lcd.begin(20, 4);
lcd.print("GPS Interruption:");
lcd.setCursor(0, 1);
lcd.print("Time: : : .");
// lcd.setCursor(0, 2);
// lcd.print("Fix:");
// lcd.setCursor(0, 3);
// lcd.print("Bat: V mA");
delay(1000);
}
void loop()
{
//indexTime = RTC.get();
while (SerialGPS.available()) {
if (gps.encode(SerialGPS.read())) { // process gps messages
// when TinyGPS reports new data...
gps.crack_datetime(&Year, &Month, &Day, &Hour, &Minute, &Second, &Hundredths, &age);
// set the Time to the latest GPS reading
if (age < 300 ) {
setTime(Hour, Minute, Second, Day, Month, Year);
adjustTime(offset * SECS_PER_HOUR);
Serial.print("Time set 1");
Serial.println();
}
}
}
if (timeStatus() != timeNotSet) {
if (now() != prevDisplay) { //update the display only if the time has changed
prevDisplay = now(); //store updated display for comparison
//digitalClockDisplay(); //call serial clock display function
lcdDisplay(); //call LCD display function
}
}
ledFunction();
beginFunction();
countFunction();
}
void ledFunction() {
//Function to control the led pin state with interrupts disabled (is that a good idea or not?). This will drive a MOSFET in the final version.
// Serial.print("led Function Called");
// Serial.println();
byte oldSREG = SREG; // remember if interrupts are on or off
noInterrupts (); // turn interrupts off
if ( now() == countTime) {
ledAprevious = ledAstate;
ledAstate = HIGH;
}
if (now() == (countTime - offTime)) {
ledAprevious = ledAstate;
ledAstate = LOW;
}
if (ledAstate != ledAprevious) {
digitalWrite(ledApin, ledAstate);
}
SREG = oldSREG; // turn interrupts back on, if they were on before
}
void beginFunction() {
//Function determines UNIX start point for 7am of current day
//and returns value as beginTime
// Serial.print("begin Function Called");
// Serial.println();
tm.Second = 0;
tm.Hour = beginHour;
tm.Minute = 0;
tm.Day = day();
tm.Month = month();
tm.Year = year() - 1970;
beginTime = makeTime(tm);
}
void countFunction() {
//Function counts one cycle past now() to obtain countTime variable to feed the LED Function
// Serial.print("count Function Called");
// Serial.println();
countTime = beginTime;
while (countTime < now()) {
countTime = (countTime + onTime + offTime);
}
}
void lcdDisplay() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
// Serial.print("LCD Function Called");
// Serial.println();
lcd.setCursor(19, 0);
lcd.print(ledAstate);
lcd.setCursor(8, 1);
if (hour() < 10) {
lcd.print("0 ");
lcd.setCursor(9, 1);
lcd.print(hour());
}
else {
lcd.setCursor(8, 1);
lcd.print(hour());
}
lcd.setCursor(11, 1);
if (minute() < 10) {
lcd.print("0 ");
lcd.setCursor(12, 1);
lcd.print(minute());
}
else {
lcd.setCursor(11, 1);
lcd.print(minute());
}
lcd.setCursor(14, 1);
if (second() < 10) {
lcd.print("0 ");
lcd.setCursor(15, 1);
lcd.print(second());
}
else {
lcd.setCursor(14, 1);
lcd.print(second());
}
lcd.setCursor(6, 2);
lcd.print(RTC.get());
lcd.setCursor(6, 3);
lcd.print(now());
}
void digitalClockDisplay() {
}
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);
}