I have built a GPS clock plus temperature display, using the UP501D gps module.
I have the display seperate to the gps unit, and send the numbers to be displayed via a cable using VirtualWire ( running slowly to avoid cable capacitance problems ) The waveform at the display end is identical to the gps unit end so thats fine.
At switch on, no data is sent to the display until the first valid sentance is received.
To avoid the occaisional spurious data from the gps being displayed, I read the minutes and hours every second, and every time the minute changes, I add a minute to make " nextminute" and " nexthour" to compare with the following minutes data.
If they match, the freerunning clock is updated, and its millis timing reset to zero.
Initially I lose an extra minute at switch on, but it takes a while for the gps to lock on anyway at power on.
If the GPS loses lock, the free running clock carries on updating the display every minute using its 16 MHz xtal ( its accurate to within a few seconds a day, so I havn't bothered with a RTC , the gps stays locked on virtually all the time )
At the display end, I have a micro receiving the VW data, and sending it serially to the display digits which are latched.
To avoid showing the wrong time all day if the data stops, I have a timer that blanks the display after 130 seconds of no data received.
My only problem is that once in a blue moon, the display blanks , which shows a lack of data.
The LED stays on ( not flashing ) which shows a valid sentance is being received... and if it did lose lock, the freerun clock should be transmitting every minute anyway..
Unfortunately both times it has happened, I didnt leave it on to see if it would come back on after a minute, and it hasn't happened in the last day or two. I am waiting with the scope ready, but a watched pot never boils ....
Can anyone see in my code below, if I have any stupid mistakes, or situations that could make it hang ?
// GPS CLOCK BOTTOM END APR 7
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <VirtualWire.h>
#define ledPin 8 // flashes LED
int sensorPin = 3; // analog pin 0 reads tmp35 output
unsigned long clockmillis = 0;
unsigned long rxmillis = 0;
unsigned long interval = 60000;
unsigned long currentMillis;
unsigned long currentclockMillis;
int clockmins;
int clockhours;
#define RXPIN 14 //
#define TXPIN 15 //
#define GPSBAUD 9600 // baud rate of our UP501D GPS module. Change for your GPS module if different
char msg [6];
TinyGPS gps;
NewSoftSerial uart_gps(RXPIN, TXPIN);
void getgps(TinyGPS &gps);
int temptens;
int tempunits;
int hourtens;
int hourunits;
int mintens;
int minunits;
int rxhours;
int rxmins;
int ledState = LOW;
long previousMillis = 0;
long flashinterval = 1200;
int searching;
// ************************************* SET UP ***********************************************
void setup() {
uart_gps.begin(GPSBAUD); // setup sketch for data output speed of GPS module
// Serial.begin(115200);
interval = 60000;
pinMode (ledPin, OUTPUT );
digitalWrite(ledPin, LOW);
searching = HIGH;
vw_set_tx_pin(16); // Tx module connections and speed
vw_set_ptt_pin(10); // powers Tx and LED not used this project
vw_setup(1000);
} // end of setup
// ===================================GET GPS==========================
void getgps(TinyGPS &gps) // The getgps function will get the values we want.
{
int year,a,t;
byte month, day, hour, minute, second, hundredths;
gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
hour=hour+2; // my zone is GMT +2
if (hour>23) {
hour = hour - 24;
}
int nexthour = rxhours;
int nextmins = (rxmins + 1) ;
if (nextmins > 59 ){
nextmins = 0;
( nexthour + 1 );
if ( nexthour > 23 ){
nexthour = 0;
}
}
rxhours = ( int ) hour;
rxmins = (int) minute;
if ( rxmins == nextmins ){
if (rxhours == nexthour) { // IF TIME IS AS EXPECTED FROM PREV READ
searching = LOW;
clockmins = rxmins;
clockhours = rxhours;
clockmillis = millis () ; // reset freerun clock counter millis
showtime ();
}
}
} // end of get gps
//********************************************************************************************
void loop()
{
//******************************* flashing the led *************************************************
currentMillis = millis(); // flash the led til GPS aquires
if(currentMillis - previousMillis > flashinterval) {
previousMillis = currentMillis;
if (ledState == LOW)
{
ledState = HIGH;
}
else
{
ledState = LOW;
}
}
digitalWrite ( ledPin, ledState );
//********************************NOW CHECK THE GPS RECEIVER ************************************************
if(uart_gps.available()) // While there is data on the RX pin...
{
int c = uart_gps.read(); // load the data into a variable...
if(gps.encode(c)) // if there is a new valid sentence...
{
ledState = HIGH; // LEAVES THE LED ON when valid sentance aquired by resetting the ledflash timer
previousMillis = currentMillis;
getgps(gps); // then grab the data,
}// end if GPS encode
} // end if uuart avail
// ------------------------------------------------ FREE RUNNING BACKUP CLOCK ------------------
currentclockMillis = millis();
if(currentclockMillis - clockmillis > interval) { // if new minute
clockmillis = currentclockMillis;
clockmins ++;
if ( clockmins >59 ) {
clockmins = 0;
clockhours ++;
if (clockhours >23 ) {
clockhours = 0 ;
}
}
if ( searching == LOW ){
showtime ();
}
}// end of if new minute
} // end of loop
//*********************************GEN DISPLAY NUMBERS AND SEND TO DISPLAY UNIT ****************************************
void showtime () {
checktemp ();
int t,a;
byte hour, minute;
if (clockhours<10)
{
hourtens = 0;
hourunits = clockhours; // Serial.print("less than ten hours == "); Serial.println(hourunits);
}
if (clockhours>=10) {
t=clockhours/10;
a=int(t);
hourtens = a; // Serial.print(" hourstens = "); Serial.println(hourtens);
t=clockhours%10;
hourunits = t; // Serial.print(" hoursunits == "); Serial.println(hourunits);
}
if (clockmins<10)
{
mintens = 0;
minunits = clockmins; // Serial.print("less than ten mins == "); Serial.println(minunits);
}
if (clockmins>=10)
{
t=clockmins/10;
a=int(t);
mintens = a; //Serial.print(" mintens >10 ="); Serial.println(mintens);
t=clockmins%10;
minunits = t; // Serial.print(" minunits>10 == "); Serial.println(minunits);
}
msg [0] = hourtens;
msg [1] = hourunits;
msg [2] = mintens;
msg [3] = minunits;
msg [4] = temptens;
msg [5] = tempunits;
vw_send((uint8_t *)msg, 6); // send the character out
vw_wait_tx(); // Wait until the whole message is gone
}
//================================================CHECKING TEMPERATURE=======================
void checktemp () {
int reading = analogRead(sensorPin);
float voltage = reading * 5.0;
voltage /= 1024.0;
int temperatureC = (voltage ) * 100 ;
int x,y;
if (temperatureC<10)
{
temptens = 0;
tempunits = temperatureC;
}
if (temperatureC>=10) {
x=temperatureC/10;
y=int(x);
temptens = y; //
x=temperatureC%10;
tempunits = x; //
}
} // end checktemp
// =================================================================================