文章目录
一、概要
- 使用STM32单片机连接阿里云平台,实现数据上传与接收
二、整体架构流程
项目详细说明主控STM32F103ZET6通信串口通信,波特率:115200、数据位:8、停止位:1、校验:None开发软件STM32CubeMX硬件ESP32-01S
将ESP32-01S单片机串口连接到STM32串口二,使用AT指令控制wifi模块,连接阿里云平台;
三、软件流程
3.1 STM32CubeMX生成基础软件
- 选择主芯片,这里我选择STM32F103ZET6,根据自己情况选择,常用的型号都可以,思路是一样的;
- 配置调试口这里需要配置为图中所示,因为我用的STLink仿真器,使用Jlink也是一样的。
- 配置时钟因为我使用的是开发板,上面有外部晶振,所以这里我配置为外部时钟。大家可以根据自己的情况选择;这里我使用的时钟为外部8M晶振,系统时钟为72M,可以按照这个配置;
- 串口配置因为这里需要和esp32-01s通信,所以需要配置串口,波特率115200,其他不变。我也配置了串口DMA,看各自需求,其实也可以不用配置; 以上就是基础工程配置,输出用Keil编程框架;
3.2 ESP32-01S初始化及配置
这里采用的是AT指令操作,说直白一点就是,我单片机发送这些指令就可以控制esp32-01s这个wifi模块操作相应动作;
AT:测试AT启动,返回OK
AT+RST:重启模块,返回OK
AT+GMR:查看版本信息,返回 OK ,为8位版本号
AT+CWJAP=“WiFi名字”,“密码”:连接WiFi
AT+CWAUTOCONN=1:设置开机自动连入Wifi
AT+CIPMUX=1:设置单连接
AT+CIOBAUD=115200:修改波特率
指令说明实例AT+RST软重启模块TX:OKAT+RESTORE恢复出厂设置TX:OK
- 串口调试助手测试这里发送了一条复位指令,串口会返回相应指令,这样的话,我们STM32就知道是否执行成功。这就是与wifi模块基础的通信问题;
- 连接wifi热点 首先我们需要对wifi模块进行小小的更新,买到手的模块可能是AT固件,我们需要更新为MQTT固件,具体操作不在这里说明,网上很多;
我们先来连接一下整个连接流
1.刚上电,我们可以复位一下wifi模块,发送指令:AT+RST
2.可以重置一下旧配置,以免影响本次操作,发送指令:AT+RESTORE
3.我们需要让wifi模块主动去连接手机热点,所有需要配置一下模式,发送指令:AT+CWMODE=1
4.因为模块是不知道我们手机热点的名字和密码的,所有我们需要告知模块这两个信息,发送指令AT+CWJAP=“wifi名字”,“wifi密码”
以上操作后在手机上就会看到有设备连接,名字大概就是esp32…,类似,大差不差的
- 连接阿里云平台 连接阿里云需要自己注册一个平台账号,在平台创建产品与设备,这里就不在阐述了,网上很多的;附上截图一张 上面为阿里云平台入口,创建好产品和设备后得到一些数据如下:这里的MQTT参数就是我们需要的,需要通过AT指令告知wifi模块这里信息数据
3.3 STM32软件实现
以上操作都是通过串口发送字符串,所以我们需要实现的是STM32串口发送字符串,参考程序如下:
voidESP8266_SendString(uint8_t*str,uint8_t len){uint8_t i=0;for(i=0;i<len;i++){
USART2->DR =*str;
str++;HAL_Delay(1);}}uint8_tESP8266_SendCmd(uint8_t*cmd,uint8_t*res){uint8_t num =200;ESP8266_Clear();ESP8266_SendString(cmd,strlen((constchar*)cmd));while(num--){if(strstr((constchar*)esp_buff,(constchar*)res)!=NULL){ESP8266_Clear();return0;}HAL_Delay(10);}return1;}
通过上述两个函数,就可以简单实现AT指令发送了,例如:
#defineWIFI_NAME"spx24"// wifi名#defineWIFI_PASS"52xiaobai999"// wifi密码voidESP8266_Init(void){HAL_UART_Receive_DMA(&huart2,esp_buff,ESPBUFF_MAX_SIZE);// 开启DMA接收__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);// 开启串口的空闲中断while(ESP8266_SendCmd("AT+RST\r\n","ready"))while(ESP8266_SendCmd("AT\r\n","OK")){}while(ESP8266_SendCmd("AT+CWMODE=1\r\n","OK")){}while(ESP8266_SendCmd("AT+CWJAP=\""WIFI_NAME"\",\""WIFI_PASS"\"\r\n","OK")){}}
连接阿里云也是一样的道理,替换成自己的参数即可:
// 设置阿里账号,上云#defineALI_USERNAME"xxx&k1v5xYRUyUn"#defineALICLIENTLD"xxx"#defineALI_PASSWD"xxx"#defineALI_MQTT_HOSTURL"xxx"#defineALI_PORT"1883"#defineALI_TOPIC_SET"/sys/k1v5xYRUyUn/xxx/thing/service/property/set"#defineALI_TOPIC_POST"/sys/k1v5xYRUyUn/xxx/thing/event/property/post"voidAli_Yun_Init(void){//设置用户名,密码while(ESP8266_SendCmd("AT+MQTTUSERCFG=0,1,\"NULL\",\""ALI_USERNAME"\",\""ALI_PASSWD"\",0,0,\"\"\r\n","OK")){}HAL_Delay(10);// 设置客服idwhile(ESP8266_SendCmd("AT+MQTTCLIENTID=0,\""ALICLIENTLD"\"\r\n","OK")){}// 连接腾讯云 AT+MQTTCONN=0,"iot-06z00b28nanp9ew.mqtt.iothub.aliyuncs.com",1883,1while(ESP8266_SendCmd("AT+MQTTCONN=0,\""ALI_MQTT_HOSTURL"\",1883,1\r\n","OK")){}Ali_Yun_Topic();}voidAli_Yun_Topic(void){//"AT+MQTTPUB=0,\"发布的主题\",\"";while(ESP8266_SendCmd("AT+MQTTSUB=0,\""ALI_TOPIC_SET"\",0\r\n","OK")){}while(ESP8266_SendCmd("AT+MQTTSUB=0,\""ALI_TOPIC_POST"\",0\r\n","OK")){}}
现在需要上传数据至云平台,或者从云平台下发指令等等操作。在云平台创建一些模块,例如,温度湿度,LED灯等。
单片机软件实现:
voidAli_Yun_Send(void){uint8_t msg_buf[1024];uint8_t params_buf[1024];uint8_t data_value_buf[24];uint16_t move_num =0;
cJSON *send_cjson =NULL;char*str =NULL;int i=0;
cJSON *params_cjson =NULL;memset(msg_buf,0,sizeof(msg_buf));memset(params_buf,0,sizeof(params_buf));memset(data_value_buf,0,sizeof(data_value_buf));
send_cjson =cJSON_CreateObject();
params_cjson =cJSON_CreateObject();cJSON_AddNumberToObject(params_cjson,"temperature",temp_value++);cJSON_AddNumberToObject(params_cjson,"Humidity",humi_value++);cJSON_AddItemToObject(send_cjson,"params", params_cjson);cJSON_AddItemToObject(send_cjson,"version",cJSON_CreateString("1.0.0"));
str =cJSON_PrintUnformatted(send_cjson);for(i=0;*str!='\0';i++){
params_buf[i]=*str;if(*(str+1)=='"'||*(str+1)==','){
params_buf[++i]='\\';}
str++;
move_num++;}
str = str - move_num;sprintf((char*)msg_buf,"AT+MQTTPUB=0,\""ALI_TOPIC_POST"\",\"%s\",0,0\r\n",params_buf);ESP8266_SendCmd(msg_buf,"OK");ESP8266_Clear();cJSON_Delete(send_cjson);if(str!=NULL){free(str);
str =NULL;}}
四、技术细节
4.1 MQTT
- 什么是MQTT
消息队列遥测传输协议,是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,并且该协议构建于TCP/IP协议之上,我们知道TCP协议本身就具有高可靠性的特点,因此基于其上的MQTT协议同样也是具有高可靠、低开销的特点,之所以低开销,是以为MQTT协议传输的最小的报文也只有两个字节。
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分
- Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)
- payload,可以理解为消息的内容,是指订阅者具体要使用的内容
在我们这里,单片机上传数据时,我们就作为发布者,当接收数据时,我们则作为订阅者,其他操作我们不用过多关心;
- cJson
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
语法规则如下:
JSON 语法衍生于 JavaScript 对象标记法语法:
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号{}容纳对象
- 方括号[]容纳数组
举个例子:
{"information":{"school":"编程大学","grade":4,"专业":"软件工程"}}
对于我们这里来说,为了完成这个功能,不用了解过多,能用即可。
小结
以上是一个简单的STM32连接阿里云平台的实例,没有过多操作,很简单。也是为了方便记录自己调试心得,内容有错地方还请各位指出,共同学习进步;实现这个功能之后就可以由此衍生,如下:
- 完成真实的数据上传,例如温湿度,GPS定位,烟雾等;
- 可以云平台下发指令开灯,关灯,以及控制电机等;
- 也可以编写App对接平台,远程控制单片机;
- 还可以通过云平台进行IAP升级,云平台好像支持这个远程升级功能;
最后这个程序很简单,网上也有很多参考教程,我也可以发出来给大家一起参考;
版权归原作者 ProMonkeyZ 所有, 如有侵权,请联系我们删除。