1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.基本原理&知识点 1.1运行原理: 单片机通过串口usart向esp8266发送AT指令,上报信息。 其他设备上报的信息通过云,传送到单片机端的esp8266。 单片机通过串口usart接收esp8266所得到的云端信息。 1.2esp8266 at 指令 【对于穿透的理解】 顾名思义,开启穿透就是不用管wifi协议怎么实现的~ 我们只用专注于在A设备和B设备间使用串口收发数据, 就好像A和B直接用导线相连~ 就好像穿透了~ +++可推出穿透模式 【ESP8266的一般使用顺序】 这里的“一般”指的是:ESP8266连接当前环境的热点,与服务器建立TCP连接,传输数据。 AT+CWMODE=1:设置工作模式(STA模式) AT+RST:模块重启(生效工作模式) AT+CWJAP=“111”,“11111111”:连接当前环境的WIFI热点(热点名,密码) AT+CIPMUX=0:设置单路连接模式 AT+CIPSTART=“TCP”,“xxx.xxx.xxx.xxx”,xxxx:建立TCP连接 AT+CIPMODE=1:开启透传模式 AT+CIPSEND:透传模式下,传输数据 +++:退出透传模式 1.3mqtt协议 普通的socket连接对服务器的消耗太大,所以出现了类似MQTT这种轻量级、低消耗的协议来维护长连接。维护长连接需要采用心跳机制… 这篇博客写的比较简练——感谢博主. 2.云平台部分【阿里云】 我之前博客的连接. tips:点灯的产品流转规则~没必要用json格式,二进制就行。 所谓的产品流转规则就是数据的流转规则,而数据又依托存放在topic中。 故:产品流转规则就是设计A设备使用的topic数据传送到B设备使用的topic. 3.上位机部分【安卓app】 我之前的android studio 开发app博客专题合集——mqtt.jar包. 4.下位机部分【stm32+AT指令】 库移植操作: 4.1mqtt协议库 这个库有6个函数,作用如函数名所示 4.2esp8266at指令库 这个库有12个函数,对at指令做了封装,直接调用相应函数(不用死记at指令) 4.3main.c 4.3.1 宏定义 4.3.2 main函数 4.3.3 自定义函数 USART1接收中断代码 /****** USART1接收中断代码 *****/ // ES8266驱动串口接收中断处理函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) // 判断是由哪个串口触发的中断 { //将接收到的数据放入接收usart1接收数组 usart1_rxbuf[usart1_rxcounter] = usart1_rxone[0]; usart1_rxcounter++; //接收数量+1 //重新使能串口1接收中断 /**【易错~~接受回调函数中别忘再次使能】*/ HAL_UART_Receive_IT(&huart1,usart1_rxone,1); } } 进入错误模式代码 /************ 进入错误模式代码 ************/ //进入错误模式等待手动重启 void Enter_ErrorMode(uint8_t mode) { HAL_GPIO_WritePin(LED_G_GPIO_Port,LED_G_Pin,GPIO_PIN_SET); while(1) { switch(mode){ case 0:user_main_error("ESP8266初始化失败!rn");break; case 1:user_main_error("ESP8266连接热点失败!rn");break; case 2:user_main_error("ESP8266连接阿里云服务器失败!rn");break; case 3:user_main_error("ESP8266阿里云MQTT登陆失败!rn");break; case 4:user_main_error("ESP8266阿里云MQTT订阅主题失败!rn");break; default:user_main_info("Nothingrn");break; } user_main_info("请重启开发板"); //HAL_GPIO_TogglePin(LED_R_GPIO_Port,LED_R_Pin); HAL_Delay(200); } } 初始化函数 /************* STM32 MQTT业务代码 **********/ //MQTT初始化函数 void ES8266_MQTT_Init(void) { uint8_t status=0; //初始化|检查esp8266好坏 if(ESP8266_Init()) { user_main_info("ESP8266初始化成功!rn"); status++; } else Enter_ErrorMode(0); //连接手机热点|家庭wifi if(status==1) { if(ESP8266_ConnectAP(WIFI_NAME,WIFI_PASSWD)) { user_main_info("ESP8266连接热点成功!rn"); status++; } else Enter_ErrorMode(1); } //连接阿里云IOT服务器 if(status==2) { if(ESP8266_ConnectServer("TCP",MQTT_BROKERADDRESS,1883)!=0) { user_main_info("ESP8266连接阿里云服务器成功!rn"); status++; } else Enter_ErrorMode(2); } //登陆MQTT if(status==3) { if(MQTT_Connect(MQTT_CLIENTID, MQTT_USARNAME, MQTT_PASSWD) != 0) { user_main_info("ESP8266阿里云MQTT登陆成功!rn"); status++; } else Enter_ErrorMode(3); } //订阅主题 if(status==4) { if(MQTT_SubscribeTopic(MQTT_SUBSCRIBE_TOPIC,0,1) != 0) { user_main_info("ESP8266阿里云MQTT订阅主题成功!rn"); } else Enter_ErrorMode(4); } } 单片机状态上报——————依据项目修改 /******* 单片机状态上报 *************/ //单片机状态上报 void STM32DHT11_StatusReport(void) { //获取温湿度信息 uint8_t temperature; uint8_t humidity; uint8_t get_times; // 获取温湿度信息并用串口打印,获取十次,直到成功跳出 for(get_times=0;get_times<10;get_times++) { if(!dht11Read(&temperature, &humidity))//Read DHT11 Value { user_main_info("temperature=%d,humidity=%d n",temperature,humidity); break; } } //上报一次数据 uint8_t led_r_status = HAL_GPIO_ReadPin(LED_R_GPIO_Port,LED_R_Pin) ? 0:1; uint8_t led_g_status = HAL_GPIO_ReadPin(LED_G_GPIO_Port,LED_G_Pin) ? 0:1; uint8_t led_b_status = HAL_GPIO_ReadPin(LED_B_GPIO_Port,LED_B_Pin) ? 0:1; sprintf(mqtt_message, "{"method":"thing.service.property.set","id":"181454577","params":{ "DHT11_Temperature":%.1f, "DHT11_Humidity":%.1f, "Switch_LEDR":%d, "Switch_LEDG":%d, "Switch_LEDB":%d },"version":"1.0.0"}", (float)temperature, (float)humidity, led_r_status, led_g_status, led_b_status ); //阿里云数据上报格式~ MQTT_PublishData(MQTT_PUBLISH_TOPIC,mqtt_message,0); // } 字符串处理函数*2 /*********** 自定义函数~方便处理str *******/ char temp_str[30]; // 临时子串 /**从母串中获取与子串长度相等的临时子串*/ void ReadStrUnit(char * str,char *temp_str,int idx,int len) // 从母串中获取与子串长度相等的临时子串 { int index; for(index = 0; index < len; index++) { temp_str[index] = str[idx+index]; } temp_str[index] = ' |