当前位置:   article > 正文

从零开始制作一个基于STM32和ESP8266-01S的智能时钟(4)ESP8266-01S模块(下)(高德天气API)_2.已知有字符串'星期*,温度*℃,天气*',其中*会随用户输入的数据而变化。 请通过

2.已知有字符串'星期*,温度*℃,天气*',其中*会随用户输入的数据而变化。 请通过


前言

提示:这里可以添加本文要记录的大概内容:

本项目需要基础的stm32单片机知识,这里我推荐
链接:https://www.bilibili.com/video/BV1th411z7sn?p=1&vd_source=e9ab6ae9ee7c74bb73c9334f2da0a743
如果不想看那么多,看到4-2 OLED显示屏就差不多。我使用的是他的OLED基本例程。


提示:在这里我使用了UsartPrintf()函数打印esp8266_buf数组,但是我之前提到了UsartPrintf()函数里面局部定义的数组只有296个,但是esp8266_buf数组我重新定义有400个,所以需要修改UsartPrintf()函数里面的数组为400个才不会出现数据丢失的情况。

一、高德地图API

1.获取key

首先,我们需要根据高德地图API的入门指南获取一下API。

在这里插入图片描述

第一步,按照网址指示:https://lbs.amap.com/api/webservice/guide/create-project/get-key,申请Web服务API密钥。

在这里插入图片描述

之后会得到一个Key,可以使用的服务如下

在这里插入图片描述

2.IP定位

然后这里我们用到了IP定位、逆地理编码、天气查询的API,不懂的可以点进去学习一下

在这里插入图片描述

“若用户不填写IP,则取客户HTTP之中的请求来进行定位”,所以我们如果想要获取本地的IP,只需要在ESP8266连接高德地图tcp后进入数据交换模式后发送如下指令,即可获得用户IP地址的定位。(需要加回车换行符,这个key需要填上你们上面申请到的key)

GET https://restapi.amap.com/v3/ip?&key=ef8466d69928146d187ea512e8a7936a\r\n

为了STM32可以完整地获取到返回的数据我们需要定义一个接收函数。这个函数可以根据参数自行定义等待时间,并且接收完成一帧数据后,会通过串口1输出一帧数据和其个数,方便调试。经过这个延时等待接收完成的函数,我们可以获得接收完成的esp8266_buf数组。

