这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» STM32» STM32G070RB探测23-ESP8266(ESP01S)http上传数据至

共2条 1/1 1 跳转至

STM32G070RB探测23-ESP8266(ESP01S)http上传数据至Onenet(单片机控制)

高工
2021-01-24 01:02:15 打赏
好几天没更新了,因为最近年底赶进度忙了起来,加班多咯,今天接着上篇,写一下如何使用STM32G070RB控制esp8266通过HTTP协议上传数据到Onenet平台根据上篇用串口助手操作,这篇直接按照这个套路上传就行了

1.连接wifi 2.连接TCP服务器 3.发送POST数据

前两条之前已经操作过了(第14篇),添加一个透传模式设置以及发送代码即可

编写代码

添加透传模式

直接在之前的初始化命令数组里边添加即可

//前边是发送的指令,后边是要确定的回令 char *const esp_inti_cmd[][2] = { {"AT\r\n", "OK"}, {"ATE0\r\n", "OK"}, {"AT+CWMODE=3\r\n", "OK"}, {"AT+CWJAP=\"******\",\"********\"\r\n", "GOT IP"}, {"AT+CIFSR\r\n", "OK"}, {"AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n", "CONNECT"}, {"AT+CIPMODE=1\r\n", "OK"}, {"AT+CIPSEND\r\n", ">"}, {0, 0} };

重要的是如何封装数据

POST /devices/device_id/datapoints?type=3 HTTP/1.1 api-key:*********************** Host:api.heclouds.com Content-Length:10 {"tem":42}

类似于这样,来进行字符串操作,主要用到了sprintf和strcat strcat就是将两个字符串拼接起来

添加两个宏定义

#define DEVID #define APIKEY

就是device_id和api-key

我的代码也是参考onenet的官方例程写的 展示一下

void OneNet_FillBuf(char *buf) { char text[24]; char buf1[128]; memset(text, 0, sizeof(text)); memset(buf1, 0, sizeof(buf1)); strcpy(buf1, "{"); memset(text, 0, sizeof(text)); sprintf(text,"\"tem\":%.1f,",pv.tem); strcat(buf1, text); memset(text, 0, sizeof(text)); sprintf(text,"\"hum\":%d,",pv.hum); strcat(buf1, text); memset(text, 0, sizeof(text)); sprintf(text,"\"lux\":%d",pv.lux_16); strcat(buf1, text); strcat(buf1, "}"); sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\n" "Content-Length:%d\r\n\r\n", DEVID, APIKEY, strlen(buf1)); strcat(buf, buf1); }

先测试一下这个函数的封装效果对不对

可以,是这个效果

然后直接发送就行了

void OneNet_SendData(void) { char buf[256]; memset(buf, 0, sizeof(buf)); OneNet_FillBuf(buf); //封装数据流 ESP_SendString((unsigned char *)buf, strlen(buf)); //上传数据 }

主函数里添加

while (1) { static uint8_t num; num++; BH1750_Send_Cmd(ONCE_H_MODE);//单次模式 sprintf(buf,"tem:%.1f ",pv.tem); OLED_P8x16Str(0u,2u,(uint8_t *)buf); sprintf(buf,"hum:%d%% ",pv.hum); OLED_P8x16Str(0u,4u,(uint8_t *)buf); sprintf(buf,"lux:%d ",pv.lux_16); OLED_P8x16Str(0u,6u,(uint8_t *)buf); HAL_Delay(500); AHT10ReadData(&pv.tem,&pv.hum); BH1750_Read_Dat(pv.lux);//读取数据 pv.lux_16 = BH1750_Dat_To_Lux(pv.lux);//转换数据 printf("lux:%d\r\n",pv.lux_16); printf("tem:%.1f\r\nhum:%d%%\r\n",pv.tem,pv.hum); if(num>10) { num = 0; OneNet_SendData(); } if(usart1_rx.flag)//接收到数据 { printf("%s",usart1_rx.rx_buff); Clear_Usart(&usart1_rx);//清空缓存 } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }

5s发送一次

出来咯



高工
2021-01-27 23:21:51 打赏
2楼

优化,将透传模式改为定长发送模式

首先,将初始化里透传模式命令删除


添加定长发送函数

//========================================================== // 函数名称: ESP8266_SendData // // 函数功能: 发送数据 // // 入口参数: data:数据 // len:长度 // // 返回参数: 无 // // 说明: //========================================================== void ESP8266_SendData(unsigned char *data, unsigned short len) { char cmdBuf[32]; uint16_t timeOut = 5000; Clear_Usart(&usart1_rx);//清空接收缓存 sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len); //发送命令 if(!ESP8266_SendCmd(cmdBuf, "OK",5000)) //收到‘>’时可以发送数据 { ESP_SendString(data, len); //发送设备连接请求数据 while(timeOut--)//等待 { if(usart1_rx.flag) //如果收到数据 { if(strstr((const char *)usart1_rx.rx_buff, "SEND OK") != NULL) //如果匹配到数据 { Clear_Usart(&usart1_rx); //清空缓存 } else { Clear_Usart(&usart1_rx); //清空缓存 } } } } }


然后替换onenet_send


void OneNet_SendData(void) { char buf[256]; memset(buf, 0, sizeof(buf)); OneNet_FillBuf(buf); //封装数据流 ESP8266_SendData((unsigned char *)buf, strlen(buf)); }



共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]