STM32+ESP8266+华为云

这篇具有很好参考价值的文章主要介绍了STM32+ESP8266+华为云。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

华为云平台创建产品

创建账号

此部分省略…

打开物联网平台

搜索框内搜索物联网平台

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

点击打开【设备接入IOTDA】

点击进入【管理控制台】

这里进入后可能会提示你进行实名认证,如果不实名认证的话是不可以使用云平台的

创建产品

我记得第一次使用的话好像还需要创建一个空间啥的,如果创建的话就一切默认就行了

  1. 点击右上角的【创建产品】

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

  1. 参考下图进行信息填写
  1. 创建完成后进入创建的产品,进行产品模型设置
  2. 首先先创建一个服务,服务ID自己根据实际写(因为我是基于STM32开发的,所以写的就是STM32)

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

  1. 点击【新增属性】,添加产品需要收发的数据

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

  1. 根据实际项目需求的数据格式,填写内容(下图是我读取和设置电机速度建立的属性)
  1. 如果你还需要进行云端下发指令控制设备,那么还需要点击【添加命令】,进行指令的设置

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

  1. 指令设置里面,【下发参数】就是下发指令控制设备,【响应参数】就是读取设备上传信息

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

创建设备

在【所有设备】界面,点击右上角的【注册设备】添加设备

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

记住下面页面生成的两个参数,他会给你一个下载一个TXT文件,这两个参数一会需要使用

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

获取MQTT三元组

用下面的网页生成三元组:Huaweicloud IoTDA Mqtt ClientId Generator (myhuaweicloud.com)

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

点击【Generate】后会根据你填写的信息生成MQTT三元组

平台地址和接口获取

参照下图,找到MQTT协议下的平台地址和端口号

我们使用的是MQTT,所以端口是1883

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

ESP8266烧录AT指令

这里参考之前连接阿里云的笔记【如果之前烧录过AT指令,这里就可以不用再烧录了】

烧录所需资源

链接:https://pan.baidu.com/s/1TsdqrG8J2jgWOyJGn-KJrw?pwd=u3il
提取码:u3il

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

打开烧录工具进行烧录

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

先点击【ERASE】,等完成后,再点击【START】进行烧录

烧录实际可能比较慢,耐心等待进度条跑完

出现提示弹出显示3-run stub fail,可能事端口选择错误或波特率错误(115200与1152000注意)

STM32+标准库函数+连接华为云

