esp12实现的网络时钟校准

网络时间的获取是通过向第三方服务器发送GET请求获取并解析出来的。

在本篇博客中,网络时间的获取是一种自动的行为,当系统成功连接WiFi获取到网络天气后,系统将自动获取并解析得到时间和日期,为了减少误差每两分钟左右进行一次校准。在网络时间成功获取后,定时器中时间计数从这个数开始,并且到达一定数目,系统自动更新上下午和日期信息。

时间日期显示设计如图所示:

访问网络服务器校准网络时钟,需要了解服务器返回给我们的json字符串格式。可以用CJSON库进行解析,但是这里我采用手动解析。

            {
            "success": "1",
            "result": {
            "timestamp": "1718090343",
            "datetime_1": "2024-06-11 15:19:03",
            "datetime_2": "2024年06月11日 15时19分03秒",
            "week_1": "2",
            "week_2": "星期二",
            "week_3": "周二",
            "week_4": "Tuesday"
                }
            }

对应的接收代码

if(comGetChar(COM3,&getChar))
{	
		switch(state)
		{
			case 0:
				if(getChar == '{'){ state=1;}
						Recv_len=0;
						break;
					case 1:
						if(getChar == '}') 
						{
							state=0;
							Recv_CommandFlag=TIMERECV;
						}
						else
						{
							*(Recv_Buf+Recv_len) = getChar;
							Recv_len++;
							printf("%c",getChar);
							if(Recv_len>=210)
							{
								Recv_CommandFlag=UNRECV;
								state=0;
							}
						}
						break;
					default:
						break;
				}
			}

 解析调用

Recv_CommandFlag = 0;
		ret = timeParse(Recv_Buf);
		if(ret == 0)
		{
			Times_Change(myday,mymonth,myyear);    //计算当前日期
			Display_days(myyear, mymonth, myday);  //显示日期
			GetTimes(myhour,myminute,mysecond);Display_time(TIMES);
		}else{
			printf("\r\ntimeParse fail\r\n");
		}
		NetStatus=ESP_TLINK_INIT;//回去弄tlink看看是不是有网

mytime.c

#include "mytime.h"
#include "esp8266.h"

volatile uint32_t TIMES = 0;

void GetTimes(char h,char m, char s )
{
	TIMES=h*60*60+m*60+s;
	return;
}
void Times_Change(unsigned char d, unsigned char m, int y)
{
	if(m == 2)    //如果是2月
	{
		 if(d == 29)
		 {
			 if(!((((y%4) == 0) && ((y%100) != 0)) || ((y % 400) == 0)))  //如果不是闰年
			 {
				m ++;    
				d = 1;
			 }
		 }
		 else if(d == 30)
		 {
			 if((((y%4) == 0) && ((y%100) != 0)) || ((y % 400) == 0))  //如果是闰年
		   {
				m ++;    
				d = 1;
		   }
		 }	 
	}
	 else if(d == 31)
	 {
		  if(m == 4 | m == 6 | m == 9 | m == 11)
		  { 
			  m ++; 
			  d = 1;
		  }
	 }
	 else if(d > 31)
	 {							 
		if(m == 12)
		{
		  y ++;
		  m = 1;
		  d = 1;
		}								 
		else
		{
			m ++; 
			d = 1;
		}
	 }
}


/*-------------------------------------------------------------
 *计算时间函数  
 *起始页地址  宏定义  TIME_START_PAGE
 *起始列地址  宏定义  TIME_START_COL
 *时间  times   为0~86399,即24小时最大秒数
 *分别计算出时 分 秒 上 下午 并显示在相应位置
 *-------------------------------------------------------------*/
void Display_time(unsigned int times)    
{
	char timeStr_lvgldisp[30];
	unsigned int temp_time = times;
	unsigned char temp_hour, temp_minutues, temp_seconds;
	unsigned char t_h_ten, t_h_one, t_m_ten, t_m_one, t_s_ten, t_s_one;
	char timewhen;
	
	temp_hour = times / 3600;            //得到小时数
	temp_minutues =(times % 3600) / 60;  //得到分钟数
	temp_seconds = (times % 3600) % 60;  //得到秒数
	
	myhour=temp_hour;
	myminute=temp_minutues;
	mysecond=temp_seconds;
	
	t_h_ten = temp_hour / 10;          //取小时十位数
	t_h_one = temp_hour % 10;          //取小时个位数
	t_m_ten = temp_minutues /10;       //取分钟十位数
	t_m_one = temp_minutues %10;       //取分钟个位数
	t_s_ten = temp_seconds /10;        //取秒十位数
	t_s_one = temp_seconds %10;        //取秒个位数
	
	
	if(temp_time < 43200)    //上午
	{
		timewhen='A';
	}
	else  //下午
	{
		timewhen='P';
	}
	sprintf((char *)timeStr_lvgldisp, "%d%d:%d%d:%d%d-%cM",t_h_ten,t_h_one,t_m_ten,t_m_one,t_s_ten,t_s_one,timewhen);
	printf("\r\ntimeStr:%s\n\r",(char *)timeStr_lvgldisp);
}

