当前位置:   article > 正文

【ESP32S3】ESP32S3网络时间校准笔记_esp32-s3的设备时间如何更新

esp32-s3的设备时间如何更新


前言

本文基于ESP_IDF5.0 powershell 编译、下载等操作,VS code代码编辑 ,fireTools 串口调试工具打印log ,飞书文档管理和项目沟通等操作。
软件工具总结思维导图

一、简单介绍

ESP32S3开发项目是常用的世界协调时间(UTC),那么智能设备同步网络时间是非常必要的,这篇文章将提供两种网络时间校准的方法,一种是通过网络时间服务器(SNTP)上获取的,另一种通过自定义指令同步设备UTC。

二、SNTP校准时间

2.1 SNTP代码展示

SNTP 指简单网络时间协议(Simple Network Time Protocol),使用非常简单,如下,联网判断成功后,
创建一个SNTP 校准时间的任务,代码及其简洁和干净

//创建一个SNTP 校准时间的任务
xTaskCreate(&sntp_task, "sntp_task", 1024 * 4, NULL, 6, NULL);
//SNTP 校准时间的任务
void sntp_task(void *pvParameter)
{
    sntp_setoperatingmode(SNTP_OPMODE_POLL);  //单播模式
    sntp_setservername(0, "ntp1.aliyun.com"); //阿里云ntp1服务
    sntp_setservername(1, "ntp2.aliyun.com"); //阿里云ntp2服务
    sntp_setservername(2, "ntp3.aliyun.com"); //阿里云ntp3服务
    //设置时区
    setenv("TZ", "CST-8", 1);                   //东八区
    sntp_init();  //sntp初始化
    
    time_t now = 0;
    struct tm timeinfo = { 0 };
    int sntp_retry_cnt = 0;
    int sntp_retry_time = 0;
    while (1) 
    {//直到获取成功,才退出循环
        for (int32_t i = 0; (i < (SNTP_RECV_TIMEOUT / 100)) && timeinfo.tm_year < (2019 - 1900); i ++) {
            vTaskDelay(100 / portTICK_PERIOD_MS);
            time(&now);
            localtime_r(&now, &timeinfo);//时间戳转化为本地时间结构
        }
        
        if (timeinfo.tm_year < (2019 - 1900) && sntp_retry_cnt < (SNTP_RECV_TIMEOUT / 100)) {
            sntp_retry_time = SNTP_RECV_TIMEOUT << sntp_retry_cnt;

            if (SNTP_RECV_TIMEOUT << (sntp_retry_cnt + 1) < SNTP_RETRY_TIMEOUT_MAX) {
                sntp_retry_cnt ++;	//sntp尝试次数累加
            }

            ESP_LOGI(TAG,"SNTP get time failed, retry after %d ms\n", sntp_retry_time);
            vTaskDelay(sntp_retry_time / portTICK_PERIOD_MS);//延时时间
        } 
        else 
        {
            ESP_LOGI(TAG,"SNTP get time success\n");
            break; //获取时间成功,退出循环
        }
    }
    sntp_stop();

    long timenow=time(NULL);
    ESP_LOGI(TAG,"网络时间同步:%ld\r\n",timenow);
    vTaskDelete(NULL); // 删除任务
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

2.2 SNTP测试情况

sntp测试打印时间

三、mqtt下发指令校准时间

有了SNTP网络时间同步,为什么还需要考虑指令同步呢?
1:实际测试过程中,SNTP服务获取网络时间不是实时的,需要等待一段时间才能同步。
2:实际测试过程中,ESP32S3的 UTC校时后,运行一段时间后,实际设备里的UTC和网络UTC误差很大,频繁调用SNTP负担很重。
如上UTC时间是大部分系统是定义为long型,也就是4个字节就可以定义UTC,那么我们通过MQTT协议自定义一个指令,服务器向ESP32S3发送携带4个字节UTC指令即可立刻同步时间,非常高效简洁

3.1 指令校准时间代码展示

MQTT的通讯,省略…

void SET_A2_11(unsigned char *data, unsigned char data_len) //UTC对时
{
    if (data_len == 4)
    {
    	//4个字节数据组合
        devicestation.NOW_UTC=(data[0]<<24)+(data[1]<<16)+(data[2]<<8)+data[3];
        struct timeval  tv;
        tv.tv_sec = devicestation.NOW_UTC;    
        tv.tv_usec = 0;
        // long timenow = time(NULL);
        if(settimeofday(&tv,NULL)==ESP_OK)
        {
            ESP_LOGI(TAG, "A2 11 UTC对时:%lld",tv.tv_sec);
        }
        else
        {
            ESP_LOGI(TAG, "A2 11 UTC对时失败:%lld",tv.tv_sec);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

指令校准更加简单
主要用到函数settimeofday()

settimeofday

  • 函数功能:设置时间和时序到系统的函数。
  • 参数说明:
    • tv:指向时间结构体指针。
    • tz:指向时区结构体指针。
  • 函数返回:成功返回0,失败返回-1。

int settimeofday(const struct timeval *tv, const struct timezone *tz)

3.2 指令校准时间测试情况

16进制和10进制转换

指令校时展示
测试完成校验成功。

总结

SNTP校准时间不需要搭建服务器,直接选用免费NTP服务器即可,但是不确定增加,校时效率比较慢。可以结合MQTT指令校时方法,在项目开发上两个都可以使用,实际上非常实用。

参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/471991
推荐阅读
相关标签
  

闽ICP备14008679号