Giter VIP home page Giter VIP logo

gps_rtc_clock's People

Contributors

matt448 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

kacza

gps_rtc_clock's Issues

Clock running late for some reason

Hi. I've tried to build a clock based on your code; to get a better grasp of it I left only a "skeleton". Surprisingly, my RTC gets correctly set, but then the clock starts to run late - every second it gets behind the actual time. Here is the log with timestamps enabled:

02:03:07.024 -> ---RTC TIME---
02:03:07.024 -> UTC: 2019/6/23 23:3:6
02:03:07.024 -> RTC has set the system time
02:03:07.024 -> 2:03:06
02:03:07.278 -> GPS not ready yet. Waiting for fix. Sat count: 0
02:03:07.646 -> GPS not ready yet. Waiting for fix. Sat count: 10
02:03:07.856 -> New boot. Need to update RTC with GPS time. Sat count: 10
02:03:07.856 -> Setting RTC from GPS
02:03:07.856 -> 
02:03:07.856 -> RTC set from GPS
02:03:08.227 -> 2:03:07
02:03:09.461 -> 2:03:08
02:03:10.982 -> 2:03:09
02:03:12.174 -> 2:03:10
02:03:13.341 -> 2:03:11
02:03:14.646 -> 2:03:12
02:03:16.096 -> 2:03:13
02:03:17.274 -> 2:03:14
02:03:18.541 -> 2:03:15

Notice that it was off by a second in the first line, but in 10 seconds it was behind by 3 seconds.

Here is my "skeleton" code:

#include "RTClib.h"           //https://github.com/adafruit/RTClib
#include <DS1307RTC.h>        //https://github.com/PaulStoffregen/DS1307RTC
#include <Time.h>             //https://github.com/PaulStoffregen/Time
#include <Timezone.h>         //https://github.com/JChristensen/Timezone
#include <TinyGPS++.h>        //https://github.com/mikalhart/TinyGPSPlus
#include <SoftwareSerial.h>
#include <Wire.h>

// Serial config for the GPS module
static const int RXPin = 3, TXPin = 13;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial GPS_Serial(RXPin, TXPin);

RTC_DS1307 rtc;

bool rtcSet = false;

//Timezone stuff
TimeChangeRule msk = {"MSK", Last, Sun, Mar, 1, 180}; // 3 * 60 = 180 minutes between UTC and Moscow
Timezone tzMSK(msk);

TimeChangeRule *tcr;        //pointer to the time change rule, use to get TZ abbrev
time_t utc, local;

//variables for time counting
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long syncTimer = 0;
unsigned long scheduledTimer = 0;

bool newboot = true;
int prevSecond = 0; // for debugging

////////////////////////////////////
// SETUP
////////////////////////////////////

void setup() {
  Serial.begin(115200);
  GPS_Serial.begin(GPSBaud);
  if (! rtc.begin()) {
    Serial.println(F("Couldn't find RTC"));
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println(F("RTC is NOT running!"));
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
  checkRTCset();
  Serial.println();
  Serial.println("---RTC TIME---");
  DateTime now = rtc.now();
  Serial.print("UTC: ");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) {
    Serial.println(F("Unable to sync with the RTC"));
  } else {
    Serial.println(F("RTC has set the system time"));
  }
}

////////////////////////////////////
// MAIN LOOP
////////////////////////////////////

void loop() { 
  currentMillis = millis();
  if(!rtcSet){
    Serial.println(F("RTC not set"));
    setRTCfromGPS();
    checkRTCset();
  }
  // Read GPS data from serial connection until no more data is available
  while (GPS_Serial.available() > 0) {
    gps.encode(GPS_Serial.read());
  }

  if (currentMillis > 5000 && gps.charsProcessed() < 10) {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
  utc = now(); // Grab the current time
  //printTime(utc, "UTC");
  local = tzMSK.toLocal(utc, &tcr);
  //printTime(local, tcr -> abbrev);
  
  syncOnBoot();

  // Show clock
  DisplayTime();
  
  //Syncs GPS time to the RTC regularly.
  scheduledSync();

}

////////////////////////////////////
// FUNCTIONS
////////////////////////////////////

void DisplayTime() {
  if(!rtcSet)  {
    Serial.println(F("Waiting for GPS Fix"));
  }else{
    if (second(local) != prevSecond){
      Serial.print(hour(local));
      padZero(minute(local)); 
      padZero(second(local)); 
      Serial.println();
    }
    prevSecond = second(local);
  }
}

void checkRTCset() {
  DateTime now = rtc.now();
  if(now.hour() == 0 && now.minute() == 0 && now.second() == 0 && now.year() < 2010)
  {
    Serial.println(F("*** RTC TIME NOT SET. ***"));
    Serial.println();
  }else{
    rtcSet = true;
    Serial.println(F("RTC TIME SET."));
    Serial.println();

  }
}

void syncOnBoot() {
  if(newboot) {
    int satcount = gps.satellites.value();
    if (gps.date.isValid() && gps.time.isValid() && satcount > 4) {
      Serial.print(F("New boot. Need to update RTC with GPS time. Sat count: "));
      Serial.println(satcount);
      setRTCfromGPS();
      newboot = false;
      syncTimer = 0;
    } else {
      if(currentMillis > (syncTimer + 250)) {
        Serial.print(F("GPS not ready yet. Waiting for fix. Sat count: "));
        Serial.println(satcount);
        syncTimer = currentMillis;
      }
    }
  }
}

void setRTCfromGPS() {
  /* This line sets the RTC with an explicit date & time:
     rtc.adjust(DateTime(2000, 12, 31, 12, 59, 59));
   */
  Serial.println("Setting RTC from GPS");
  Serial.println();
  if (gps.date.isValid() && gps.time.isValid()) {
    rtc.adjust(DateTime(gps.date.year(), gps.date.month(), gps.date.day(), gps.time.hour(), gps.time.minute(), gps.time.second()));
    Serial.println(F("RTC set from GPS"));
  } else {
    Serial.println(F("No GPS fix yet. Can't set RTC yet."));
  }
}

void scheduledSync() {
  /*
   * Re-syncs the RTC with the time stamp from the GPS data regularly.
   */
  if(
    (currentMillis > (scheduledTimer + 10000)) &&
    newboot == false
  ){  // Only allow RTC sync to happen once every 10 sec
    Serial.println(F("Regular scheduled sync about to proceed..."));
    if(minute(local) == 50) {
      Serial.println(F("Scheduled RTC sync from GPS Time."));
      setRTCfromGPS();
    } 
    //Serial.println(F("Adjusted Arduino time from RTC."));
    //DateTime now = rtc.now();
    scheduledTimer = currentMillis;
  }
}

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

I am really out of ideas. I will greatly appreciate your advice on what might be wrong with my code. Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.