这里的设置参考:( STM32 标准库+ESP8266+华为云物联网平台_stm32 物联网平台_IOT趣制作的博客-CSDN博客

delay函数使用自己的就行,没有提供

移植文件

这两个文件是我参考的博客里面提供的驱动文件,我并没有完全按照他说的进行移植更改

HuaweiIOT_at_esp8266.c

/*
*********************************************************************************************************
*	模块名称:esp8266+AT指令+华为云物联网平台
*	文件名称: HuaweiIOT_at_esp8266.c
*	说明备注:无
*	修改记录:无	
*	版本号     日期          作者     																		说明
*	V1.0       22-8-1      	 funiot.xyz|公众号“IOT趣制作”
*	Copyright by JIA
*********************************************************************************************************
*/
//【步骤1】使用本驱动文件时,请在main.c中添加引用 #include "HuaweiIOT_at_esp8266.h"
//【步骤2】使用本驱动文件时,请将HuaweIOT.h中宏定义的数据进行补齐
//【步骤3】使用本驱动文件时,请将下面变量的声明拷贝至main.c
/*
步骤3拷贝开始↓
*********************************************************************************************************
uint8_t uart1_rec_i=0;
extern uint8_t atok_rec_flag;
char uart1_recdata=0,uart1_recstring[256],sub_string[150],analysis_Str[256];
*********************************************************************************************************
步骤3拷贝截至↑
*/
//【步骤4】使用本驱动文件时,请将下面的USART1_IRQHandler()串口接收中断处理函数拷贝至main.c,系统中断函数无需额外声明
/* 
步骤4拷贝开始↓
// *********************************************************************************************************
// * 函 数 名: USART1_IRQHandler
// * 功能说明: 串口中断1函数:主要完成esp8266模块的通信接收处理
// * 形 参:无
// * 返 回 值: 无
// *********************************************************************************************************

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	char str_temp[128];
	char request_id[48];
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  	//接收中断
	{
			USART_ClearITPendingBit(USART1,USART_IT_RXNE); 			//清除中断标志
			uart1_recdata =USART_ReceiveData(USART1);						//读取接收到的数据
			if(uart1_recdata!='\n')
			{				 
				//防止第一个接收为空格
				if((uart1_rec_i==0)&&(uart1_recdata==' '))
				{
					//测试发现在接收MQTT服务器下发的命令时,有时接收的数据第一位为空格
					//通过上述判断方式可以解决,触发原因暂时不明,贾工留坑-2022.9.3.1
				}
				else
				{
					uart1_recstring[uart1_rec_i]=uart1_recdata;
					//printf("%c",uart1_recstring[uart1_rec_i]);		//调试时开启
					uart1_rec_i++;	//统计接收字符数量
				}
			}
			else
			{
				//printf("Rec Over,uart1_rec_i=%d,data=%s\r\n",uart1_rec_i,uart1_recstring);//调试时开启,用于检查接收数据内容
				if(uart1_rec_i>=2)
				{
					strncpy(sub_string,uart1_recstring,2);	//截取前两位
					if(strcmp(sub_string,"OK")==0)
					{
						atok_rec_flag=1;
						//printf("Get Ok\r\n");//调试时开启,用于确定是否接收到"ok"
					}
					
					strncpy(sub_string,uart1_recstring,5);
					if(strcmp(sub_string,"ready")==0)
					{ 
						atok_rec_flag=1;
						//printf("Get ready\r\n");//调试时开启,用于确定是否接收到“ready”
					}
					
					strncpy(sub_string,uart1_recstring,5);
					if(strcmp(sub_string,"ERROR")==0)
					{
						atok_rec_flag=0;
						//printf("Get ERROR\r\n");//调试时开启,用于确定是否接收到“ERROR”
					}
					//我的接收数据长度为201,下面采用JSON字符串硬解析的方式,具体下标请根据自己实际接收的参数处理
					//+MQTTSUBRECV:0,"$oc/devices/61fb2d7fde9933029funiot_esp8266_test01/sys/commands/request_id=4152fb5d-e5ae-4b89-b39d-283ba59cf033",68,{"paras":{"led":1},"service_id":"Dev_data","command_name":"Control"}
          if(uart1_rec_i>=200)
					{
						strncpy(analysis_Str, uart1_recstring, 12);							//提取出“+MQTTSUBRECV”
						if(strcmp(analysis_Str,"+MQTTSUBRECV")==0)
            {
							memset(analysis_Str,0,sizeof(analysis_Str));					//清空缓存区
							//printf("MQTT命令接收头正确\r\n");
							strncpy(request_id, uart1_recstring+92, 36);     			//提取出request_id
							//printf("request_id=%s\r\n",request_id);
							strncpy(analysis_Str, uart1_recstring+135, 5);    		//提取出"paras"
							//printf("paras=%s\r\n",analysis_Str);
							if(strcmp(analysis_Str,"paras")==0)        						//有效参数体
							{
											memset(analysis_Str,0,sizeof(analysis_Str));	//清空缓存区
											strncpy(analysis_Str, uart1_recstring+144,3);	//提取出"led"
											//printf("att is %s\r\n",analysis_Str);
											if(strcmp(analysis_Str,"led")==0)
											{
															//printf("led set %c\r\n",uart1_recstring[149]);
															
															if(uart1_recstring[149]=='0')
															{
																			//printf("关灯\r\n");
																			LED_TurnOff(3);  
															}
															else if(uart1_recstring[149]=='1')
															{
																			//printf("开灯\r\n");      
																			LED_TurnOn(3);
															} 
															//向云平台完成命令响应
															printf("AT+MQTTPUB=0,\"$oc/devices/%s/sys/commands/response/request_id=%s\",\"\",0,0\r\n",HUAWEI_MQTT_DeviceID,request_id);
															
															memset(analysis_Str,0,sizeof(analysis_Str));//清空缓存区  		
															memset(str_temp,0,sizeof(str_temp));				//清空缓存区  																	
											}        
							}
						}
						
					}
				}
				uart1_rec_i=0;
				memset(uart1_recstring,0,sizeof(uart1_recstring));//清空uart1_recstring字符串
				memset(sub_string,0,sizeof(sub_string));					//清空sub_string字符串				
			}				
	 } 	
} 
步骤4拷贝截至↑
*/

///
/*头文件包含区*/
#include "HuaweiIOT_at_esp8266.h"
#include "string.h"
#include "delay.h"
#include "usart.h"

///
/*宏定义区*/

///
/*外部变量声明区*/
uint8_t atok_rec_flag;
///
/*函数声明区*/

///
/*函数实体区*/

/**********************************************************************************************************
* 函 数 名: HuaweiIot_init
* 功能说明: 华为云物联网平台初始化
* 形 参:无
* 返 回 值: 无
**********************************************************************************************************/
void HuaweiIot_init(void)
{
    uint8_t i=0;
	
		char str_temp[256];	//虽然在实际使用时str_temp最大不超100,但是测试时发现char str_temp[128]时程序会卡死
												//经过景哥和强哥帮助,将其改为char str_temp[256]时可以正常运行,或者将其定义为全局变量
												//初步分析为作用域不同导致分配栈空间不同,具体原因待日后分析。—贾工留坑-2023.3.10.1
	
		delay_ms(1000);			//等待模块上电稳定

    for(i=0;i<10;i++)
    {
        if(atok_rec_flag==1)
        {
            AT_write("AT");					//AT测试
            printf("AT+RST\r\n");		//重启设备
            delay_ms(2000);					//等待设备重启
            AT_write("AT");					//AT测试
            AT_write("AT+CWMODE=1");//设置模块为STA模式
					
						sprintf(str_temp,"AT+CWJAP=\"%s\",\"%s\"",WIFI_SSID,WIFI_PWD);	//连接WiFi
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTUSERCFG=0,1,\"NULL\",\"%s\",\"%s\",0,0,\"\"",HUAWEI_MQTT_USERNAME,HUAWEI_MQTT_PASSWORD);//设置MQTT的登陆用户名与密码
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTCLIENTID=0,\"%s\"",HUAWEI_MQTT_ClientID);//设置MQTT的ClientID
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTCONN=0,\"%s\",%s,1",HUAWEI_MQTT_ADDRESS,HUAWEI_MQTT_PORT);//设置MQTT接入地址与端口号
						AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/properties/report\",1",HUAWEI_MQTT_DeviceID);	//订阅设备属性上报的主题
						AT_write(str_temp);
						
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/commands/#\",1",HUAWEI_MQTT_DeviceID);//订阅设备命令接收的主题
            AT_write(str_temp);
						
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/commands/response/#\",1",HUAWEI_MQTT_DeviceID);//订阅设备命令响应的主题
            AT_write(str_temp);
            break;
        }    
        else
        {
						if(i==9)
						{
							printf("Connected ESP01s Fail!\r\n");	//连接超时
							break;
						}
						else 
						{
							printf("AT\r\n");
							delay_ms(1000);
						}
						
        }            
    }
}
/**********************************************************************************************************
* 函 数 名: AT_write
* 功能说明: AT指令发送
* 形 参:无
* 返 回 值: 无
**********************************************************************************************************/
void AT_write(char atstring[512])//阻塞等待OK
{
		atok_rec_flag=0;
    printf("%s\r\n",atstring);
		while(1)
		{
			if(atok_rec_flag==1)	//接收到OK后串口中断会将atok_rec_flag置1
			{
				atok_rec_flag=0;
				break;
			}
			else 
				delay_ms(50);
		}	
}
/**********************************************************************************************************
* 函 数 名: HuaweiIot_publish
* 功能说明: 华为云设备属性上报
* 形 参:char * att,属性名;uint16_t data:属性值
* 返 回 值: 无
**********************************************************************************************************/
void HuaweiIot_DevDate_publish(char *att,uint16_t data)
{
	printf("AT+MQTTPUB=0,\"$oc/devices/%s/sys/properties/report\",\"{\\\"services\\\":[{\\\"service_id\\\":\\\"%s\\\"\\,\\\"properties\\\":{\\\"%s\\\": %d}}]}\",0,0\r\n",HUAWEI_MQTT_DeviceID,HUAWEI_MQTT_ServiceID,att,data);
}

