ESP8266-----SNTP获取网络时间

article/2025/8/21 23:21:46

目录

前言

user_init

IP定时的回调函数

初始化SNTP

SNTP定时回调函数


前言

介绍了8266如何获取网络时间

user_init

首先将8266设置为sta模式

void ICACHE_FLASH_ATTR user_init(void)
{uart_init(115200,115200);	// 初始化串口波特率os_delay_us(10000);			// 等待串口稳定os_printf("\r\n=================================================\r\n");os_printf("\t Project:\t%s\r\n", ProjectName);os_printf("\t SDK version:\t%s", system_get_sdk_version());os_printf("\r\n=================================================\r\n");// OLED显示初始化//----------------------------------------------------------------OLED_Init();								// OLED初始化OLED_ShowString(0,0,"                ");	// Internet TimeOLED_ShowString(0,2,"Clock =         ");	// Clock:时钟OLED_ShowString(0,4,"Temp  =         ");	// Temperature:温度OLED_ShowString(0,6,"Humid =         ");	// Humidity:湿度//----------------------------------------------------------------LED_Init_JX();		// LED初始化ESP8266_STA_Init_JX();			// ESP8266_STA初始化OS_Timer_IP_Init_JX(1000,1);	// 1秒重复定时(获取IP地址)
}

IP定时的回调函数

如果成功获取到ip地址,那么调用ESP8266_SNTP_Init_JX();   来初始化SNTP

// IP定时的回调函数
//=========================================================================================================
void ICACHE_FLASH_ATTR OS_Timer_IP_cb(void)
{u8 C_LED_Flash = 0;				// LED闪烁计次struct ip_info ST_ESP8266_IP;	// ESP8266的IP信息u8 ESP8266_IP[4];				// ESP8266的IP地址// 成功接入WIFI【STA模式下,如果开启DHCP(默认),则ESO8266的IP地址由WIFI路由器自动分配】//-------------------------------------------------------------------------------------if( wifi_station_get_connect_status() == STATION_GOT_IP )	// 判断是否获取IP{wifi_get_ip_info(STATION_IF,&ST_ESP8266_IP);	// 获取STA的IP信息ESP8266_IP[0] = ST_ESP8266_IP.ip.addr;			// IP地址高八位 == addr低八位ESP8266_IP[1] = ST_ESP8266_IP.ip.addr>>8;		// IP地址次高八位 == addr次低八位ESP8266_IP[2] = ST_ESP8266_IP.ip.addr>>16;		// IP地址次低八位 == addr次高八位ESP8266_IP[3] = ST_ESP8266_IP.ip.addr>>24;		// IP地址低八位 == addr高八位// 显示ESP8266的IP地址//------------------------------------------------------------------------------------------------//os_printf("\nESP8266_IP = %d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);//OLED_ShowIP(24,2,ESP8266_IP);	// OLED显示ESP8266的IP地址//------------------------------------------------------------------------------------------------// 接入WIFI成功后,LED快闪3次//----------------------------------------------------for(; C_LED_Flash<=5; C_LED_Flash++){GPIO_OUTPUT_SET(GPIO_ID_PIN(4),(C_LED_Flash%2));delay_ms(100);}os_timer_disarm(&OS_Timer_IP);	// 关闭定时器ESP8266_SNTP_Init_JX();			// 初始化SNTP}
}

初始化SNTP

8266最多支持设置三个SNTP服务器,其中SNTP0是主服务器,剩下的两个是备用服务器

我们可以调用这两个API来设置SNTP服务器,参数一是SNTP服务器的优先级

sntp_setservername(0, "us.pool.ntp.org");    // 服务器_0【域名】 参数二是SNTP的域名
sntp_setserver(2, addr);                    // 服务器_2【IP地址】参数二是SNTP服务器的32位二进制IP地址

所以说在使用sntp_setserver(2, addr);之前要先用ipaddr_aton("210.72.145.44", addr); 来将点分十进制字符串形式ip地址转化成32位的二进制ip地址,作为sntp_setserver(2, addr);的参数

