【问题标题】:get ntp time in milliseconds以毫秒为单位获取 ntp 时间
【发布时间】:2021-02-24 16:02:41
【问题描述】:

我正在使用 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-ide esp32 ntp milliseconds


    【解决方案1】:

    由于(原始)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
    编辑
    gettimeofday() 表示自 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
    

    此功能为您提供所有使用方法

    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 之谜。

    【讨论】:

    • 感谢@Codebreaker007!我会尝试让你知道它是否解决了我的问题
    • @Codebreaker007 一个小问题:我们在调用 gettimeofday() 时是否还需要 wifi 连接,就像调用 getLocalTime() 一样?
    【解决方案2】:

    我正在使用 arduino IDE 并且我尝试了您所说的这样:

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

    但我得到的是:TimeVal-sec = 5TimeVal-usec = 792802

    我也是在 Windows 上,有问题吗?

    【讨论】:

      【解决方案3】:
      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)
      

      以上代码在python中获取ntp_server时间是正确的,单位为微秒

      【讨论】:

      • 这个问题专门针对 ESP32 运行和 Arduino 草图。 Python 代码可能是正确的,但它不是问题的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 2017-08-05
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      相关资源
      最近更新 更多