/*
溢出时间 = 输入*10ms
*/
void wait_rev(uint16_t time_out)
{
	uint16_t timeout;		//定义溢出时间间隔
	for(timeout = time_out; timeout>0; timeout--)
	{
		if(ESP8266_WaitRecive() == REV_OK)	//如果接收一帧数据完成
		{
			UsartPrintf(USART_DEBUG,"%d\r\n",esp8266_cnt);		//通过串口1输出一帧数据的个数
			UsartPrintf(USART_DEBUG, "%s\r\n", esp8266_buf);	//通过串口1输出一帧数据
			break;		//接收完成退出循环,避免浪费时间
		}

		Delay_ms(10);		//每次等待时间
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

发送获取IP指令后,串口助手返回如图,乱码是因为高德地图返回的中文编码方式为UTF-8,而串口助手无法显示UTF-8编码的字符所以会出现乱码。(可以下载一个可以显示UTF-8编码的串口助手,如:SingTownSerialport,方便后续调试)。为了测试GET后面的URL是否能够成功通信,可以直接把GET后面的网址使用浏览器打开,打开后出现如下画面即证明URL是可以通信的。

在这里插入图片描述

这里的返回值我们只需要取出对应IP地址的经纬度,即“rectangle”部分,只需要第一个就可以。

在这里插入图片描述

逆地址编码API是可以根据提供的经纬度,返回较为准确的位置和地区编码,所以我们使用上面获取到的IP地址经纬度,再将经纬度放到这里,就可以获得IP地址区级的地区编码。ESP-01S指令如下

GET https://restapi.amap.com/v3/geocode/regeo?key=ef8466d69928146d187ea512e8a7936a&location=112.3483157,22.96136686\r\n

串口返回如下:

在这里插入图片描述

返回的数值为79是因为接收到的数据总数已经超过了接收数组定义的400bit,而当超过时,中断函数会将接收值置零,采用覆盖接收的方式继续接收,所以这里的79代表了已经有79bit数据被覆盖掉,但是那些丢失的数据并不重要,为了节省资源,这里就采用这种方法接收。这些数据中我们需要的是地区编码:adcode:441204;我们只需要将441204提取出来即可。

同样的可以将网址直接打开,查看是否能够成功与网站通信。
在这里插入图片描述

这里我通过get_ip_data()函数获取ip地址对应的地址区县编码。先给ESP-01S发送获取IP地址的命令,然后通过wait_rev(200)函数等待接收完成,将经纬度提取出来。然后将经纬度放到获取逆地理编码命令中,发送给ESP-01S,等待接收完成,将IP地址对应的区县编码提取出来放到获取天气信息的命令中,为后续获取当地的天气信息做准备。

unsigned char get_ip_cmd_packback[] = "GET https://restapi.amap.com/v3/ip?&key=ef8466d69928146d187ea512e8a7936a\r\n";	//获取IP地址的命令

const char *get_adcode_cmd_dead = "GET https://restapi.amap.com/v3/geocode/regeo?key=ef8466d69928146d187ea512e8a7936a&location=";		//获取地址编码命令的开头部分

unsigned char  get_weather_cmd_packback[] = "GET https://restapi.amap.com/v3/weather/weatherInfo?city=440511&key=ef8466d69928146d187ea512e8a7936a\r\n";	//获取相应地址天气的命令

/*获取IP的地址编码并放到获取天气命令中*/
void get_ip_data(void)
{
	char *data_set_start;		//需要的数据开始位置
	char *data_set_end;			//需要的数据结束位置
	char latitude[30];		//经纬度字符数组
	char get_adcode_cmd_packback[130];		//获取地区编码命令
	char adcode[6];		//地区编码数组,地区编码都为6位
	char *processing_change_city_adcode;	//需要修改编码的位置
	
	Usart_SendString(USART2,get_ip_cmd_packback, sizeof(get_ip_cmd_packback));	//发送获取IP地址命令
	
	wait_rev(200);	//等待接收完成
	
	data_set_start = &strstr((const char*)esp8266_buf, "rectangle")[12];	//找经纬度开始位置
	
	data_set_end = strstr(data_set_start, ";");		//找经纬度结束位置
	
	i = 0;
	i = data_set_end - data_set_start;	//计算经纬度字符串长度
	
	memcpy(latitude, data_set_start, i);		//将经纬度字符串放到latitude数组
	
	UsartPrintf(USART_DEBUG, "%s\r\n", latitude);		//串口1输出经纬度字符串,用于调试
	
	/*将获取地址编码命令补充完整*/
	strcat(get_adcode_cmd_packback, get_adcode_cmd_dead);		
	strcat(get_adcode_cmd_packback, latitude);
	strcat(get_adcode_cmd_packback, "\r\n");
	
	UsartPrintf(USART_DEBUG, "%s\r\n", get_adcode_cmd_packback);	//串口1输出获取地址编码命令,用于调试
	
	ESP8266_Clear();	//清除esp8266_buf数组
	
	Delay_s(1);	//ESP-01S发送命令不能过快,所以需要延时1s
	
	Usart_SendString(USART2, (unsigned char*)get_adcode_cmd_packback, strlen(get_adcode_cmd_packback));	//发送获取地址编码命令
	
	wait_rev(200);	//等待接收完成
	
	data_set_start = &strstr((const char*)esp8266_buf, "adcode")[9];	//找地址编码开始位置
	
	/*将地址编码放到adcode数组*/
	for(i=0; i<sizeof(adcode); i++)
	{
		adcode[i] = data_set_start[i];		
	}
	
	UsartPrintf(USART_DEBUG,"\r\n%s\r\n",adcode);	//串口1输出adcode数组,用于调试
	
	processing_change_city_adcode = &strstr((const char*)get_weather_cmd_packback, "city=")[5];	//获取需要修改编码的位置
	
	/*用新的地址编码代替旧的地址编码*/
	for(i=0; i<sizeof(adcode); i++)
	{
		processing_change_city_adcode[i] = adcode[i];		
	}
	
	UsartPrintf(USART_DEBUG,"%s\r\n",get_weather_cmd_packback);	//串口1输出修改完的获取天气命令,用于调试
	
	ESP8266_Clear();	//清除esp8266_buf数组
	
	Delay_s(1);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

串口调试返回如图
在这里插入图片描述
在这里插入图片描述

3.获取地区名和天气

天气查询API是一个简单的HTTP接口,根据用户输入的adcode,查询目标区域当前/未来的天气情况,数据来源是中国气象局。
在这里插入图片描述

天气API可以根据输入的城市编码获取实时的天气信息,其ESP-01S指令如下

GET https://restapi.amap.com/v3/weather/weatherInfo?city=440511&key=ef8466d69928146d187ea512e8a7936a\r\n

所以我们只需要将前面获取到的adcode编码放到city参数里即可获取IP地址对应的天气信息。这个在上面get_ip_data()函数里面已经处理好了。所以get_weather_data()函数只需要发送获取天气命令,等待接收完成,然后将我们需要的信息放到processing_data数组中,处理完成后,processing_data数组就是我们需要的包含天气信息和地区名字的json数据包。

/*获取天气信息,将需要的json数据包放到processing_data数组中,等待处理*/
void get_weather_data(void)
{
	char *weather_set_start;	//天气开始的位置
	char *weather_set_end;	//天气结束的位置
	
	Usart_SendString(USART2, get_weather_cmd_packback, sizeof(get_weather_cmd_packback));	//发送获取天气指令
	
	wait_rev(200);
	
	weather_set_start = strstr((const char*)esp8266_buf, "\"city\"");	//获取esp8266_buf数组中以\city\开头的字符串地址
	
	weather_set_end = strstr((const char*)esp8266_buf, ",\"temperature\"");	//获取esp8266_buf数组中以,\temperature\开头的字符串地址
	
	strncpy(&processing_data[1], weather_set_start, weather_set_end - weather_set_start);	//将\city\到,\temperature\的数据放到processing_data[1]的位置
	
	/*在数组的开始和结尾补上{}符号变成json格式数据*/
	processing_data[0] = '{';
	processing_data[weather_set_end - weather_set_start + 1] = '}';
	
	UsartPrintf(USART_DEBUG,"%s\r\n",processing_data);	//串口1输出得到的json格式数据,用于调试
	
	ESP8266_Clear();	//清除esp8266_buf数组
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

串口返回如下

310
{“status”:“1”,“count”:“1”,“info”:“OK”,“infocode”:“10000”,“lives”:[{“province”:“广东”,“city”:“高要区”,“adcode”:“441204”,“weather”:“多云”,“temperature”:“34”,“winddirection”:“东南”,“windpower”:“≤3”,“humidity”:“64”,“reporttime”:“2023-07-01 16:00:44”,“temperature_float”:“34.0”,“humidity_float”:“64.0”}]}
{“city”:“高要区”,“adcode”:“441204”,“weather”:“多云”}

上面黄色的部分就是将地区和天气从接收数据中提取出来并处理成json数据格式的数据包(编码格式为UTF-8)。
有人可能要问,这整个数据就已经是完整的json数据格式的数据包,为什么不直接使用json库函数处理,而要多此一举将一部分信息提取出来,自己加上{}组成json格式?
这是因为一开始,我直接使用json库函数处理会出现bug,后面发现是因为建立json类会占用大量内存空间导致内存溢出,所以会出现解析错误的情况,所以如果减少json处理的信息,就能解决这个bug。(还有一种办法是直接修改STM32的内存容量,怎么改自己上网搜索)所以我使用了上面的办法自己建立一个简短的json数据包。(其实还可以像上面一样使用多次strstr获取到地区和天气的数据包,不过这里就学习一下json数据包是怎么使用的吧)

4.时间

时间我这里是直接使用发送GET命令给高德地图服务器的方法获取的。ESP-01S的指令如下:

GET\r\n

ESP-01S的返回如下图
在这里插入图片描述

里面会返回一个实时时间如红框所示,所以我们只要将它提取出来就可以获得实时时间。但是这里返回的数据是远远超过了400bit的,所以会应用到接收中断函数里面超过了400bit就会从零开始覆盖的方法。覆盖会过滤掉我们不需要的信息,只留下我们需要的信息。

实际接收到的esp8266_buf里面的数据如下图
在这里插入图片描述
这里其实已经覆盖了2遍了,但是我们需要的日期时间信息没有丢失就没有问题。所以这里我们调用get_time_data()函数将需要的日期时间字符串放到processing_data数组中。

#define time_len 14	//日期时间字符串长度
char processing_data[60];		//接收esp8266_buf中处理完成的数据

/*获取日期时间信息,将需要的日期时间字符串放到processing_data数组中,等待处理*/
void get_time_data(void)
{
	char *time_set_start;	//时间开始的位置
	
	Usart_SendString(USART2,get_time_cmd_packback, sizeof(get_time_cmd_packback));	//天气开始的位置
	
	wait_rev(200);
	
	time_set_start = &strstr((const char*)esp8266_buf, "Date:</td>")[21];	//获取时间开始位置
	
	strncpy(processing_data, time_set_start, time_len);	//将需要的日期时间字符串放到processing_data数组中,时间长度为14
	
	UsartPrintf(USART_DEBUG, "\r\n%s\r\n", processing_data);	//串口1输出得到时间数据,用于调试
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

串口1返回如下,表明成功将日期和时间字符串提取出来了。
在这里插入图片描述

二、使用方法

为了时间准确,我开启了TIM2定时器,每秒钟计数一次。每秒钟手动更新日期时间并且显示,每分钟使用网络更新天气信息和日期时间。

/*定时器中断函数*/
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		/*timeCount计数超过60代表出错了,所以使timeCount变为初始值,重置*/
		if(timeCount>60)
		{
			timeCount = 59;
		}
		
		timeCount++;	//每秒钟timeCount+1
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);	//清除标志位
	}
}

/*TIM2定时器初始化函数*/
void MY_TIME_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, DISABLE);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

我们知道发送给ESP8266的指令不能太快,所以前面我每次发送指令后都会延时1s。为了实时更新天气信息和时间的时分,每过1分钟我需要发送获取天气指令和获取时间指令,为了分开两个指令,当时间过去了59s时,获取天气信息。当时间过去了60s时,获取时间信息。
因为程序只会更新时间的秒数,而时间的时和分都是通过ESP-01S返回的信息实时更新的,所以需要知道实时时间的秒数,才能准确地完成刚好到一分钟时更新时间的时和分。所以这里我定义了一个timeCount 变量记录当前时间的秒数。每当timeCount 发生变化时,证明过了1s,如果timeCount 为59时,代表当前时间秒数为59s,这时我们更新天气信息。如果timeCount 为60时,代表当前时间秒数为60s,这时我们更新时间信息,及时更新时间的时分和日期,并且将当前时间的秒数提取出来更新timeCount变量。如果timeCount即不为59s也不为60s,表明只是0-57过去了1s,所以我们需要手动更新时间的秒数,并且为了中断接收不影响光照度和温湿度的每秒检测,在这里完成测量。

uint8_t timeCount = 59;	//时间变量(取值范围为0-60)

int main(void)
{	
	uint8_t time_pre = 0;	//前一秒时间
	
	uint8_t weather_string_len_pre = 0;	//记录天气字符串长度
	
	cJSON* json;	//创建cjson类
	cJSON* json_name;	//创建cjson类
	
	char time_string[time_len];	//日期时间数组
	
	Delay_Init();	//延时初始化
	OLED_Init();	//OLED初始化
	BH1750_Init();	//BH1750模块初始化
//	LED_Init();
//	key_Init();
//	My_EXTI_Init();
	Usart1_Init(115200);							//串口1初始化,打印信息用
	Usart2_Init(115200);							//串口2初始化,驱动ESP8266用
	
	ESP8266_Init();	//ESP8266初始化
	MY_TIME_Init();	//TIM2初始化
	
	Delay_s(1);
	
	get_ip_data();	//获取IP地址信息
	
	TIM_Cmd(TIM2, ENABLE);	//使能TIM2定时器
	
	while(1)
	{
		/*如果time_pre不等于timeCount 代表时间过去了1s*/
		if(timeCount != time_pre)
		{
			/*如果timeCount为59s,获取天气信息*/
			if(timeCount == 59)		
			{
					OLED_ShowString(2, 14, "9");	//手动更新OLED的时间为59s
				
					get_weather_data();	//获取天气信息

					json = cJSON_Parse((const char*)processing_data); //创建JSON解析对象,返回JSON格式是否正确
					
					processing_data_clean();	//清空数组
					
					if(json == NULL)
					{
						UsartPrintf(USART_DEBUG, "error:%s", cJSON_GetErrorPtr()); //输出json格式错误信息
					}
					
					json_name = cJSON_GetObjectItem(json, "weather"); //获取weather键对应的值的信息
					
					/*如果前一个天气字符串长度和当前天气字符串长度不同,执行一次OLED清屏,防止前一次的字符串出现*/
					if(weather_string_len_pre != strlen(json_name->valuestring))
					{
						OLED_Clear();
					}
					
					UsartPrintf(USART_DEBUG, "%s\r\n", json_name->valuestring);		//串口1输出得到的天气字符串,用于调试
					
					OLED_ShowChinese(1 ,8, (uint8_t *)json_name->valuestring);	//OLED显示天气
					
					weather_string_len_pre = strlen(json_name->valuestring);	//更新天气字符串长度
					
					json_name = cJSON_GetObjectItem(json, "city");	//获取city键对应的值的信息
					
					UsartPrintf(USART_DEBUG, "%s\r\n", json_name->valuestring);		//串口1输出得到的城市名字符串,用于调试
					
					OLED_ShowChinese(1,1,(uint8_t *)json_name->valuestring);	//OLED显示城市名
					
					cJSON_Delete(json);	//释放内存
			}
			
			/*如果timeCount为60s,获取时间信息*/
			else if(timeCount == 60)
			{
				get_time_data();	//获取日期时间信息
				
				/*如果没有获取到日期时间信息,重置*/
				if(strlen(processing_data) < 14)
				{
					error_rst();
				}
				
				strncpy(time_string, processing_data, time_len);	//将日期时间信息放到time_string数组
				
				processing_data_clean();	//清空数组
				
				OLED_ShowString(2, 1, time_string);	//OLED显示日期时间
				
				timeCount = (time_string[time_len-2] - '0')*10 + (time_string[time_len-1] - '0');	//timeCount记录获取到的秒数
			}
			
			/*如果timeCount即不为60s也不为59s,更新时间的秒数和光照度、温湿度*/
			else
			{
				/*如果秒数个位为9,十位+1,个位变零*/
				if(time_string[time_len-1] == '9')
				{
						time_string[time_len-2] += 1;
						time_string[time_len-1] = '0';
				}
				
				/*如果秒数个位不为9,个位+1*/
				else
				{
					time_string[time_len-1] = time_string[time_len-1] + 1;
				}
				
				UsartPrintf(USART_DEBUG, "\r\n%s\r\n", time_string);	//串口1输出日期时间,用于调试
				
				OLED_ShowString(2, 1, time_string);	//OLED显示日期时间
				
				BH1750_Get_Light();	//OLED更新光照度
				
				DHT11_Get_Temp_Humidity();	//OLED更新温湿度
			}
			
			time_pre = timeCount;	//更新time_pre计数
			
		}
		
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127

效果图如下
在这里插入图片描述

但事实上,时间有可能会快1s或者2s,这是因为获取时间的时候,获取到的时间自己就会快1s或者2s,如下图所示,串口助手显示当前时间为49s(准确的),但是返回的时间却是51s(不准确的),这个bug我就没什么办法了。。。

在这里插入图片描述

总结

本篇通过高德地图的IP定位、逆地理编码、天气查询的API成功将IP地址对应的天气信息显示到OLED上,并且每分钟实时更新,而日期和时间也成功获取到显示到OLED。还有最后一点内容是OLED如何显示中文字符和如何解决UTF-8编码的问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/821507
推荐阅读
相关标签
  

闽ICP备14008679号