///

HuaweiIOT_at_esp8266.h

/*
*********************************************************************************************************
*	模块名称: esp8266+AT指令+华为云物联网平台
*	文件名称: HuaweiIOT_at_esp8266.h
*	说明备注:无
*	修改记录:无
*	版本号     日期          作者     						说明
*	V1.0       22-8-1      	funiot.xyz|公众号“IOT趣制作”  
*	Copyright by JIA
*********************************************************************************************************
*/
#ifndef __HUAWEIIOT_H
#define __HUAWEIIOT_H

///
/*头文件包含区*/
#include "sys.h"
///
/*宏定义区*/
//使用时请在这里补全相关信息
#define WIFI_SSID									"xxxxxxxx"
#define WIFI_PWD									"xxxxxxxx"
#define HUAWEI_MQTT_USERNAME			"xxxxxxxx"
#define HUAWEI_MQTT_PASSWORD			"xxxxxxxx"
#define HUAWEI_MQTT_ClientID			"xxxxxxxx"
#define HUAWEI_MQTT_ADDRESS				"xxxxxxxx"
#define HUAWEI_MQTT_PORT					"xxxxxxxx"
#define HUAWEI_MQTT_DeviceID			"xxxxxxxx"
#define HUAWEI_MQTT_ServiceID			"xxxxxxxx"
///
/*外部变量声明区*/