/*-------------------------------------------------------------
 *计算日期和星期函数
 *日期起始页地址  宏定义  DAYS_START_PAGE
 *日期起始列地址  宏定义  DAYS_START_COL
 *星期起始页地址  宏定义  WEEK_START_PAGE
 *星期起始列地址  宏定义  WEEK_START_COL
 *日期  days   为0~86399,即24小时最大秒数
 *计算出星期 和日期 并显示在相应位置
 *
 * 吉姆拉尔森公式:w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)mod7
 *w:week, y = year , m = moon, d = day , 1月=13月,2月=14月
 *w = 0,星期一 ~ w = 6,星期日 
 *-------------------------------------------------------------*/
void Display_days(int year, unsigned char moon, unsigned char day)
{
	char dateStr[20];
	int temp_year, temp_moon, temp_day, temp_week;
	unsigned char t_y_frist, t_y_second, t_y_thrid, t_y_forth;
	unsigned char t_m_ten, t_m_one, t_d_ten, t_d_one;
	int y, m, d;

	temp_year = year;
	temp_moon = moon; 
	temp_day = day;
	  
	t_y_frist = temp_year / 1000;
	t_y_second = (temp_year % 1000) / 100;
	t_y_thrid = (temp_year % 100) / 10;
	t_y_forth = temp_year % 10;

	t_m_ten = temp_moon / 10;
	t_m_one = temp_moon % 10;
	t_d_ten = temp_day / 10;
	t_d_one = temp_day % 10;

	y = year;
	m = moon;
	d = day;

	if((m == 1) || (m == 2))
	{
		m += 12;
		y --;
	}
	temp_week = ((d +2*m + 3*(m + 1) / 5 + y +y/4 - y /100 +y/400)%7)+1;   //计算星期几 
	myweek = temp_week;  //汉字一为第1个字符,方便计算
	
	sprintf((char *)dateStr, "%d%d%d%d-%d%d-%d%d:%d",t_y_frist,t_y_second,t_y_thrid,t_y_forth,t_m_ten,t_m_one,t_d_ten,t_d_one,temp_week);
	printf("dateStr:%s\n\r",(char *)dateStr);
}





mytime.h

#ifndef __MYTIME__
#define __MYTIME__

#include "stdint.h"

extern volatile uint32_t TIMES;

//extern char timeStr_lvgldisp[30];

void Times_Change(unsigned char d, unsigned char m, int y);
void Display_time(unsigned int times);
void Display_days(int year, unsigned char moon, unsigned char day);
void GetTimes(char h,char m, char s );

#endif

发起请求

ESP_Fefresh_NET_Massage(wifi_ssid,wifi_password,time_address,time_point,GetNet_Time);	
//time
char time_keystr[150]="GET http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json&HTTP/1.1\r\n";
char time_address[25]="api.k780.com";
char time_point[5]="88";

//日期时间变量
int myyear=2024;
int mymonth=6;
int myweek=3;
int myday=12;
int myhour=21;
int myminute=31;
int mysecond=56;

char subdatetime_1[20]; 
//char subdatetime_2[8];

u8 timeParse(char * timestr)
{
	char *datetime1_start = strstr(timestr,"datetime_1"); 
	if (datetime1_start != NULL) 
	{
		datetime1_start += (strlen("datetime_1")+3); 
		strncpy(subdatetime_1, datetime1_start, 19); 
		subdatetime_1[19] = '\0'; 
		printf("datetime_1: %s\r\n", subdatetime_1);
		sscanf(subdatetime_1, "%d-%d-%d %d:%d:%d", &myyear, &mymonth, &myday, &myhour, &myminute, &mysecond);
		GetTimes(myhour,myminute,mysecond);
		return 0;
	} else {
		printf("\r\nKey not found\r\n");
		return 1;
	}
}

/*-------------------------------------------------
 * 更新网络时间函数
 * 已经连接WIFI,定期连接TCP更新网络时间
-------------------------------------------------*/

