这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 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 跳转至

回复

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