///
/*函数声明区*/
void AT_write(char atstring[512]);//阻塞等待OK
void HuaweiIot_init(void);
void HuaweiIot_DevDate_publish(char * att,uint16_t data);
///
#endif

填写宏定义数据

HUAWEI_MQTT_DeviceID:创建产品时生成的产品ID

HUAWEI_MQTT_ServiceID:创建产品时在模型里面创建的服务ID

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

添加usart文件

我这把usart中断函数放在了usart.c文件中,没有放在main.c中

usart.c

#include "stm32f10x.h"                  // Device header
#include <string.h>
#include <stdio.h>
#include "HuaweiIOT_at_esp8266.h"

uint8_t uart1_rec_i = 0;
extern uint8_t atok_rec_flag;
char uart1_recdata = 0, uart1_recstring[256], sub_string[150], analysis_Str[256];
extern uint16_t speed;
uint16_t speed_flag;

void MyUSART_Init(void) {
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//1.开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;                 //初始化GIPIO
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitTypeDef USART_InitStructure;              //初始化串口
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStructure);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE);

}

// *********************************************************************************************************
// * 函 数 名: USART1_IRQHandler
// * 功能说明: 串口中断1函数:主要完成esp8266模块的通信接收处理
// * 形 参:无
// * 返 回 值: 无
// *********************************************************************************************************

void USART1_IRQHandler(void)                    //串口1中断服务程序
{
    char str_temp[128];
    char request_id[48];

    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    //接收中断
    {
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);            //清除中断标志
        uart1_recdata = USART_ReceiveData(USART1);                        //读取接收到的数据
        if (uart1_recdata != '\n') {
            //防止第一个接收为空格
            if ((uart1_rec_i == 0) && (uart1_recdata == ' ')) {
                //测试发现在接收MQTT服务器下发的命令时,有时接收的数据第一位为空格
                //通过上述判断方式可以解决,触发原因暂时不明,贾工留坑-2022.9.3.1
            } else {
                uart1_recstring[uart1_rec_i] = uart1_recdata;
                //printf("%c",uart1_recstring[uart1_rec_i]);		//调试时开启
                uart1_rec_i++;    //统计接收字符数量
            }
        } else {
            //printf("Rec Over,uart1_rec_i=%d,data=%s\r\n",uart1_rec_i,uart1_recstring);//调试时开启,用于检查接收数据内容
            if (uart1_rec_i >= 2) {
                strncpy(sub_string, uart1_recstring, 2);    //截取前两位
                if (strcmp(sub_string, "OK") == 0) {
                    atok_rec_flag = 1;
                    //printf("Get Ok\r\n");//调试时开启,用于确定是否接收到"ok"
                }

                strncpy(sub_string, uart1_recstring, 5);
                if (strcmp(sub_string, "ready") == 0) {
                    atok_rec_flag = 1;
                    //printf("Get ready\r\n");//调试时开启,用于确定是否接收到“ready”
                }

                strncpy(sub_string, uart1_recstring, 5);
                if (strcmp(sub_string, "ERROR") == 0) {
                    atok_rec_flag = 0;
                    //printf("Get ERROR\r\n");//调试时开启,用于确定是否接收到“ERROR”
                }
                //我的接收数据长度为201,下面采用JSON字符串硬解析的方式,具体下标请根据自己实际接收的参数处理
                //+MQTTSUBRECV:0,"$oc/devices/61fb2d7fde9933029funiot_esp8266_test01/sys/commands/request_id=4152fb5d-e5ae-4b89-b39d-283ba59cf033",68,{"paras":{"led":1},"service_id":"Dev_data","command_name":"Control"}
                if (uart1_rec_i >= 190) {
                    strncpy(analysis_Str, uart1_recstring, 12);                            //提取出“+MQTTSUBRECV”
                    if (strcmp(analysis_Str, "+MQTTSUBRECV") == 0) {
                        memset(analysis_Str, 0, sizeof(analysis_Str));                    //清空缓存区
                        //printf("MQTT命令接收头正确\r\n");
                        strncpy(request_id, uart1_recstring + 84, 36);                //提取出request_id
                        //printf("request_id=%s\r\n",request_id);
                        strncpy(analysis_Str, uart1_recstring + 127, 5);            //提取出"paras"
                        //printf("paras=%s\r\n",analysis_Str);
                        if (strcmp(analysis_Str, "paras") == 0)                                //有效参数体
                        {
                            memset(analysis_Str, 0, sizeof(analysis_Str));    //清空缓存区
                            strncpy(analysis_Str, uart1_recstring + 136, 7);    //提取出"led"
                            //printf("att is %s\r\n",analysis_Str);
                            if (strcmp(analysis_Str, "ActVel1") == 0) {
                                //printf("led set %c\r\n",uart1_recstring[145]);

                                if (uart1_recstring[144] == ':') {
									speed = (uart1_recstring[145] - '0') * 10  + (uart1_recstring[146] - '0');
//                                  printf("关灯\r\n");

                                } else if (uart1_recstring[145] == '1') {
                                    printf("开灯\r\n");
                                    //LED_TurnOn(3);
                                }
                                //向云平台完成命令响应
                                printf("AT+MQTTPUB=0,\"$oc/devices/%s/sys/commands/response/request_id=%s\",\"\",0,0\r\n",
                                       HUAWEI_MQTT_DeviceID, request_id);

                                memset(analysis_Str, 0, sizeof(analysis_Str));//清空缓存区  		
                                memset(str_temp, 0, sizeof(str_temp));                //清空缓存区  																	
                            }
                        }
                    }

                }
            }
            uart1_rec_i = 0;
            memset(uart1_recstring, 0, sizeof(uart1_recstring));//清空uart1_recstring字符串
            memset(sub_string, 0, sizeof(sub_string));                    //清空sub_string字符串				
        }
    }
}

