STM32天气数据获取

本文介绍了利用STM32和ESP8266无线上网模块获取天气数据的方法。先对ESP8266进行简介,阐述其通讯及模式;接着介绍HTTP协议;然后说明从心知天气网获取数据,包括创建账户、申请激活等步骤,最后给出功能实现及完整示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32天气数据获取

  • 硬件资源
    ESP8266无线上网模块、STM32系统板、OLED屏
  • 实现方式
    ESP8266无线上网模块配置为STA+TCPClinet;
    通讯协议:HTTP
    天气数据获取:心知天气网

1.ESP8266WIFI简介

  ESP8266是ai-thinker公司推出的一款无线WIFI模块,专为移动设备,可穿戴电子产品和物联应用设计,采用USART通讯,通过AT指令配置,和单片机上的串口进行通信,利用WIFI进行数据传输。ESP8266支持TCP和UDP模式,有AP模式、STA模式以及AP+STA并存模式。

  • STA+TCPClinet AT指令
const char *STA_TCPCLINET[]=
{
  "AT\r\n",//测试指令
  "ATE0\r\n",//关回显
  "AT+CWMODE=1\r\n",//设置STA模式
  "AT+RST\r\n",//模块复位
  "ATE0\r\n",//关回显
  "AT+CWJAP=\"HUAWEIshui\",\"asdfghjkl12\"\r\n",//连接wifi
  "AT+CIPMUX=0\r\n",//设置单连接
  "AT+CIFSR\r\n",//查询IP
  "AT+CIPSTART=\"TCP\",\"192.168.43.204\",8080\r\n",//连接服务器
  "AT+CIPMODE=1\r\n",//设置透传模式
  "AT+CIPSEND\r\n",//开始发送数据
};
  • STA+TCPClinet 模式配置函数封装
u8 Esp8266_STA_TCPclinet_Init(u8 *wifi_name,u8 *wifi_key,u8 *server_ip,u16 server_port)
{
  char buff[100];
  /*退出透传模式*/
  u8 i=0;
  char *p=NULL;
  for(i=0;i<5;i++)
  {
    Usartx_SendString(USART3,(u8 *)"+++");//退出透传模式
    Delay_Ms(500);
    if(Esp8266_SendCmdCheckStat("AT\r\n","OK\r\n")==0)
    {
      i=0;
      break;
    }
  }
  if(i!=0)
  {
    printf("退出透传模式失败\r\n");
    return 0xff;
  }
  printf("1.发送测试指令\r\n");
  if(Esp8266_SendCmdCheckStat("AT\r\n","OK\r\n"))return 1;
  printf("2.关回显\r\n");
  if(Esp8266_SendCmdCheckStat("ATE0\r\n","OK\r\n"))return 2;
  printf("3.设置模式\r\n");
  if(Esp8266_SendCmdCheckStat("AT+CWMODE=1\r\n","OK\r\n"))return 3;  
  printf("4.模块复位\r\n");
  if(Esp8266_SendCmdCheckStat("AT+RST\r\n","OK\r\n"))return 4;  
  Delay_Ms(1000);
  Delay_Ms(1000);
  printf("5.关回显\r\n");
  if(Esp8266_SendCmdCheckStat("ATE0\r\n","OK\r\n"))return 5;  
  

  printf("6.连接WIFI\r\n");
  if(ESP8266_ConectWifi(wifi_name,wifi_key))return 6;
  printf("7.设置单连接\r\n");
  if(Esp8266_SendCmdCheckStat("AT+CIPMUX=0\r\n","OK\r\n"))return 7;    
  printf("8.查询IP地址\r\n");
  if(Esp8266_SendCmdCheckStat("AT+CIFSR\r\n","OK\r\n"))return 8;
  printf("ip:%s\r\n",usart3_rx_buff);//打印IP信息
  /*
      ip:+CIFSR:STAIP,"192.168.43.111"
      +CIFSR:STAMAC,"84:f3:eb:a6:be:f9"
    OK
  */
  i=0;
  p=strstr((char *)usart3_rx_buff,"STAIP,\"");//查找字符串
  if(p!=NULL)
  {
    p+=7;
    while((*p!='"') && (*p!='\0'))
    {
      buff[i++]=*p++;
    }
  }
  buff[i]='\0';
  printf("ip:%s\r\n",buff);
  snprintf(buff,sizeof(buff),"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",server_ip,server_port);
//  printf("buff:%s\r\n",buff);
  printf("9.连接服务器\r\n");
  if(Esp8266_SendCmdCheckStat(buff,"OK\r\n"))return 9;  
  printf("配置透传模式\r\n");
  if(Esp8266_SendCmdCheckStat("AT+CIPMODE=1\r\n","OK\r\n"))return 10;  
  printf("开始发送数据\r\n");
  if(Esp8266_SendCmdCheckStat("AT+CIPSEND\r\n",">"))return 11;  
  return 0;
}

