1

I am learning how the Arduino and GPS module work so I can apply it to another project. My components are an Arduino Uno, NEO-6M GPS module, and a Adafruit 1.8" TFT display.

The code did not work as expected. It does display "waiting for sats".

However, it still displays the generic time and date, 1-1-1970 and 12:00:00 AM, for a while until the local time adisplays.

Plus the updated code takes a lot longer to display the time

Here is the code so far. What I would like it to do is:

  1. Display "waiting for sats"
  2. continue when a successful GPS signal is received
  3. adjust GPS time & date to local
  4. display date and time

Eventually this will be the basis for a Speed and GPS trackker for my RC vehicles. Any help is greatly appreciated.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <TimeLib.h>

#define cs   10
#define dc   8
#define rst  9

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

static const int RXPin = 2, TXPin = 3; //GPS communication

// Change this value to suit your Time Zone
const int UTC_offset = -4;   // Eastern Australia Time is 10

static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

time_t prevDisplay = 0; // Count for when time last displayed

void setup()
{

  Serial.begin(9600);  //set baud rate for serial monitor
     ss.begin(GPSBaud);  //set baud rate for GPS

   tft.initR(INITR_BLACKTAB);     //correct INITR for my display

  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(20, 58);
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
  tft.println("GPS Date & Time");
  tft.print("        Monitor");
  delay(3000);
  tft.fillScreen(ST7735_BLACK);
}

void loop()
{
 
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
 
     if (ss.available() < 1)
{
       gps.encode(ss.read());
 }

        GPS_Timezone_Adjust();  // Call Time Adjust Function

}
 

void GPS_Timezone_Adjust(){
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
     
      int Year = gps.date.year();
      byte Month = gps.date.month();
      byte Day = gps.date.day();
      byte Hour = gps.time.hour();
      byte Minute = gps.time.minute();
      byte Second = gps.time.second();

//Hour = hourFormat12();
        // Set Time from GPS data string
        setTime(Hour, Minute, Second, Day, Month, Year);
        // Calc current Time Zone time by offset value
        adjustTime(UTC_offset * SECS_PER_HOUR); 
     
    }
  }

  if (timeStatus()!= timeNotSet) {
  if (now() != prevDisplay) {     
      prevDisplay = now();
      ClockDisplay();
    }
 }
} 

void ClockDisplay(){
    tft.setCursor(5, 8);
     
    tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
    tft.print("Date:   ");
    tft.setTextColor(ST7735_CYAN,ST7735_BLACK);


      if(month() < 10){
        tft.print("0");
        }
      tft.print(month());
     
      tft.print("-");

      if(day() < 10){
        tft.print("0");
        }
      tft.print(day());

      tft.print("-");
     
      tft.print(year());
     

    tft.setCursor(4, 30);
    tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
    tft.print("Time:   ");
    tft.setTextColor(ST7735_CYAN,ST7735_BLACK);

      if(hourFormat12() < 10){
        tft.print("0");
        }
    tft.print(hourFormat12());
    tft.print(":");

      if(minute() < 10){
        tft.print("0");
        }
    tft.print(minute());
    tft.print(":");

      if(second() < 10){
        tft.print("0");
        }
    tft.print(second());

    if (isAM()) {
    tft.println(" AM ");
    } else {
    tft.println(" PM ");
    }

    tft.setCursor(5,50);
    tft.setTextColor(ST7735_WHITE,ST7735_RED);
    tft.println("RAW GPS DATE & TIME");

    tft.setCursor(5,58);
    tft.print(gps.date.month());
    tft.print("-");
    tft.print(gps.date.day());
    tft.print("-");
    tft.print(gps.date.year());

    tft.setCursor(5,66);
    tft.print(gps.time.hour());
    tft.print(":");
    tft.print(gps.time.minute());
    tft.print(":");
    tft.print(gps.time.second());
     
  smartDelay(400);
  }
    // deadline for a good recption
      static void smartDelay(unsigned long ms)
  {
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}
0

2 Answers 2

1

Display "waiting for sats" ... continue when a successful GPS signal is received

You are (or the Arduino library you are using is) using the time.h library which starts on January 1st, 1970. If no adjustments are made, time.h will report January 1st, 1970.

You are not (or the Arduino library you are using is not) waiting for a "good GPS signal" indication from the GPS module before displaying the time.

adjust GPS time & date to local

If you are using time.h you (or the Arduino library you are using) should set a time-zone offset instead of correcting the time by hand. This will take advantage of the time.h library utilities which take care of troublesome cases like calculating a time & date which crosses midnight with respect to UTC (aka GMT).

display date and time

The time.h library stores the date / time as the number of seconds since January 1st, 1970. So when displaying the current time, use time.h function calls to convert this counter to the current local time.

Hints / Suggestions:

  • The GPS module is a radio receiver. It works best when the view of the sky is unobstructed by buildings, trees, hills or bad weather. Such obstructions results in slow lock times or no lock at all. The more satellites the GPS module can see the better.
  • The GPS module is a computer in and of its self. The computer will analyze messages form satellites several times before it is ready to report location and time data. If possible, leave the GPS module powered up even if the Arduino is not. This should likely reduce or eliminate the delay the GPS module needs before reporting location and time.

Added later...

@Tvr4 brings up a good point. While time.h is more ubiquitous (used almost everywhere in C programming), in the Arduino paradigm, the built in Arduino time library is often used. For more, this is discussed in this stackoverflow question / answer. If you want to dive into the Arduino time library, the code is in this github repository. Also, you should find more help with this time libaray in the readme file displayed on that web page.

2
  • timeStatus() is part of the TimeLib Here is the page on the library playground.arduino.cc/Code/Time
    – Tvr4
    Commented Jul 6, 2020 at 14:03
  • ...thanks. Added additional text to the answer according to you suggestion.
    – st2000
    Commented Jul 7, 2020 at 13:36
0

I'm guessing that the GPS module doesn't receive a time reading until it acquires a GPS lock. That can take many seconds.

You haven't posted your code so we can't tell how you're handling the time reading.

I would suggest checking for the midnight 1970 time (which is the UNIX "epoch time") and handling that with special-case code. If you're reading the time as a numeric value it is almost certainly 0.

2
  • I am wondering if the problem is with this part of the code if (timeStatus()!= timeNotSet) { if (now() != prevDisplay) { prevDisplay = now(); ClockDisplay(); } }
    – Tvr4
    Commented Jul 5, 2020 at 19:40
  • what library defines the function timeStatus()? You need to tell us what libraries/frameworks you are using.
    – Duncan C
    Commented Jul 5, 2020 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.