//内部调用函数,注意要勾选OPTIONS中的USE Micro LIB选项
int fputc(int ch, FILE *f)   //printf重定向  
{
    USART_SendData(USART1, (uint8_t) ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    return ch;
}

usart.h文章来源地址https://www.toymoban.com/news/detail-766197.html

#ifndef __USART_H
#define __USART_H
#include "stdio.h"

void MyUSART_Init(void);

#endif

程序移植更改过程

1.main.c中添加头文件

#include "HuaweiIOT_at_esp8266.h" 
#include "usart.h" 

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

2.main.c中main函数中开启初始化

MyUSART_Init();
HuaweiIot_init();    //华为云物联网平台初始化

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

3.数据上传

		HuaweiIot_DevDate_publish("ActVel1",speed++);
		delay_ms(3000);

4.全局变量从HuaweiIOT_at_esp8266.c移植到usart.c(如果直接拷贝上述的usart文件则可以跳过)

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

5.中断服务函数HuaweiIOT_at_esp8266.c移植到usart.c(如果直接拷贝上述的usart文件则可以跳过)

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

6.中断服务函数中的接受云端数据的代码分析更改(这部分是需要根据你个人的实际数据格式进行更改的)

网页控制华为云esp,笔记,单片机,stm32,华为云,单片机,嵌入式硬件,物联网

这部分最麻烦的就行算那个长度,其实我之前连阿里云的时候用的是使用循环直接查找属性名获取数据值的,但是他提供的驱动里面使用的是这种手动计算长度,然后截取字符串判断后获取数据,我本来想改成自动的,但没改成,就只能用他的了

个人完整工程

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h" 
#include "HuaweiIOT_at_esp8266.h" 
#include "usart.h" 

uint16_t speed;
int main(){
	MyUSART_Init();
	HuaweiIot_init();    //华为云物联网平台初始化
	
	while(1){
		HuaweiIot_DevDate_publish("ActVel1",speed++);
		delay_ms(3000);
	}
}

HuaweiIOT_at_esp8266.c

#include "HuaweiIOT_at_esp8266.h"
#include "string.h"
#include "Delay.h"
#include "usart.h"

/*外部变量声明区*/
uint8_t atok_rec_flag;

/**********************************************************************************************************
* 函 数 名: HuaweiIot_init
* 功能说明: 华为云物联网平台初始化
* 形 参:无
* 返 回 值: 无
**********************************************************************************************************/
void HuaweiIot_init(void)
{
    uint8_t i=0;
	
		char str_temp[256];	//虽然在实际使用时str_temp最大不超100,但是测试时发现char str_temp[128]时程序会卡死
												//经过景哥和强哥帮助,将其改为char str_temp[256]时可以正常运行,或者将其定义为全局变量
												//初步分析为作用域不同导致分配栈空间不同,具体原因待日后分析。—贾工留坑-2023.3.10.1
	
		delay_ms(1000);			//等待模块上电稳定

    for(i=0;i<10;i++)
    {
        if(atok_rec_flag==1)
        {
            AT_write("AT");					//AT测试
            printf("AT+RST\r\n");		//重启设备
            delay_ms(2000);					//等待设备重启
            AT_write("AT");					//AT测试
            AT_write("AT+CWMODE=1");//设置模块为STA模式
					
						sprintf(str_temp,"AT+CWJAP=\"%s\",\"%s\"",WIFI_SSID,WIFI_PWD);	//连接WiFi
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTUSERCFG=0,1,\"NULL\",\"%s\",\"%s\",0,0,\"\"",HUAWEI_MQTT_USERNAME,HUAWEI_MQTT_PASSWORD);//设置MQTT的登陆用户名与密码
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTCLIENTID=0,\"%s\"",HUAWEI_MQTT_ClientID);//设置MQTT的ClientID
            AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTCONN=0,\"%s\",%s,1",HUAWEI_MQTT_ADDRESS,HUAWEI_MQTT_PORT);//设置MQTT接入地址与端口号
						AT_write(str_temp);
					
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/properties/report\",1",HUAWEI_MQTT_DeviceID);	//订阅设备属性上报的主题
						AT_write(str_temp);
						
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/commands/#\",1",HUAWEI_MQTT_DeviceID);//订阅设备命令接收的主题
            AT_write(str_temp);
						
						sprintf(str_temp,"AT+MQTTSUB=0,\"$oc/devices/%s/sys/commands/response/#\",1",HUAWEI_MQTT_DeviceID);//订阅设备命令响应的主题
            AT_write(str_temp);
            break;
        }    
        else
        {
						if(i==9)
						{
							printf("Connected ESP01s Fail!\r\n");	//连接超时
							break;
						}
						else 
						{
							printf("AT\r\n");
							delay_ms(1000);
						}
						
        }            
    }
}
/**********************************************************************************************************
* 函 数 名: AT_write
* 功能说明: AT指令发送
* 形 参:无
* 返 回 值: 无
**********************************************************************************************************/
void AT_write(char atstring[512])//阻塞等待OK
{
		atok_rec_flag=0;
    printf("%s\r\n",atstring);
		while(1)
		{
			if(atok_rec_flag==1)	//接收到OK后串口中断会将atok_rec_flag置1
			{
				atok_rec_flag=0;
				break;
			}
			else 
				delay_ms(50);
		}	
}
/**********************************************************************************************************
* 函 数 名: HuaweiIot_publish
* 功能说明: 华为云设备属性上报
* 形 参:char * att,属性名;uint16_t data:属性值
* 返 回 值: 无
**********************************************************************************************************/
void HuaweiIot_DevDate_publish(char *att,uint16_t data)
{
	printf("AT+MQTTPUB=0,\"$oc/devices/%s/sys/properties/report\",\"{\\\"services\\\":[{\\\"service_id\\\":\\\"%s\\\"\\,\\\"properties\\\":{\\\"%s\\\": %d}}]}\",0,0\r\n",HUAWEI_MQTT_DeviceID,HUAWEI_MQTT_ServiceID,att,data);
}

