ESP01S通过STM32控制阿里云云平台实现小灯的开关操作

目录

一、ESP01S与STM32的连接

二、接收阿里云平台发来的数据

 三、解析数据

四、根据数据进行状态判断

五、可视化界面的设计


一、ESP01S与STM32的连接

        ESP01S与STM32的通信方式为串口通信,连线方式ESP01S的TXD,RXD与STM32的TXD,RXD交叉互连,VCC接3V3,GND接GND。

二、接收阿里云平台发来的数据

        在使用STM32代替串口调试助手给ESP01S传数据之前,先用串口调试助手来分析云平台给STM32所发的数据格式,附AT指令集(ESP-AT 系列: AT+MQTT 使用)。

        首先通过AT指令连接到阿里云平台,这个指令在我的上一篇博客有写(ESP-01S通过AT MQTT连接阿里云),连接到云平台以后,在云平台中设置一个灯的属性。

         然后添加设备,自己取一个设备名字。

         之后查看设备的三元组信息,并将三元组信息在阿里云配置软件中赋值,生成相应的MQTT参数,此处不懂的可以参考我的上一篇博客。

        创建产品并成功连接到阿里云以后,通过AT+MQTTSUB=0,”订阅的TOPIC“指令订阅一个具有set权限的TOPIC。

         进入在线调试,通过在阿里云平台设置参数,观察串口调试助手中接收到的数据。

        可以观察到,其实STM32就是要解析这个数据,并通过解析这个数据完成开关灯的设置。

 三、解析数据

        实验次数多以后会发现每次的id值不同,且位数也不相同,这就表明该数据是一个不定长的数据,而STM32接收不定长数据可以通过串口的接收中断和空闲中断来实现。以下是USART1的初始化配置。

void uart_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟

	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口空闲中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

         重点是要开启USART1的接收中断和空闲中断

        当串口每接收到一个数据后就会进入USART1的接收中断,当一帧数据接收完成后,在没收到数据的这段期间,会进入空闲中断,在空闲中断中,就可以判断该数据的长度,并且在空闲中断中还可以判断该数据是不是阿里云发来的,而不是ESP01S收到数据后给STM32返回的OK。

char MQTT_Head[]="+MQTTSUBRECV";
	
void USART1_IRQHandler(void)                	//串口1中断服务程序
{

	uint8_t uart1RecvFlag = 0;		//接收完成标志位

	static uint8_t uart1RecvLen = 0;			//接收数据的长度
	extern char MQTT_Receive_Data[176];

		if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)  //接收中断
		{
				USART_RX_BUF[uart1RecvLen] = USART1->DR;
				USART_ClearITPendingBit(USART1, USART_IT_RXNE);	
				uart1RecvLen++;
		}

	else if(USART_GetITStatus(USART1,USART_IT_IDLE) ==SET)		//空闲中断
	{
			USART1->SR;
			USART1->DR;	//作用是清除IDLE标志位, 根据规格要求, 清除IDLE是要先读取SR后读DR, 因为中断是IDLE, 所以从DR读出来的是没意思的数据,
				
		for(int i=0;i<11;i++)
		{
				if( USART_RX_BUF[i] != MQTT_Head[i])		//接收到的数据不是云平台发来的
					{
						memset(USART_RX_BUF,0x00,sizeof(USART_RX_BUF));
						uart1RecvFlag = 0;			
						break;
					}
					else uart1RecvFlag = 1;				//接收到的数据是云平台发来的
		}
    if(uart1RecvFlag == 1 )			
		{	
			for(int i = 0;i < uart1RecvLen;i++)
				{	
				    MQTT_Receive_Data[i] = USART_RX_BUF[i];	//将缓冲区数据传给另一个数组					
				}		
		}	
	uart1RecvLen = 0;
}

        判断完数据是云平台发出的以后,就可以在应用层层面来进行状态判断,从而实现灯的亮灭。

四、根据数据进行状态判断

void Receive_Deal(void)
{
	int i = 0,index;	
	
    char MQTT_Power_State[]="powerstate";
    char *p;
    	
	p = MQTT_Receive_Data;					//指针p指向接受数组的第一个元素
	for(i=0;i<sizeof(MQTT_Receive_Data);i++)
	{
		
		if(*(p+i)=='p' && *(p+i+1)=='a' && *(p+i+2) == 'r')
		{
			index = i+10; 
			break;
		}
	}

	for(i=0;i<10;i++,index++)
	{
		ESP01SStruct.MQTT_Param[i] = MQTT_Receive_Data[index];
	}
	
	ESP01SStruct.MQTT_Param_Value = MQTT_Receive_Data[index+2];	
	
	//param_compare
	for(i=0;i<10;i++)
	{
		if(ESP01SStruct.MQTT_Param[i] != MQTT_Power_State[i])
		{
			ESP01SStruct.Led_State_flag=0;
			break;
		}
		else
			ESP01SStruct.Led_State_flag=1;
	}

	//paramvalue_compare
	if(ESP01SStruct.Led_State_flag==1)
	{
	  
		switch (ESP01SStruct.MQTT_Param_Value)
		{
			case 0x30:
			{	
				ESP01SStruct.Led_flag=0; 
				break;
			}
			case 0x31:
			{		
				ESP01SStruct.Led_flag=1;	
				break;
			}				
		}
	}	
	
	//led_work
	if(ESP01SStruct.Led_State_flag==1 && ESP01SStruct.Led_flag==1)
			Led_ON();
	if(ESP01SStruct.Led_State_flag==1 && ESP01SStruct.Led_flag==0)
		 Led_OFF();

}	

        由于要实现的不仅仅是灯的亮灭,还有其他一些功能待完善,如:温湿度的实时上报以及控制电机的转动等等。如果只用于点灯的话,状态判断部分的代码不必这么复杂,读者自行设计即可。

五、可视化界面的设计

        登录阿里云IOT Studio平台,创建新的Web开发界面。

         进入到页面以后,即可添加自己所需的组件,点击相应的组件,在右侧对应的交互中,配置数据与阿里云平台中的数据一致即可。

         这样点击页面上方的预览,按一下按钮即可实现灯的打开啦!

         后续将会把温湿度实时上报部分的数据处理也加上。

        感谢你的耐心观看,本人水平有限,代码写的不一定最优,有其他方法也可以共同探讨。

物联沃分享整理
物联沃-IOTWORD物联网 » ESP01S通过STM32控制阿里云云平台实现小灯的开关操作

发表评论