之后调用sntp_init();  SNTP初始化API

再设置OS_Timer_SNTP_Init_JX(1000,1);  1秒重复定时(SNTP)

// 初始化SNTP
//=============================================================================
void ICACHE_FLASH_ATTR ESP8266_SNTP_Init_JX(void)
{ip_addr_t * addr = (ip_addr_t *)os_zalloc(sizeof(ip_addr_t));sntp_setservername(0, "us.pool.ntp.org");	// 服务器_0【域名】sntp_setservername(1, "ntp.sjtu.edu.cn");	// 服务器_1【域名】ipaddr_aton("210.72.145.44", addr);			// 点分十进制 => 32位二进制sntp_setserver(2, addr);					// 服务器_2【IP地址】os_free(addr);								// 释放addrsntp_init();	// SNTP初始化APIOS_Timer_SNTP_Init_JX(1000,1);				// 1秒重复定时(SNTP)
}

SNTP定时回调函数

调用sntp_get_current_timestamp();来查询当前距离基准时间(1970.01.01 00:00:00 GMT+8)的时间戳(单位:秒)  基准时间是1970年1月1号0时0分0秒东8区

如果TimeStamp这个时间戳不等于0,就说明SNTP获取网络时间成功。

调用sntp_get_real_time(TimeStamp);它的参数就是距离基准时间的时间戳,来获取当前的真实时间。

之后串口打印时间戳,串口打印实际时间

根据获取到的时间来将我们所需要的时间,日期,时刻的值用oled显示,并且oled显示读取到的温湿度数据