///

HuaweiIOT_at_esp8266.h

/*
*********************************************************************************************************
*	模块名称: esp8266+AT指令+华为云物联网平台
*	文件名称: HuaweiIOT_at_esp8266.h
*	说明备注:无
*	修改记录:无
*	版本号     日期          作者     						说明
*	V1.0       22-8-1      	funiot.xyz|公众号“IOT趣制作”  
*	Copyright by JIA
*********************************************************************************************************
*/
#ifndef __HUAWEIIOT_H
#define __HUAWEIIOT_H

///
/*头文件包含区*/
#include "stm32f10x.h"                  // Device header
///
/*宏定义区*/
//使用时请在这里补全相关信息
#define WIFI_SSID						"xxxxxxxx"  //WiFi名
#define WIFI_PWD						"xxxxxxxx"  //WiFi密码
#define HUAWEI_MQTT_USERNAME			"xxxxxxxx"  //Username
#define HUAWEI_MQTT_PASSWORD			"xxxxxxxx"  //Password
#define HUAWEI_MQTT_ClientID			"xxxxxxxx"  //ClientId
#define HUAWEI_MQTT_ADDRESS				"xxxxxxxx"  //平台地址
#define HUAWEI_MQTT_PORT				"xxxxxxxx"  //端口号
#define HUAWEI_MQTT_DeviceID			"xxxxxxxx"  //设备ID
#define HUAWEI_MQTT_ServiceID			"xxxxxxxx"  //服务ID
///
/*外部变量声明区*/

///
/*函数声明区*/
void AT_write(char atstring[512]);//阻塞等待OK
void HuaweiIot_init(void);
void HuaweiIot_DevDate_publish(char * att,uint16_t data);
///
#endif

usart.c

#include "stm32f10x.h"                  // Device header
#include <string.h>
#include <stdio.h>
#include "HuaweiIOT_at_esp8266.h"

uint8_t uart1_rec_i = 0;
extern uint8_t atok_rec_flag;
char uart1_recdata = 0, uart1_recstring[256], sub_string[150], analysis_Str[256];
extern uint16_t speed;
uint16_t speed_flag;

