当前位置:网站首页>ESP8266-----SNTP获取网络时间
ESP8266-----SNTP获取网络时间
2022-07-26 22:43:00 【Paradise_Violet】
目录
前言
介绍了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 Time
OLED_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); // 释放addr
sntp_init(); // SNTP初始化API
OS_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; // 计时=0
if(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上秒一直在走,说明它一直在不停地获取准确的网络时间。
边栏推荐
- Solve the problem that rsyslog service occupies too much memory
- Come and help you understand the mobile Internet in a minute
- RS485 signal measurement
- Doris or starrocks JMeter pressure measurement
- Six ways for the Internet of things to improve our lives
- Choose RTMP or RTC protocol for mobile live broadcast
- How does KS catch salt value? api,did?
- SQL learning (1) - table related operations
- Play guest cloud with zerotier nanny level teaching to ensure learning waste
- SQL关系代数——除法
猜你喜欢

Unity 使用NavMesh实现简易的摇杆功能

Solve the problem that rsyslog service occupies too much memory

Come and help you understand the mobile Internet in a minute

Website log collection and analysis process

VIS工作流 - PlantCV

The basic concept of how Tencent cloud mlvb technology can highlight the siege in mobile live broadcasting services

4.root用户登录

What is the digital economy and how does it change the business model?

顺序表之OJ题

Come and help you understand the Internet of things in three minutes
随机推荐
Next generation Internet: Video Networking
Scoring system based on 485 bus
6. 世界杯来了
5. Xshell connection server denied access, password error
5.xshell连接服务器拒绝访问,密码错误
梦想的旅程
05 - attack and defense of phishing websites
Unity UGUI Text文本框自适应
Surrounded area
记一次RawImage渲染出来的场景错乱
Li Hongyi machine learning (2017 Edition)_ P14: back propagation
Iptables detailed explanation and practical cases
c语言实现三子棋游戏
Jenkins--基础--5.2--系统配置--系统配置
The dependency of POM file is invalid when idea imports external projects. Solution
快来帮你三分钟了解物联网
Deep understanding of pod objects: basic management
Database interim (I)
x 的平方根
数据库期中(二)