// SNTP定时回调函数
//===================================================================================================
void ICACHE_FLASH_ATTR OS_Timer_SNTP_cb(void	 * arg)
{// 字符串整理 相关变量//------------------------------------------------------u8 C_Str = 0;				// 字符串字节计数char A_Str_Data[20] = {0};	// 【"日期"】字符串数组char *T_A_Str_Data = A_Str_Data;	// 缓存数组指针char A_Str_Clock[10] = {0};	// 【"时间"】字符串数组char * Str_Head_Week;		// 【"星期"】字符串首地址char * Str_Head_Month;		// 【"月份"】字符串首地址char * Str_Head_Day;		// 【"日数"】字符串首地址char * Str_Head_Clock;		// 【"时钟"】字符串首地址char * Str_Head_Year;		// 【"年份"】字符串首地址//------------------------------------------------------uint32	TimeStamp;		// 时间戳char * Str_RealTime;	// 实际时间的字符串// 查询当前距离基准时间(1970.01.01 00:00:00 GMT+8)的时间戳(单位:秒)//-----------------------------------------------------------------TimeStamp = sntp_get_current_timestamp();if(TimeStamp)		// 判断是否获取到偏移时间{//os_timer_disarm(&OS_Timer_SNTP);	// 关闭SNTP定时器// 查询实际时间(GMT+8):东八区(北京时间)//--------------------------------------------Str_RealTime = sntp_get_real_time(TimeStamp);// 【实际时间】字符串 == "周 月 日 时:分:秒 年"//------------------------------------------------------------------------os_printf("\r\n----------------------------------------------------\r\n");os_printf("SNTP_TimeStamp = %d\r\n",TimeStamp);		// 时间戳os_printf("\r\nSNTP_InternetTime = %s",Str_RealTime);	// 实际时间os_printf("--------------------------------------------------------\r\n");// 时间字符串整理,OLED显示【"日期"】、【"时间"】字符串//…………………………………………………………………………………………………………………// 【"年份" + ' '】填入日期数组//---------------------------------------------------------------------------------Str_Head_Year = Str_RealTime;	// 设置起始地址while( *Str_Head_Year )		// 找到【"实际时间"】字符串的结束字符'\0'Str_Head_Year ++ ;// 【注:API返回的实际时间字符串,最后还有一个换行符,所以这里 -5】//-----------------------------------------------------------------Str_Head_Year -= 5 ;			// 获取【"年份"】字符串的首地址T_A_Str_Data[4] = ' ' ;os_memcpy(T_A_Str_Data, Str_Head_Year, 4);		// 【"年份" + ' '】填入日期数组T_A_Str_Data += 5;				// 指向【"年份" + ' '】字符串的后面的地址//---------------------------------------------------------------------------------// 获取【日期】字符串的首地址//---------------------------------------------------------------------------------Str_Head_Week 	= Str_RealTime;							// "星期" 字符串的首地址Str_Head_Month = os_strstr(Str_Head_Week,	" ") + 1;	// "月份" 字符串的首地址Str_Head_Day 	= os_strstr(Str_Head_Month,	" ") + 1;	// "日数" 字符串的首地址Str_Head_Clock = os_strstr(Str_Head_Day,	" ") + 1;	// "时钟" 字符串的首地址// 【"月份" + ' '】填入日期数组//---------------------------------------------------------------------------------C_Str = Str_Head_Day - Str_Head_Month;				// 【"月份" + ' '】的字节数os_memcpy(T_A_Str_Data, Str_Head_Month, C_Str);	// 【"月份" + ' '】填入日期数组T_A_Str_Data += C_Str;		// 指向【"月份" + ' '】字符串的后面的地址// 【"日数" + ' '】填入日期数组//---------------------------------------------------------------------------------C_Str = Str_Head_Clock - Str_Head_Day;				// 【"日数" + ' '】的字节数os_memcpy(T_A_Str_Data, Str_Head_Day, C_Str);		// 【"日数" + ' '】填入日期数组T_A_Str_Data += C_Str;		// 指向【"日数" + ' '】字符串的后面的地址// 【"星期" + ' '】填入日期数组//---------------------------------------------------------------------------------C_Str = Str_Head_Month - Str_Head_Week - 1;		// 【"星期"】的字节数os_memcpy(T_A_Str_Data, Str_Head_Week, C_Str);		// 【"星期"】填入日期数组T_A_Str_Data += C_Str;		// 指向【"星期"】字符串的后面的地址// OLED显示【"日期"】、【"时钟"】字符串//---------------------------------------------------------------------------------*T_A_Str_Data = '\0';		// 【"日期"】字符串后面添加'\0'OLED_ShowString(0,0,A_Str_Data);		// OLED显示日期os_memcpy(A_Str_Clock, Str_Head_Clock, 8);		// 【"时钟"】字符串填入时钟数组A_Str_Clock[8] = '\0';OLED_ShowString(64,2,A_Str_Clock);		// OLED显示时间//…………………………………………………………………………………………………………………}// 每5秒,读取/显示温湿度数据//-----------------------------------------------------------------------------------------C_Read_DHT11 ++ ;		// 读取DHT11计时if(C_Read_DHT11>=5)		// 5秒计时{C_Read_DHT11 = 0;	// 计时=0if(DHT11_Read_Data_Complete() == 0)		// 读取DHT11温湿度{DHT11_NUM_Char();	// DHT11数据值转成字符串OLED_ShowString(64,4,DHT11_Data_Char[1]);	// DHT11_Data_Char[0] == 【温度字符串】OLED_ShowString(64,6,DHT11_Data_Char[0]);	// DHT11_Data_Char[1] == 【湿度字符串】}else{OLED_ShowString(64,4,"----");	// Temperature:温度OLED_ShowString(64,6,"----");	// Humidity:湿度}}//-----------------------------------------------------------------------------------------
}

 

可以看到8266已经成功的获取到了距离基准时间的时间戳,并且根据这个时间戳成功的获取了当前的实际时间 Sun Jul 24 19:14:22 2022 跟电脑系统时间是一致的,这就说明8266通过SNTP成功的获取到了网络时间,在olde上秒一直在走,说明它一直在不停地获取准确的网络时间。


http://chatgpt.dhexx.cn/article/paJxyQ1o.shtml

相关文章

微软 sntp服务器地址,电脑sntp服务器地址