void MyUSART_Init(void) {
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//1.开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;                 //初始化GIPIO
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitTypeDef USART_InitStructure;              //初始化串口
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStructure);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE);

}

// *********************************************************************************************************
// * 函 数 名: USART1_IRQHandler
// * 功能说明: 串口中断1函数:主要完成esp8266模块的通信接收处理
// * 形 参:无
// * 返 回 值: 无
// *********************************************************************************************************

void USART1_IRQHandler(void)                    //串口1中断服务程序
{
    char str_temp[128];
    char request_id[48];

    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    //接收中断
    {
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);            //清除中断标志
        uart1_recdata = USART_ReceiveData(USART1);                        //读取接收到的数据
        if (uart1_recdata != '\n') {
            //防止第一个接收为空格
            if ((uart1_rec_i == 0) && (uart1_recdata == ' ')) {
                //测试发现在接收MQTT服务器下发的命令时,有时接收的数据第一位为空格
                //通过上述判断方式可以解决,触发原因暂时不明,贾工留坑-2022.9.3.1
            } else {
                uart1_recstring[uart1_rec_i] = uart1_recdata;
                //printf("%c",uart1_recstring[uart1_rec_i]);		//调试时开启
                uart1_rec_i++;    //统计接收字符数量
            }
        } else {
            //printf("Rec Over,uart1_rec_i=%d,data=%s\r\n",uart1_rec_i,uart1_recstring);//调试时开启,用于检查接收数据内容
            if (uart1_rec_i >= 2) {
                strncpy(sub_string, uart1_recstring, 2);    //截取前两位
                if (strcmp(sub_string, "OK") == 0) {
                    atok_rec_flag = 1;
                    //printf("Get Ok\r\n");//调试时开启,用于确定是否接收到"ok"
                }

                strncpy(sub_string, uart1_recstring, 5);
                if (strcmp(sub_string, "ready") == 0) {
                    atok_rec_flag = 1;
                    //printf("Get ready\r\n");//调试时开启,用于确定是否接收到“ready”
                }

                strncpy(sub_string, uart1_recstring, 5);
                if (strcmp(sub_string, "ERROR") == 0) {
                    atok_rec_flag = 0;
                    //printf("Get ERROR\r\n");//调试时开启,用于确定是否接收到“ERROR”
                }
                //我的接收数据长度为201,下面采用JSON字符串硬解析的方式,具体下标请根据自己实际接收的参数处理
                //+MQTTSUBRECV:0,"$oc/devices/61fb2d7fde9933029funiot_esp8266_test01/sys/commands/request_id=4152fb5d-e5ae-4b89-b39d-283ba59cf033",68,{"paras":{"led":1},"service_id":"Dev_data","command_name":"Control"}
                if (uart1_rec_i >= 190) {
                    strncpy(analysis_Str, uart1_recstring, 12);                            //提取出“+MQTTSUBRECV”
                    if (strcmp(analysis_Str, "+MQTTSUBRECV") == 0) {
                        memset(analysis_Str, 0, sizeof(analysis_Str));                    //清空缓存区
                        //printf("MQTT命令接收头正确\r\n");
                        strncpy(request_id, uart1_recstring + 84, 36);                //提取出request_id
                        //printf("request_id=%s\r\n",request_id);
                        strncpy(analysis_Str, uart1_recstring + 127, 5);            //提取出"paras"
                        //printf("paras=%s\r\n",analysis_Str);
                        if (strcmp(analysis_Str, "paras") == 0)                                //有效参数体
                        {
                            memset(analysis_Str, 0, sizeof(analysis_Str));    //清空缓存区
                            strncpy(analysis_Str, uart1_recstring + 136, 7);    //提取出"led"
                            //printf("att is %s\r\n",analysis_Str);
                            if (strcmp(analysis_Str, "ActVel1") == 0) {
                                //printf("led set %c\r\n",uart1_recstring[145]);

                                if (uart1_recstring[144] == ':') {
									speed = (uart1_recstring[145] - '0') * 10  + (uart1_recstring[146] - '0');
//                                  printf("关灯\r\n");

                                } else if (uart1_recstring[145] == '1') {
                                    printf("开灯\r\n");
                                    //LED_TurnOn(3);
                                }
                                //向云平台完成命令响应
                                printf("AT+MQTTPUB=0,\"$oc/devices/%s/sys/commands/response/request_id=%s\",\"\",0,0\r\n",
                                       HUAWEI_MQTT_DeviceID, request_id);

                                memset(analysis_Str, 0, sizeof(analysis_Str));//清空缓存区  		
                                memset(str_temp, 0, sizeof(str_temp));                //清空缓存区  																	
                            }
                        }
                    }

                }
            }
            uart1_rec_i = 0;
            memset(uart1_recstring, 0, sizeof(uart1_recstring));//清空uart1_recstring字符串
            memset(sub_string, 0, sizeof(sub_string));                    //清空sub_string字符串				
        }
    }
}