2.HTTP协议

  超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。
  HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本 HTTP 1.1。
  HTTP 是一个基于 TCP/IP 通信协议来传递数据( HTML 文件, 图片文件, 查询结果等)。工作于客户端-服务端架构上,默认端口号为 80,但是你也可以改为 8080或其它端口号。HTTP协议永远都是客户端发起请求,服务器回送响应。
在这里插入图片描述

3.天气数据获取平台

  心知天气是中国气象局官方授权的商业气象服务公司,基于气象数值预报和人工智能技术,提供高精度气象数据、天气监控机器人、气象数据可视化产品,本次天气数据获取从心知天气网平台获取。

  • 实现步骤
    1.创建心知天气个人账户
    平台地址:https://www.seniverse.com/
    在这里插入图片描述
    2.选择产品->天气数据接口,免费试用。
    在这里插入图片描述
    3.选择免费申请,激活
    在这里插入图片描述
    激活成功后即可看到公钥和私钥,这个参数在后面获取数据是需要用到。
    在这里插入图片描述
    4.HTTP方式获取天气数据
    在这里插入图片描述
    在这里插入图片描述
  • 接口说明
https://api.seniverse.com/v3/weather/now.json?key=SwD4-aaQxhedD1z7U&location=beijing&language=zh-Hans&unit=c
“api.seniverse.com”     -- 平台访问域名
“SwD4-aaQxhedD1z7U”  --个人私有秘钥
“beijing”             --要获取的城市名称
“zh-Hans”           --获取到的数据语言(zh-Hans为简体中文)

在这里插入图片描述

  • 平台返回数据
    在这里插入图片描述
    5.功能实现
    心知的 API 目前基于 http 协议,域名是 api.seniverse.com,端口是缺省的 80(http)和 443(https)。
int main()
{
	u8 stat=0;
	u16 cnt=0;
	Beep_Init();//蜂鸣器初始化
	Led_Init();//LED初始化
	Key_Init();//按键初始化
	Usartx_Init(USART1,115200,72);
	Usartx_Init(USART2,9600,36);//蓝牙默认9600
	Usartx_Init(USART3,115200,36);//WIFI默认115200
	TIMx_Init(TIM2,72,20000);//通过定时器2辅助串口接收数据,20ms
	TIMx_Init(TIM3,72,20000);//TIM3辅助串口2数据接收,20ms接收一帧数据
	TIMx_Init(TIM4,72,20000);//TIM4辅助串口3数据接收,20ms接收一帧数据
	printf("wifi Init\r\n");
count++;
		cnt++;
		DelayMs(10);
		if(count>=500)
		{
			count=0;
			USARTx_Sendstr(USART3,"GET https://api.seniverse.com/v3/weather/now.json?key=SwD4-ybQxhedD1z7U&location=jiangxi nanchang&language=en&unit=c\n");
			// USARTx_Sendstr(USART3,"GET https://api.seniverse.com/v3/weather/grid/minutely.json?key=SwD4-ybQxhedD1z7U&location=114.38:27.80\n");
		}
		if(usart3_flag)
		{
			usart3_rx_buff[usart3_cnt]='\0';
			weather_show_stat=1;
			//printf("%s\r\n",usart3_rx_buff);
			/*
			{"results":[{"location":{"id":"WSCQ4UBFXPTE","name":"Yichun","country":"CN",
			"path":"Yichun,Yichun,Jiangxi,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},
			"now":{"text":"Sunny","code":"0","temperature":"36"},"last_update":"2020-08-03T14:00:00+08:00"}]}			
			*/
			if(key==0)
			{
				/*解析天气数据*/
				stat=Weather_analysis(usart3_rx_buff,(u8 *)"\"name\"",(u8 *)buff);//城市名称
				if(!stat)
				{
					OLED_Display_str((127-48-strlen(buff)*8)/2,4,(u8 *)buff);
				}
				stat=Weather_analysis(usart3_rx_buff,(u8 *)"\"temperature\"",(u8 *)buff);//获取温度
				if(!stat)
				{
					OLED_Display_str(127-26,6,(u8 *)"  ");
					OLED_Display_str(127-20-strlen(buff)*8,6,(u8 *)buff);
					OLED_Display_Flont(127-20,6,4);//显示℃
				}
				stat=Weather_analysis(usart3_rx_buff,(u8 *)"\"code\"",(u8 *)buff);//天气代码
				if(!stat)
				{
					sscanf(buff,"%d",(int *)&cnt);
					//printf("cnt=%d\n",cnt);
					switch(cnt)
					{
						case 0://晴
						case 1://晚上晴
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_0);
							break;
						case 4://多云
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_4);
							break;
						case 5://晴转多云
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_5);
							break;
						case 6:
						case 7:
						case 8:
						case 9://阴
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_9);
							break;
						case 10://阵雨
						case 11://雷阵雨
						case 13:
						case 14://雨
						case 15:
						case 16://大雨
						case 17:
						case 18://暴雨
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_14);
							break;
						default:
							OLED_Dislay_Bmp(127-48,0,48,48,bmp_0);
							break;
					}
				}
			}
			usart3_flag=0;
			usart3_cnt=0;	
		}
  • 解析天气数据函数
