学习日记——ESP8266SNTP

article/2025/8/21 22:30:24

SNTP基本知识

1、定义
SNTP是简单网络时间协议,而NTP网络时间协议就是网络计算机上同步计算时间的协议,具有高度的精确性,实际上也用不到这么高精度的算法。所以就在NTP上简化了以下变成SNTP,SNTP协议主要被用来同步因特网上计算机的时间。
2、工作方式
SNTP采用客户端/服务器的工作方式,可以采用单播或者广播的模式。
单播即客户端定期直接与SNTP服务器交互获取时间差进行校时。广播则是SNTP服务器定期向指定的多播地址发送时间信息,SNTP客户端通过监听这些多播地址来获取时间信息进行同步。UNIX网络编程中有SNTP广播方式的部分实现代码。
3、SNTP校时原理
SNTP协议主要是通过记录客户端向服务器发送数据包时的时间戳t1,服务器端接收到该数据包时的时间戳t2,服务器向客户端回应时的时间戳t3和最后客户端接收到服务器回应时的时间戳t4来计算客户端时间和服务器端时间的偏差,从而进行校时操作,如下图所示:
在这里插入图片描述
则t1与t2之间的时间差为((T2-T1)+ (T3-T4))/2
数据包在网络上的传播时间是 (T2-T1) + (T4-T3)

SNTP接口

1、sntp_setserver
功能:通过 IP 地址设置 SNTP 服务器,⼀共最多⽀持设置 3 个 SNTP 服务器
函数定义:void sntp_setserver(unsigned char idx, ip_addr_t *addr)
参数:
unsigned char idx:SNTP 服务器编号,最多⽀持 3 个 SNTP 服务器(0 ~ 2);0 号为主服务器,1 号和 2 号为备⽤服务器。
ip_addr_t *addr:IP 地址;⽤户需⾃⾏确保,传⼊的是合法 SNTP 服务器
返回:⽆
2、sntp_getserver
功能:查询 SNTP 服务器的 IP 地址,对应的设置接⼝为:sntp_setserver
函数定义: ip_addr_t sntp_getserver(unsigned char idx)
参数: unsigned char idx:SNTP 服务器编号,最多⽀持 3 个 SNTP 服务器(0 ~ 2)
返回:IP 地址
3、sntp_setservername
功能:通过域名设置 SNTP 服务器,⼀共最多⽀持设置 3 个 SNTP 服务器
函数定义:void sntp_setservername(unsigned char idx, char *server)
参数
unsigned char idx:SNTP 服务器编号,最多⽀持 3 个 SNTP 服务器(0 ~ 2);0 号为主服务器,1 号和 2 号为备⽤服务器。
char *server:域名;⽤户需⾃⾏确保,传⼊的是合法 SNTP 服务器
返回:无
4、sntp_getservername
功能:查询 SNTP 服务器的域名,仅⽀持查询通过 sntp_setservername 设置的 SNTP 服务器
函数定义:char * sntp_getservername(unsigned char idx)
参数: unsigned char idx:SNTP 服务器编号,最多⽀持 3 个 SNTP 服务器(0 ~ 2)
返回:服务器域名
5、sntp_init
功能:SNTP 初始化
函数定义:void sntp_init(void)
参数:⽆
返回:⽆
6、sntp_stop
功能:SNTP 关闭
函数定义:void sntp_stop(void)
参数:⽆
返回:⽆
7、sntp_get_current_timestamp
功能:查询当前距离基准时间 (1970.01.01 00:00:00 GMT + 8) 的时间戳,单位:秒
函数定义:uint32 sntp_get_current_timestamp()
参数:⽆
返回:距离基准时间的时间戳
8、sntp_get_real_time
功能:查询实际时间 (GMT + 8)
函数定义:char* sntp_get_real_time(long t)
参数:long t:与基准时间相距的时间戳
返回:实际时间
9、sntp_set_timezone
功能:设置时区信息
注意:调⽤本接⼝前,请先调⽤ sntp_stop
函数定义:bool sntp_set_timezone (sint8 timezone)
参数:sint8 timezone:时区值,参数范围:-11 ~ 13
返回:
true:成功
false:失败
示例:

 sntp_stop();if(	true	==	sntp_set_timezone(-5)	)	{sntp_init();}

10、.sntp_get_timezone
功能:查询时区信息
函数定义:sint8 sntp_get_timezone (void)
参数:⽆
返回:时区值,参数范围:-11 ~ 13

例程

首先在user_init函数中初始化串口,等待串口稳定后,使OLED显示初始化的内容,并且将ESP8266设置成STA模式,并且进行1秒钟的重复定时。这个user_init函数与之前UDP通信TCP通信的函数一样。区别在于需要OLED显示的内容不同。

void ICACHE_FLASH_ATTR user_init(void)
{uart_init(115200,115200);	// 初始化串口波特率os_delay_us(10000);			// 等待串口稳定os_printf("\t Project:\t%s\r\n", ProjectName);os_printf("\t SDK version:\t%s", system_get_sdk_version());// 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地址)
}

设置好STA相关参数后,获取IP地址,如果成功获取到IP地址后,就初始换SNTP。