电脑sntp服务器地址 内容精选 换一换 当创建文件系统后&#xff0c;您需要使用云服务器来挂载该文件系统&#xff0c;以实现多个云服务器共享使用文件系统的目的。本章节以Windows 2012版本操作系统为例进行NFS文件系统挂载&#xff0c;其他版本请参考以下主要步骤根据实际界面…

ESP32 SNTP设置

SNTP&#xff0c;Simple Network Time Protocol&#xff08;简单网络时间协议&#xff09;&#xff0c;用来同步时钟。 百度百科&#xff1a;[SNTP](https://baike.baidu.com/item/sntp/4749147?fraladdin) SNTP协议采用客户端/服务器的工作方式&#xff0c;可以采用单播&…

sntp服务器位置,sntp的服务器地址

sntp的服务器地址 内容精选 换一换 介绍常见的安全组配置示例。如下示例中,出方向默认全通,仅介绍入方向规则配置方法。不同安全组内的云耀云服务器内网互通仅允许特定 IP 地址远程连接云耀云服务器SSH远程连接Linux云耀云服务器RDP远程连接Windows云服务器公网ping云耀云服务…

sntp 校时问题

1、背景 由于项目中的数据对时间比较敏感&#xff0c;目前常常出现校时问题&#xff0c;导致时间偏差&#xff0c;出现曲线数据丢失和曲线数据重复等问题。 因此对sntp源码进行深入分析。 要了解SNTP&#xff0c;首先需要了解NTP协议。SNTP是NTP的子集&#xff0c;简化了NTP…

ESP8266_SNTP(Simple Network Time Protocol)

1、SNTP 简单网络时间协议 SNTP协议采用客户端/服务器的工作方式&#xff0c;以UDP方式通信&#xff0c;SNTP服务器通过接收GPS信号或自带的原子钟作为系统的时间基准。 网络中存在很多台SNTP服务器&#xff0c;客户端会选择几台SNTP服务器使用。如果一台SNTP服务器在工作过程…

WIFI学习六(SNTP)

简介 SNPT&#xff08;Simple Network Time Protocal简单网络时间协议&#xff09;用于跨广域网或局域网时间同步的协议&#xff0c;具有较高的精确度&#xff08;几十毫秒&#xff09;。SNTP是NTP协议的简化版 SNTP的工作方式 SNTP协议采用客户端/服务器的工作方式&#xff0…

SNTP简介

要了解SNTP&#xff0c;首先需要了解NTP协议。SNTP是NTP的子集&#xff0c;简化了NTP的许多算法和步骤&#xff0c;得到了效率&#xff0c;但时间的精度不如NTP&#xff0c;可是对于民用时间来说足够了&#xff0c;大概最多差距几秒的样子。 NTP&#xff08;Network Time Proto…

SNTP原理讲解 客户端 C语言实现

1.定义 SNTP(Simple Network Time Protocal简单网络时间协议)&#xff0c;用于跨广域网或局域网同步时间的协议&#xff0c;具有较高的精确度&#xff08;几十毫秒&#xff09; 这里给出SNTP的详细定义和解释&#xff0c;以及基于C语言的SNTP客户端实现代码&#xff1a;SNTP c…

使用SNTP协议获取时间

要了解SNTP,首先需要了解NTP协议。SNTP是NTP的子集,简化了NTP的许多算法和步骤,得到了效率,但时间的精度不如NTP,可是对于民用时间来说足够了,大概最多差距几秒的样子。 NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服…

sntp协议简介

SNTP(Simple Network Time Protocal简单网络时间协议)&#xff0c;用于跨广域网或局域网同步时间的协议&#xff0c;具有较高的精确度&#xff08;几十毫秒&#xff09;。SNTP是NTP协议的简化版&#xff0c;两者分别在RFC1305和RFC2030介绍。 SNTP工作方式 SNTP采用客户端/服务…

关于马尔可夫过程的一些学习笔记

①马尔可夫性质&#xff1a;已知“现在”的情况下&#xff0c;“未来”与“过去”彼此独立&#xff08;N1仅与N有关&#xff0c;与N以前的所有都无关&#xff09; ②马尔可夫过程&#xff1a;具有马尔可夫性质的随机过程 ③马尔可夫链&#xff1a;马尔可夫过程的原始模型&…

