首页 > 解决方案 > 以毫秒为单位获取 ntp 时间

问题描述

我正在使用ESP32 模块,我试图以毫秒为单位获取 NTP 时间。我设法使用 struct tm 和函数 getLocalTime() 以秒为单位获得时间,没有任何问题。

我在论坛和互联网上读到我必须使用struct timeval和函数gettimeofday()来实现这一点。所以我在我的代码中相应地替换了结构和函数,但现在我再也没有时间了......

我的代码如下:

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);
}

当我运行它时,我得到的只是“未能获得时间”......

PS:我正在使用 arduino IDE 并包含 sys/time.h

谁能帮我这个?

非常感谢

标签: arduino-ideesp32ntpmilliseconds

解决方案


由于(原始)POSIX 命令具有以下结构

int gettimeofday(struct timeval *tv, struct timezone *tz);

错误编号从 1 到 6

if (gettimeofday(&tv, NULL) != 0) {
   Serial.println("Failed to obtain time");
   return;
 }

因为它返回 int 而不是 bool,因为定义了您之前使用的函数:

bool getLocalTime(struct tm * info, uint32_t ms)

esp32-hal-time.c和作为

extern "C" bool getLocalTime(struct tm * info, uint32_t ms = 5000);

在 Arduino.h
EDIT
Asgettimeofday()代表自 UNIX_Epoch (1970) 以来的时间,首先尝试这个:

printf("TimeVal-sec  = %lld\n", (long long) tv.tv_sec);
printf("TimeVal-usec  = %lld\n", (long long) tv.tv_usec);

会打印出类似的东西

TimeVal-sec  = 1493735463
TimeVal-usec  = 525199   // already usec part

要“撕开”几秒钟,请执行以下操作

  // 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

此功能为您提供所有 usec

static int64_t getNowUs() {
    struct timeval tv;
    gettimeofday(&tv, NULL);

    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
}

如果您需要“真实”日期,则必须添加

const unsigned long long EPOCH = 2208988800ULL;
uint64_t tv_ntp = tv.tv_sec + EPOCH;

为了测量经过的时间,您可以使用 sec 处理 sec,使用 usec 处理 usec。希望这个 EDIT 解决了另一个 POSIX/UNIX 之谜。


推荐阅读