//内部调用函数,注意要勾选OPTIONS中的USE Micro LIB选项
int fputc(int ch, FILE *f)   //printf重定向  
{
    USART_SendData(USART1, (uint8_t) ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    return ch;
}

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"

void MyUSART_Init(void);

#endif

到了这里,关于STM32+ESP8266+华为云的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 HAL库+ESP8266+华为云物联网平台

    文章内容:     STM32 HAL库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台,并完成基本通信与控制,包括设备属性上报和命令下发解析与响应。     文末获取 “STM32 HAL库+ESP8266+华为云物联网平台keil工程 ”下载的链接。 一、华为云物联网平台 创建 产品

    2024年02月14日
    浏览(60)
  • 单片机项目分享 单片机(stm32)远程智能宠物喂养系统 - 物联网 esp8266

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(67)
  • 嵌入式项目分享 单片机(stm32)远程智能宠物喂养系统 - 物联网 esp8266

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(168)
  • 单片机设计_语音识别分类智能垃圾桶(STM32 ESP8266 LD3320)

    想要更多项目私wo!!!         离线语音识别识别垃圾种类并且垃圾桶自动翻盖: 说出唤醒词“垃圾桶”后,再说一句垃圾名称,语音识别模块端识别到相应,便会将结果通过串口发送到STM32端,STM32端接着会发送打开相应垃圾桶盖的指令,6s后,垃圾桶盖自动关闭。

    2024年02月06日
    浏览(53)
  • 毕业设计 单片机语音识别分类智能垃圾桶(STM32 ESP8266 LD3320)

    离线语音识别识别垃圾种类并且垃圾桶自动翻盖: 说出唤醒词“垃圾桶”后,再说一句垃圾名称,语音识别模块端识别到相应,便会将结果通过串口发送到STM32端,STM32端接着会发送打开相应垃圾桶盖的指令,6s后,垃圾桶盖自动关闭。其中翻盖功能是通过STM32端控制舵

    2024年04月26日
    浏览(71)
  • 【开源项目自学笔记】STM32与ESP8266通讯

    文章目录 系列文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 这个项目学习了这几块内容:stm32的串口中断,定时器中断,时间片轮询机制,esp8266,DTH11温湿度传感器的使用。对串口通信收发数据的处理。 设计知识点:串口的格式化打印。DWT内核精

    2024年02月13日
    浏览(38)
  • 十、stm32-ESP8266(串口透传、MCU透传、控制LED亮灭)

    见博客:stm32f103c8t6新建固件库模板(可自取) 固件库模板 MDK5开发环境 stm32参考手册 UART串口协议 stm32中断概念 ESP8266模块资料 利用固件库模板点灯工程(下面第三行,手动狗头) CH340 USB→TTL模块 ESP8266模块 手机软件 实验程序已经发布到百度网盘,本文末有链接可以自取

    2023年04月19日
    浏览(48)
  • 关于stm32控制esp8266链接阿里云时遇到的一些问题

    目录 问题一:关于mqtt的AT命令 固件问题而产生的其他问题: 关于mqtt报文连接阿里云的问题 用串口调试助手发送: AT+MQTTCONN=0,\\\"iot-06z00fmgtrunfzt.mqtt.iothub.aliyuncs.com\\\",1883,0 一直回复error,连不上的问题 当我的esp8266烧录的是1112号的固件,这个固件我不知道是不是有问题,有时候能

    2024年01月25日
    浏览(47)
  • STM32--ESP8266物联网WIFI模块(贝壳物联)--远程无线控制点灯

    本文适用于STM32F103C8T6等MCU,其他MCU可以移植,完整资源见文末链接 一、简介 随着移动物联网的发展,各场景下对于物联控制、数据上传、远程控制的诉求也越来越多,基于此乐鑫科技推出了便宜好用性价比极高的wifi物联模块——ESP8266,话不多少我们先来看看这个神奇的模

    2024年02月08日
    浏览(65)
  • 【学习笔记】stm32+ESP8266+阿里云+云智能APP

    个人笔记。实现的功能是通过手机APP实现对stm32上小灯的控制。 硬件环境: 1.stm32F103 2.Node MCU-ESP8266 3.安卓手机 硬件连接: ESP8266              STM32 RX                           PA2 TX                            PA3 RST                          PA4 VCC 3V3 GND GND 配置阿

    2024年01月21日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包