void ICACHE_FLASH_ATTR ESP8266_STA_Init_JX()
{struct station_config STA_Config;	// STA参数结构体struct ip_info ST_ESP8266_IP;		// STA信息结构体// 设置ESP8266的工作模式wifi_set_opmode(0x01);				// 设置为STA模式,并保存到Flash/*// 设置STA模式下的IP地址【ESP8266默认开启DHCP Client,接入WIFI时会自动分配IP地址】
wifi_station_dhcpc_stop();						// 关闭 DHCP ClientIP4_ADDR(&ST_ESP8266_IP.ip,192,168,8,35);		// 配置IP地址IP4_ADDR(&ST_ESP8266_IP.gw,192,168,8,1);		// 配置网关地址IP4_ADDR(&ST_ESP8266_IP.netmask,255,255,255,0);	// 配置子网掩码wifi_set_ip_info(STATION_IF,&ST_ESP8266_IP);	// 设置STA模式下的IP地址*/// 结构体赋值,配置STA模式参数os_memset(&STA_Config, 0, sizeof(struct station_config));	// STA参数结构体 = 0os_strcpy(STA_Config.ssid,ESP8266_STA_SSID);				// 设置WIFI名os_strcpy(STA_Config.password,ESP8266_STA_PASS);			// 设置WIFI密码wifi_station_set_config(&STA_Config);	// 设置STA参数,并保存到Flash// wifi_station_connect();		// ESP8266连接WIFI
}

初始化SNTP函数。ESP8266最多设置三个SNTP服务器,其中SNTP服务器0是主服务器,剩下的两个是备用服务器。我们可以调用sntp_setservername(0, "us.pool.ntp.org");sntp_setserver(2, addr);API来设置服务器。参数1是SNTP的优先级。第一个API的参数2是SNTP的域名第二个API的参数2是指SNTP服务器的32位IP地址,在这个API之前调用ipaddr_aton("210.72.145.44", addr);API将字符串转换成点分二进制位32位的IP地址。之后调用sntp_init();这个API初始化SNTP。最后设置了1秒钟的重复定时。

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定时回调函数中使用TimeStamp = sntp_get_current_timestamp();获取当前距离基准时间的时间戳,基准时间为1970.01.01 00:00:00 GMT+8。如果这个时间戳不等于0,就说明我们的SNTP获取网络时间成功。我们调用下一个APIStr_RealTime = sntp_get_real_time(TimeStamp);参数为距离基准时间的时间戳,来获取当前时间的真实时间。接着串口打印时间戳和实际时间。之后我们根据获取到的实际时间用OLED显示。并且OLED显示读取到的温湿度

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("SNTP_TimeStamp = %d\r\n",TimeStamp);		// 时间戳os_printf("\r\nSNTP_InternetTime = %s",Str_RealTime);	// 实际时间// 时间字符串整理,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:湿度}}//-----------------------------------------------------------------------------------------
}

现象

下载程序,打开串口助手,复位ESP8266,等待几秒后。我们可以看到串口助手成功获取到距离基准时间的时间戳。
在这里插入图片描述
根据时间戳成功获取当前的实际时间,与我们电脑的网络时间一直,说明我们的ESP8266成功获取到我们准确的实际时间,ESP8266的OLED上可以显示当前的时间以及温湿度。我从OLED上看到时间会跟着时间时间一秒一秒的增加。
在这里插入图片描述

参考链接

https://www.bilibili.com/video/BV1dJ411S723?p=43
https://www.cnblogs.com/jiangzhaowei/p/8830583.html
https://zhidao.baidu.com/question/572961879.html


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

相关文章

WiFi开发|ESP8266模组SDK开发之SNTP协议

ESP8266模组SDK开发之SNTP协议 1. NTP和SNTP NTP 是网络时间协议(Network Time Protocol),是用来同步网络设备(如计算机、手机)的时间的协议 SNTP由NTP改编而来(简单网络时间协议,Simple Net…

ESP8266学习笔记(11)——SNTP接口使用

一、SNTP简介 简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟 二、SNTP接口 SNTP 接口位于 ESP8266_NONOS_SDK/include/sntp.h。 三、初始化SNTP 设置三个时间服务器…

ESP32 SNTP配置

SNTP,Simple Network Time Protocol(简单网络时间协议),用来同步时钟。 百度百科:SNTP SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点&…

通过sntp同步系统时间

通过sntp同步系统时间 小型物联网设备,很少有接口提供给用户进行数据交互,那么我们设备的系统时间只能够通过获取网络时间后,再更新到本地。那么,就少不了使用sntp协议。 ntp协议:NTP(Network Time Protocol&#xff…

2012系统sntp服务器,如何设置SNTP服务器,实现同步PLC时钟

在过程/生产自动化系统构架和运行时,有时需要实现对时间的精确控制,即系统中所有子系统(包括设备等)的时间必须保持同步。 作为自动化系统组成部分的 以Windows 7操作系统为例,将PC机配置为SNTP服务器端的操作步骤: [注意]操作前前…

ESP32学习笔记(41)——SNTP接口使用

一、SNTP简介 简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟。 SNTP 协议是用来同步本地的时间到 unix 时间戳。通常嵌入式设备上电,连接 AP(access point)&…

物联网专题27:SNTP

什么是SNTP(Simple Network Time Protocol)?简单时钟控制协议,主要用来同步因特网中的计算机时钟。 SNTP,使用的默认端口号是 UDP123。 ESP8266中,SNTP相关的API: 1 设置SNTP服务器&#xff08…

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

目录 前言 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); // 等待串口…

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

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

ESP32 SNTP设置

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

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

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

sntp 校时问题

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

ESP8266_SNTP(Simple Network Time Protocol)

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

WIFI学习六(SNTP)

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

SNTP简介

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

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

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

使用SNTP协议获取时间

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

sntp协议简介

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

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

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

来聊聊马尔可夫过程

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