/******************解析 天气数据****************
形参:u8* buff原始数据
			u8 *Weather_stat天气数据标志
			u8 *data解析获取到的数据
返回值:0---成功,其他值---失败
************************************************/
u8 Weather_analysis(u8* buff,u8 *Weather_stat,u8 *data)
{
	char *p=NULL;
	u16 i=0;
	p=strstr((char *)buff,(char *)Weather_stat);//获取温度
	if(p)
	{
		p+=strlen((char *)Weather_stat)+2;
		i=0;
		while(*p!='\"' && *p!='\0')
		{
			data[i++]=*p++;
		}
		data[i]='\0';
		return 0;
	}
	else return 1;
}
  • 串口接收数据

在这里插入图片描述

  • 相关图标制作

在这里插入图片描述

  • 实现效果
    在这里插入图片描述
    完整示例:
    https://download.csdn.net/download/weixin_44453694/83950811
### STM32配置Sky Encoder(天空星编码器) 对于STM32平台上的Sky Encoder(假设为一种特定类型的增量式编码器),通常会利用定时器(TIM)来捕获编码器信号并计算转速或者位置变化。基于提供的代码片段[^1],可以看出已经引入了`Encoder.h`头文件,并调用了`Encoder_Init()`函数初始化编码器接口。 为了更具体地说明如何针对STM32配置Sky Encoder,在此提供一个较为通用的过程描述: #### 初始化硬件资源 - **使能外设时钟**:确保启用了用于处理编码器输入的GPIO端口及时钟源。 - **配置GPIO引脚**:设置连接到编码器A相和B相信号线对应的GPIO引脚模式为浮空输入或上下拉输入。 ```c // 假定使用的是PA0, PA1作为编码器通道 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // A/B Phase Pins GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` #### 配置定时器工作于正交解码模式 - **选择合适的定时器**:这里选择了TIM3为例,实际应用中可根据需求调整。 - **设定计数方向自动重装载寄存器**:允许根据编码器的方向改变而更新计数值。 ```c TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_InternalClockConfig(TIM3); // 设置预分频系数以及周期值 TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 99; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 启用中断请求 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); // 开始计数 ``` 上述代码展示了如何通过编程的方式让STM32能够接收来自Sky Encoder的位置反馈信息。需要注意的是,具体的参数可能依据不同的应用场景有所差异,因此建议查阅官方文档获取最准确的信息。 #### 中断服务程序中的数据读取逻辑 当发生溢出事件时触发中断,在ISR内部可以执行如下操作以记录当前的速度或位移量: ```c void TIM3_IRQHandler(){ if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET){ static int last_count = 0; int current_count = TIM_GetCounter(TIM3); // 计算速度或其他物理量 speed_value = (current_count - last_count)*some_conversion_factor; last_count = current_count; // 清除标志位 TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } } ``` 以上就是关于STM32平台上配置Sky Encoder的一个基本框架介绍。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_阿水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值