I am using an ESP32 MicroMod with a Qwiic NEO M9N.
I am trying to log time, position, speed, and heading to a csv file as well as send to both ap and sta web pages.
I can not get the time to adjust to local time, everything else works. I am not logging the date, just the time. I tried using code from the SFE examples but it does not jige correct time late at night when UTC is 0 to my time zone.
Dale
I use the Arduino TimeLib.h library to convert time zones.
Convert the GPS time and date to a unix timestamp, add or subtract the number of seconds corresponding to the difference between UTC and your local time zone, then convert the (now local) time stamp to time and date format.
Example illustrating some of the options and manipulations:
//time_make_and_add
#include "TimeLib.h"
tmElements_t te; //Time elements structure
time_t unixTime; // a time stamp
void setup() {
Serial.begin(115200);
while(!Serial); //wait for connection
// what is the current system time after startup?
Serial.print("Startup: now() = "); //current time
Serial.println((unsigned long) now());
delay(3000);
Serial.print("after 3s delay, now() = ");
Serial.println((unsigned long) now());
// display date_time in Arduino-speak
Serial.print("day/date @startup+3s : ");
Serial.print(day());
Serial.print("/");
Serial.print(month());
Serial.print("/");
Serial.print(year());
Serial.print(" ");
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(":");
Serial.println(second());
// new internal clock setting.
// convert a date and time into unix time, offset 1970
te.Second = 0;
te.Hour = 23; //11 pm
te.Minute = 0;
te.Day = 1;
te.Month = 1;
te.Year = 2017 - 1970; //Y2K, in seconds = 946684800UL
unixTime = makeTime(te);
Serial.print("Example 1/1/2017 23:00 unixTime = ");
Serial.println(unixTime);
setTime(unixTime); //set the current time to the above entered
Serial.print("now() = ");
Serial.println(now());
// print as date_time
print_date_time();
// add
unixTime += 7200UL; //add 2 hours
setTime(unixTime);
Serial.println("After adding 2 hours");
Serial.print("now() = ");
Serial.println(now());
print_date_time();
}
void print_date_time() { //easy way to print date and time
char buf[40];
sprintf(buf, "%02d/%02d/%4d %02d:%02d:%02d", day(), month(), year(), hour(), minute(), second());
Serial.println(buf);
}
void loop() {}
Hi Dale,
If you are using the SparkFun u-blox library, it has a built-in Unix Epoch function:
uint32_t epoch = myGNSS.getUnixEpoch();
The full example is here: https://github.com/sparkfun/SparkFun_u- … Micros.ino
The comments in the example are not very clear. getUnixEpoch returns the epoch in seconds. If you want the microseconds too, use:
uint32_t us; //microseconds returned by getUnixEpoch()
uint32_t epoch = myGNSS.getUnixEpoch(us);
As jreminton says, it is then easy to add or subtract your timezone from the epoch.
For ESP32, you can use the ESP32Time library to set the RTC using the epoch:
#include <ESP32Time.h> //http://librarymanager/All#ESP32Time by FBiego v2.0.0
ESP32Time rtc;
{
rtc.setTime(epoch, us);
Serial.print("System time set to: ");
Serial.println(rtc.getDateTime(true));
}
Best wishes,
Paul
Thanks for the answers and help.
I am slowly working on semi autonomous navigation. The current plan is to have the ESP32 + GPS + IMU log and send data to a web page that is displayed on a 10" screen powered driven by a Raspberry Pi mounted on the handle bars of my Razor Metro. Having the time in local would be very nice.
Dale
I worked with the ESP32Time lib and and some examples from the SparkFun_u-blox_GNS_Arduino_Library. I used the GNSS to set the RTC starting one RTC with local offset one without. Got correct local time just after local midnight on the one with offset which is where I was having the problem.
Thanks for the help.
Dale
I forgot to mention I am using a Qwiic NEO-M9N with chip antenna.
You’re welcome Dale - glad that’s working for you.
Just FYI, the RTC will be slightly slow. The Unix Epoch is extracted from the NAV-PVT message and that is transmitted just after the top-of-second.
If you want your RTC to be exact, you need to use the UBX-TIM-TP message - which gives the time for the next Time Pulse (PPS) - and then sync your RTC on the rising edge of the TP pulse using an interrupt. It works well. We’re doing exactly that on a new product which can act as a Network Time Protocol server.
Best,
Paul
You might consider setting the pi’s clock off GPS time. If you do that, the pi will take care of displaying local time.