【ESP32S3】ESP32S3网络时间校准笔记


前言

本文基于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); // 删除任务
}

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

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

settimeofday

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

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

3.2 指令校准时间测试情况

16进制和10进制转换

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

总结

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

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今日为金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值