Reputation: 11
I'm using the ESP32 module and I am trying to get the NTP time in milliseconds. I managed to get the time in seconds without any problem using a struct tm and the function getLocalTime().
I read on forums and on the internet that I had to use struct timeval and the function gettimeofday() instead to achieve this. So I replaced the struct and the function accordingly in my code but now I can't get the time anymore...
My code is as follows:
void printLocalTime()
{
//When using struct tm and getLocalTime() I can get the time without poblem in seconds
struct timeval tv;
if (!gettimeofday(&tv, NULL)) {
Serial.println("Failed to obtain time");
return;
}
long int sec = tv.tv_sec*1000LL;
Serial.println(sec);
long int temp = tv.tv_usec/1000LL;
Serial.println(temp);
}
When I run this, all I'm getting is "Failed to obtain time"...
PS: I'm using arduino IDE and have included sys/time.h
Can anyone help me with this?
Many thanks
Upvotes: 0
Views: 5222
Reputation: 41
serve = 'pool.ntp.org'
ntp = ntplib.NTPClient()
ntpResponse = ntp.request(serve)
if (ntpResponse):
# calculate the ntp time and convert into microseconds
ntp_time = float(ntpResponse.tx_time * 1000000)
#print("ntp_time",ntp_time)
The above code is correct to get the ntp_server time in microseconds in python
Upvotes: 0
Reputation: 11
I'm using arduino IDE & I tried what you said like this:
char usec[30];
struct timeval tv;
if (gettimeofday(&tv, NULL)!= 0) {
Serial.println("Failed to obtain time");
return;
}
sprintf(sec, "%lld",(long long)tv.tv_sec);
sprintf(usec, "%lld", (long long)tv.tv_usec);
//long long seconds = (long long)tv.tv_sec;
//long long microseconds = (long long)tv.tv_usec;
Serial.print("TimeVal-sec = ");
Serial.print(sec);
Serial.print("TimeVal-usec = ");
Serial.print(usec);
But what I get is this: TimeVal-sec = 5TimeVal-usec = 792802
I'm also on Windows, is it a problem?
Upvotes: 0
Reputation: 2989
As the (original) POSIX command has the following structure
int gettimeofday(struct timeval *tv, struct timezone *tz);
and the error numbers are from 1 to 6
if (gettimeofday(&tv, NULL) != 0) {
Serial.println("Failed to obtain time");
return;
}
as it returns int and not bool as the function you used before is defined:
bool getLocalTime(struct tm * info, uint32_t ms)
in esp32-hal-time.c
and as
extern "C" bool getLocalTime(struct tm * info, uint32_t ms = 5000);
in Arduino.h
EDIT
As gettimeofday()
represents the time since UNIX_Epoch (1970) try this first:
printf("TimeVal-sec = %lld\n", (long long) tv.tv_sec);
printf("TimeVal-usec = %lld\n", (long long) tv.tv_usec);
will print something like
TimeVal-sec = 1493735463
TimeVal-usec = 525199 // already usec part
To "rip" apart the seconds you do the following
// Form the seconds of the day
long hms = tv.tv_sec % SEC_PER_DAY;
hms += tz.tz_dsttime * SEC_PER_HOUR;
hms -= tz.tz_minuteswest * SEC_PER_MIN;
// mod `hms` to ensure positive range of [0...SEC_PER_DAY)
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
// Tear apart hms into h:m:s
int hour = hms / SEC_PER_HOUR;
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
This function gives you all the usec
static int64_t getNowUs() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
}
and if you need the "real" date you have toadd
const unsigned long long EPOCH = 2208988800ULL;
uint64_t tv_ntp = tv.tv_sec + EPOCH;
For measuring elapsed time you process sec with sec and usec with usec. Hope this EDIT solves another POSIX/UNIX mystery.
Upvotes: 2