u8 ESP_Fefresh_NET_Massage(char *ssid,char *pwd,const char *tcp_addr, char *point, void (*function)())
{
	char tcp_information[160]={0};
	char wifi_information[56]={0};   //WiFi热点临时数组

	u8 return_temp = 0;
	 
	comSendBuf(COM3, (uint8_t *)"+++", 3);
	vTaskDelay(3000);
	ESP12_SendAT("AT");
	if (ESP12_WaitResponse("OK", 5000) != 1)
	{
		printf("\r\n AT fail!\r\n");
		failnum|=(1<<0);
		//vTaskDelay(1000);
	}	
	ESP12_SendAT("ATE0");
	if (ESP12_WaitResponse("OK", 5000) != 1)
	{
		printf("\r\n ATE0 fail\r\n");
		failnum|=(1<<1);vTaskDelay(1000);
	}	
	
	ESP12_SendAT("AT+CWMODE=1");
	if (ESP12_WaitResponse("OK", 5000) != 1)
	{
		printf("\r\n CWMODE fail\r\n");
		failnum|=(1<<2);vTaskDelay(2000);
	}
	
	sprintf(wifi_information, "AT+CWJAP=\"%s\",\"%s\"", ssid, pwd);  //将WiFi热点名称和密码			
	ESP12_SendAT(wifi_information);
	if (ESP12_WaitResponse("OK", 5000) != 1)
	{
		printf("\r\n CWJAP fail\r\n");
		failnum|=(1<<3);
		//vTaskDelay(1000);
	}
	
	sprintf(tcp_information, "AT+CIPSTART=\"TCP\",\"%s\",%s", tcp_addr, point);  //将TCP,地址和端口号传给临时变量
	//	printf("%s\n",tcp_information);
	ESP12_SendAT(tcp_information);
	if (ESP12_WaitResponse("OK", 5000) != 1)
	{
		printf("\r\n CIPSTART fail\r\n");
		failnum|=(1<<4);//vTaskDelay(1000);
	}
	
	ESP12_SendAT("AT+CIPMODE=1");
	if (ESP12_WaitResponse("OK", 3000) != 1)
	{
		printf("\r\n CIPMODE fail\r\n");
		failnum|=(1<<5);//vTaskDelay(1000);
	}
	
	ESP12_SendAT("AT+CIPSEND");
	if (ESP12_WaitResponse("OK", 1000) != 1)
	{
		printf("\r\n CIPMODE fail\r\n");//vTaskDelay(1000);
		failnum|=(1<<6);
	}
	// Send KeyStr
	function();
	
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/751621.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】创建 swarm 集群

目录 1. 更改防火墙设置 2. 安装 Docker 组件 3. 启动 Docker 服务&#xff0c;并检查服务状态。 4. 修改配置文件&#xff0c;监听同一端口号。 5. 下载 Swarm 组件 6. 创建集群&#xff0c;加入节点 7. 启动集群 8. 查询集群节点信息 9. 查询集群具体信息 10. 查询…

用Python设置Excel工作表网格线的隐藏与显示

Excel表格界面的直观性很大程度上得益于表格中的网格线设计&#xff0c;这些线条帮助用户精确对齐数据&#xff0c;清晰划分单元格。网格线是Excel界面中默认显示的辅助线&#xff0c;用于辅助定位&#xff0c;与单元格边框不同&#xff0c;不影响打印输出。然而&#xff0c;在…

【Linux:文件描述符】

文件描述符&#xff1a; 文件描述符的分配原则&#xff1a;最小未分配原则 每一个进程中有一个task_struct结构体&#xff08;PCB)&#xff0c;而task_struct中含有struct file_sturct*file的指针&#xff0c;该指针指向了一个struct files_struct的结构体该结构体中含有一个f…

Python27 神经网络中的重要概念和可视化实现

1. 神经网络背后的直观知识 神经网络的工作方式非常相似&#xff1a;它接受多个输入&#xff0c;经过多个隐藏层中的多个神经元进行处理&#xff0c;并通过输出层返回结果&#xff0c;这个过程在技术上称为“前向传播”。 接下来&#xff0c;将神经网络的输出与实际输出进行比…

Java | Leetcode Java题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; class Solution {private static Set<Integer> cycleMembers new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));public int getNext(int n) {int totalSum 0;while (n > 0) {int d n % 10;n n / 10;totalS…

Windows下activemq开启jmx

1.activemq版本信息 activemq&#xff1a;apache-activemq-5.18.4 2.Windows下activemq开启jmx 1.进入activemq conf目录&#xff0c;备份activemq.xml文件 2.编辑activemq.xml文件&#xff0c;在broker节点增加useJmx"true" <broker xmlns"http://active…

Vuetify3:​快捷回到顶部

在Vuetify 3中&#xff0c;要实现回到顶部&#xff0c;我们需要创建悬浮按钮&#xff0c;如下&#xff1a; <template><v-list><div class"position-fixed right-0 bottom-0" style"top:50%;"><v-list-item ><v-btn icon"…

黑马点评项目总结1-使用Session发送验证码和登录login和 使用Redis存储验证码和Redis的token登录

黑马先是总结了从session实现登录&#xff0c;然后是因为如果使用了集群方式的服务器的话&#xff0c;存在集群共享session互相拷贝效率低下的问题&#xff0c;接着引出了速度更快的内存型的kv数据库Redis&#xff0c; 使用Session发送验证码和登录login 举个例子&#xff1a…

『Django』模型入门教程-操作MySQL

theme: smartblue 点赞 关注 收藏 学会了 本文简介 一个后台如果没有数据库可以说废了一半。日常开发中大多数时候都在与数据库打交道。Django 为我们提供了一种更简单的操作数据库的方式。 在 Django 中&#xff0c;模型(Model)是用来定义数据库结构的类。每个模型类通常对…

kali下安装使用蚁剑(AntSword)

目录 0x00 介绍0x01 安装0x02 使用1. 设置代理2. 请求头配置3. 编码器 0x00 介绍 蚁剑&#xff08;AntSword&#xff09;是一个webshell管理工具。 官方文档&#xff1a;https://www.yuque.com/antswordproject/antsword 0x01 安装 在kali中安装蚁剑&#xff0c;分为两部分&am…

matlab绘制二维曲线,如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表标注、在图中标记想要的点

matlab绘制二维曲线&#xff0c;如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表如何标注、如何在图中标记想要的点 matlab绘制二维曲线&#xff0c;如何在图中标记想要的点。。。如何设置线型、颜色、标记点类型。。。如何设置坐标轴。。。matlab 图表标注操作…

视频网站系统

摘 要 随着互联网的快速发展和人们对视频内容的需求增加&#xff0c;视频网站成为了人们获取信息和娱乐的重要平台。本论文基于SpringBoot框架&#xff0c;设计与实现了一个视频网站系统。首先&#xff0c;通过对国内外视频网站发展现状的调研&#xff0c;分析了视频网站的背景…

潮玩手办盲盒前端项目模版的技术探索与应用案例

一、引言 在数字化时代&#xff0c;随着消费者对个性化和艺术化产品的需求日益增长&#xff0c;潮玩手办和盲盒市场逐渐崭露头角。为了满足这一市场需求&#xff0c;前端技术团队需要构建一个功能丰富、用户友好的在线平台。本文旨在探讨潮玩手办盲盒前端项目模版的技术实现&a…

C++ | Leetcode C++题解之第201题数字范围按位与

题目&#xff1a; 题解&#xff1a; class Solution { public:int rangeBitwiseAnd(int m, int n) {while (m < n) {// 抹去最右边的 1n n & (n - 1);}return n;} };

序列检测器(Moore型)

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 参考代码 描述 请用Moore型状态机实现序列“1101”从左至右的不重叠检测。 电路的接口如下图所示。当检测到“1101”&#xff0c;Y输出一个时钟周期的高电平脉冲。 接口电路图如下&#xff1a; 输入描述&#xff1a…

携程任我行有什么用?

眼看一直到十月份都没啥假期了 五一出去玩买了几张携程的卡&#xff0c;想着买景点门票、酒店啥的能有优惠&#xff0c;但最后卡里的钱没用完不说&#xff0c;还有几张压根就没用出去 但是我又不想把卡一直闲置在手里&#xff0c;就怕过期了 最后在收卡云上99.1折出掉了&…

注意力机制在大语言模型中的应用

在大语言模型中&#xff0c;注意力机制&#xff08;Attention Mechanism&#xff09;用于捕获输入序列中不同标记&#xff08;token&#xff09;之间的关系和依赖性。这种机制可以动态地调整每个标记对当前处理任务的重要性&#xff0c;从而提高模型的性能。具体来说&#xff0…

Py之dashscope:dashscope的简介、安装和使用方法、案例应用之详细攻略

Py之dashscope&#xff1a;dashscope的简介、安装和使用方法、案例应用之详细攻略 目录 dashscope的简介 1、产品的主要特点和优势包括&#xff1a; dashscope的安装和使用方法 1、安装 2、使用方法 dashscope的案例应用 1、通义千问-Max&#xff1a;通义千问2.5系列 2…

Ubuntu Nvidia GPU驱动安装和故障排除

去官网 菜单列表下载&#xff0c;或者直接下载驱动 wget https://cn.download.nvidia.com/XFree86/Linux-x86_64/550.54.14/NVIDIA-Linux-x86_64-550.54.14.run 安装驱动 /data/install/NVIDIA-Linux-x86_64-550.54.14.run 执行命令&#xff0c;显示GPU情况 出错处理&…