来聊聊马尔可夫过程

相信你对马尔科夫这个词一定不陌生&#xff0c;因为在人工智能机器学习领域&#xff0c;这个词是避不开的&#xff0c;如马尔可夫链&#xff08;Markov chain)&#xff0c;马尔科夫随机场(Markov random field)&#xff0c;马尔可夫过程(Markov process)&#xff0c;隐马尔可夫…

【算法学习】马尔可夫过程及经典例题讲解(含代码实现)

公众号关注 52DATA &#xff0c;获得更多数据分析知识,感谢支持—> 文章目录 马尔可夫过程1. 马尔可夫性2. 马尔可夫链2.1 转移概率矩阵&#xff08;随机矩阵&#xff09;2.2 状态概率2.3 平稳分布 3.一个很经典的例题帮助理解马尔科夫预测方法1.求状态转移概率2.运用状态概…

数学基础(8)-- 马尔可夫链与马尔可夫过程

目录 1. 简介 1.1 定义 1.2 变种 2. 瞬态演变 3. 马尔科夫链性质 3.1 可还原性 3.2 周期性 3.3 重现性 4. 有限状态空间 1. 简介 马尔可夫链&#xff08;英语&#xff1a;Markov chain&#xff09;&#xff0c;又称离散时间马可夫链&#xff08;discrete-time Markov…

部分可观测马尔可夫过程POMDP

POMDP与MDP的一句话区别&#xff1a;POMDP的state具有不确定性&#xff0c;由七元数组定义&#xff0c;多了观测空间、观测函数、初始置信&#xff08;belief&#xff09;&#xff0c;根据观测概率矩阵求出最可能是的状态 利用值迭代法解决POMDP问题 MDP POMDP 状态→动作 信…

马尔可夫 java_马尔可夫过程(以马尔科夫链Markov为例)

马尔可夫过程(以马尔科夫链Markov为例) 马尔可夫过程 马尔可夫过程的大概意思就是未来只与现在有关&#xff0c;与过去无关。 简单理解就是渣男只在乎下一刻会不会爱你只取决于这一时刻对你的新鲜感&#xff0c;而与你之前对这段感情的付出毫无关系。 设有一个随机过程X(t)&…

马尔可夫决策过程

马尔可夫决策过程 一、马尔科夫决策过程&#xff1a;**马尔科夫决策过程****最优决策**值迭代策略迭代MDP中的参数估计 二、代码实战&#xff1a;A、马尔可夫决策过程值迭代B、马尔可夫决策过程策略迭代C、马尔可夫决策过程动态规划版 参考文章 本文介绍了马尔可夫决策过程&…

随机过程第2讲——马尔可夫过程的应用

温习&#xff1a;随机过程第1讲——泊松过程的模拟与检验&#xff1a;https://blog.csdn.net/ChenQihome9/article/details/82871332 去得也突然——不知在什么时候&#xff0c;雨&#xff0c;悄悄地停了。风也屏住了呼吸&#xff0c;山中一下变得非常幽静。远处&#xff0c;一…

强化学习(2): 马尔可夫过程

前言 本文重点介绍MDP&#xff0c;因为MDP是目前最适合表征强化学习问题的模型。 一个具体的赌徒例子&#xff0c;来说明强化学习的算法如何与MDP构建联系&#xff0c;并且求解出最优策略。链接如下&#xff1a;link 一、马尔可夫性 其假设未来的状态仅取决与当前的状态。过…

贝叶斯网络、马尔可夫模型、马尔可夫过程、马尔可夫链、马尔可夫网络基本概念

知识储备与简要概括 可数集【Countable set】&#xff1a; 是指每个元素都能与自然数集N的每个元素之间能建立一一对应的集合。如果将可数集的每个元素标上与它对应的那个自然数记号&#xff0c;那么可数集的元素就可以按自然数的顺序排成一个无穷序列a1&#xff0c;a2&#…