当前位置: 代码网 > 科技>人工智能 > STM32+ESP8266上传温湿度数据至新版OneNET

STM32+ESP8266上传温湿度数据至新版OneNET

2024年08月02日 人工智能 我要评论
其中,timeCount变量用于控制发送数据的时间间隔,dataPtr变量用于存储ESP8266模块接收到的数据。如果timeCount计数达到50,则执行发送数据的操作,将温湿度数据上传至OneNET平台并清空ESP8266模块缓存。同时,使用ESP8266_GetIPD函数获取ESP8266模块接收到的数据,并使用OneNet_RevPro函数处理该数据。之后分别发送AT指令,设置模块为STA模式、连接WiFi、连接到OneNet平台。3. 创建产品,点击左侧“产品中心”然后在主界面右侧“创建产品”

本文详细介绍了,stm32连接新版onenet平台上报温湿度数据的操作与步骤。

使用资源:

stm32f103c8t6、esp826612f、dht11温湿度传感器

通讯协议:

mqtt

数据格式:

cjson

一、onenet平台创建

1.  登录https://open.iot.10086.cn/,注册账号、登录。

2.  点击右上角的“开发者中心”进入产品开发界面

 3. 创建产品,点击左侧“产品中心”然后在主界面右侧“创建产品”

 创建产品信息:

添加产品物模型信息:点击创建产品的“产品开发”

 编辑物模型:点击“设置物模型”,只保留当前温度和当前湿度,删除多余物模型即可

4. 添加设备 

点击左侧“设备管理”,然后点击“添加设备”

添加设备信息: 

 5. 设备信息查看

 二、设备端代码编写

主要代码包含:esp8266.c、mqtt.c、onenet.c、main.c

1. esp8266.c

首先对gpioa进行初始化,将gpioa0配置为复位引脚。然后进行esp8266模块的复位操作。接着调用esp8266_clear函数清空esp8266模块的接收缓存区。之后分别发送at指令,设置模块为sta模式、连接wifi、连接到onenet平台。最后输出esp8266初始化成功的信息。

//单片机头文件
#include "stm32f10x.h"

//网络设备驱动
#include "esp8266.h"

//硬件驱动
#include "delay.h"
#include "usart.h"

//c库
#include <string.h>
#include <stdio.h>

#define esp8266_wifi_info		"at+cwjap=\"xxxxxx\",\"xxxxxxx\"\r\n"


#define esp8266_onenet_info		"at+cipstart=\"tcp\",\"mqtts.heclouds.com\",1883\r\n"  //新版onenet地址

unsigned char esp8266_buf[128];
unsigned short esp8266_cnt = 0, esp8266_cntpre = 0;


//==========================================================
//	函数名称:	esp8266_clear
//
//	函数功能:	清空缓存
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void esp8266_clear(void)
{

	memset(esp8266_buf, 0, sizeof(esp8266_buf));
	esp8266_cnt = 0;

}

//==========================================================
//	函数名称:	esp8266_waitrecive
//
//	函数功能:	等待接收完成
//
//	入口参数:	无
//
//	返回参数:	rev_ok-接收完成		rev_wait-接收超时未完成
//
//	说明:		循环调用检测是否接收完成
//==========================================================
_bool esp8266_waitrecive(void)
{

	if(esp8266_cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数
		return rev_wait;
		
	if(esp8266_cnt == esp8266_cntpre)				//如果上一次的值和这次相同,则说明接收完毕
	{
		esp8266_cnt = 0;							//清0接收计数
			
		return rev_ok;								//返回接收完成标志
	}
		
	esp8266_cntpre = esp8266_cnt;					//置为相同
	
	return rev_wait;								//返回接收未完成标志

}

//==========================================================
//	函数名称:	esp8266_sendcmd
//
//	函数功能:	发送命令
//
//	入口参数:	cmd:命令
//				res:需要检查的返回指令
//
//	返回参数:	0-成功	1-失败
//
//	说明:		
//==========================================================
_bool esp8266_sendcmd(char *cmd, char *res)
{
	
	unsigned char timeout = 200;

	usart_sendstring(usart2, (unsigned char *)cmd, strlen((const char *)cmd));
	
	while(timeout--)
	{
		if(esp8266_waitrecive() == rev_ok)							//如果收到数据
		{
			if(strstr((const char *)esp8266_buf, res) != null)		//如果检索到关键词
			{
				esp8266_clear();									//清空缓存
				
				return 0;
			}
		}
		delay_ms(10);
	}
	
	return 1;

}

//==========================================================
//	函数名称:	esp8266_senddata
//
//	函数功能:	发送数据
//
//	入口参数:	data:数据
//				len:长度
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void esp8266_senddata(unsigned char *data, unsigned short len)
{

	char cmdbuf[200];
	
	esp8266_clear();								//清空接收缓存
	sprintf(cmdbuf, "at+cipsend=%d\r\n", len);		//发送命令
	if(!esp8266_sendcmd(cmdbuf, ">"))				//收到‘>’时可以发送数据
	{
		usart_sendstring(usart2, data, len);		//发送设备连接请求数据
	}

}

//==========================================================
//	函数名称:	esp8266_getipd
//
//	函数功能:	获取平台返回的数据
//
//	入口参数:	等待的时间(乘以10ms)
//
//	返回参数:	平台返回的原始数据
//
//	说明:		不同网络设备返回的格式不同,需要去调试
//				如esp8266的返回格式为	"+ipd,x:yyy"	x代表数据长度,yyy是数据内容
//==========================================================
unsigned char *esp8266_getipd(unsigned short timeout)
{

	char *ptripd = null;
	
	do
	{
		if(esp8266_waitrecive() == rev_ok)								//如果接收完成
		{
			ptripd = strstr((char *)esp8266_buf, "ipd,");				//搜索“ipd”头
			if(ptripd == null)											//如果没找到,可能是ipd头的延迟,还是需要等待一会,但不会超过设定的时间
			{
				//usartprintf(usart_debug, "\"ipd\" not found\r\n");
			}
			else
			{
				ptripd = strchr(ptripd, ':');							//找到':'
				if(ptripd != null)
				{
					ptripd++;
					return (unsigned char *)(ptripd);
				}
				else
					return null;
				
			}
		}
//		usartprintf(usart_debug,"esp8266_waitrecive: %s\n", esp8266_buf);   //提示打印信息
		delay_ms(5);													//延时等待
	} while(timeout--);
	
	return null;														//超时还未找到,返回空指针

}

//==========================================================
//	函数名称:	esp8266_init
//
//	函数功能:	初始化esp8266
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void esp8266_init(void)
{
	
	gpio_inittypedef gpio_initure;
	
	rcc_apb2periphclockcmd(rcc_apb2periph_gpioa, enable);

	//esp8266复位引脚
	gpio_initure.gpio_mode = gpio_mode_out_pp;
	gpio_initure.gpio_pin = gpio_pin_0;					//gpioa0-复位
	gpio_initure.gpio_speed = gpio_speed_50mhz;
	gpio_init(gpioa, &gpio_initure);
	
	gpio_writebit(gpioa, gpio_pin_0, bit_reset);
	delay_ms(250);
	gpio_writebit(gpioa, gpio_pin_0, bit_set);
	delay_ms(500);
	
	esp8266_clear();

	usartprintf(usart_debug, "1. at\r\n");
	while(esp8266_sendcmd("at\r\n", "ok"))
		delay_ms(500);
	
	usartprintf(usart_debug, "2. cwmode\r\n");
	while(esp8266_sendcmd("at+cwmode=1\r\n", "ok"))
		delay_ms(500);
	
	usartprintf(usart_debug, "3. cwjap\r\n");
	while(esp8266_sendcmd(esp8266_wifi_info, "got ip"))
		delay_ms(500);
	
	usartprintf(usart_debug, "4. cipstart\r\n");
	while(esp8266_sendcmd(esp8266_onenet_info, "connect"))
		delay_ms(500);
	
	usartprintf(usart_debug, "5. esp8266 init ok\r\n");

}

//==========================================================
//	函数名称:	usart2_irqhandler
//
//	函数功能:	串口2收发中断
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void usart2_irqhandler(void)
{

	if(usart_getitstatus(usart2, usart_it_rxne) != reset) //接收中断
	{
		if(esp8266_cnt >= sizeof(esp8266_buf))	esp8266_cnt = 0; //防止串口被刷爆
		esp8266_buf[esp8266_cnt++] = usart2->dr;
		
		usart_clearflag(usart2, usart_flag_rxne);
	}

}

2. mqtt.c

mqtt程序编写流程如下:

引入mqtt库和所需的头文件。

连接wifi网络。

连接mqtt服务器。

订阅需要接收的主题。

在程序中实现消息的发布和接收。

关闭mqtt连接。

主要代码如下:

//协议头文件
#include "mqttkit.h"

//c库
#include <string.h>
#include "usart.h"

#define cmd_topic_prefix		"$creq"


//==========================================================
//	函数名称:	edp_newbuffer
//
//	函数功能:	申请内存
//
//	入口参数:	edppacket:包结构体
//				size:大小
//
//	返回参数:	无
//
//	说明:		1.可使用动态分配来分配内存
//				2.可使用局部或全局数组来指定内存
//==========================================================
void mqtt_newbuffer(mqtt_packet_structure *mqttpacket, uint32 size)
{
	
	uint32 i = 0;

	if(mqttpacket->_data == null)
	{
		mqttpacket->_memflag = mem_flag_alloc;
		
		mqttpacket->_data = (uint8 *)mqtt_mallocbuffer(size);
		if(mqttpacket->_data != null)
		{
			mqttpacket->_len = 0;
			
			mqttpacket->_size = size;
			
			for(; i < mqttpacket->_size; i++)
				mqttpacket->_data[i] = 0;
		}
	}
	else
	{
		mqttpacket->_memflag = mem_flag_static;
		
		for(; i < mqttpacket->_size; i++)
			mqttpacket->_data[i] = 0;
		
		mqttpacket->_len = 0;
		
		if(mqttpacket->_size < size)
			mqttpacket->_data = null;
	}

}

//==========================================================
//	函数名称:	mqtt_deletebuffer
//
//	函数功能:	释放数据内存
//
//	入口参数:	edppacket:包结构体
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void mqtt_deletebuffer(mqtt_packet_structure *mqttpacket)
{

	if(mqttpacket->_memflag == mem_flag_alloc)
		mqtt_freebuffer(mqttpacket->_data);
	
	mqttpacket->_data = null;
	mqttpacket->_len = 0;
	mqttpacket->_size = 0;
	mqttpacket->_memflag = mem_flag_null;

}

int32 mqtt_dumplength(size_t len, uint8 *buf)
{
	
	int32 i = 0;
	
	for(i = 1; i <= 4; ++i)
	{
		*buf = len % 128;
		len >>= 7;
		if(len > 0)
		{
			*buf |= 128;
			++buf;
		}
		else
		{
			return i;
		}
	}

	return -1;
}

int32 mqtt_readlength(const uint8 *stream, int32 size, uint32 *len)
{
	
	int32 i;
	const uint8 *in = stream;
	uint32 multiplier = 1;

	*len = 0;
	for(i = 0; i < size; ++i)
	{
		*len += (in[i] & 0x7f) * multiplier;

		if(!(in[i] & 0x80))
		{
			return i + 1;
		}

		multiplier <<= 7;
		if(multiplier >= 2097152)		//128 * *128 * *128
		{
			return -2;					// error, out of range
		}
	}

	return -1;							// not complete

}

//==========================================================
//	函数名称:	mqtt_unpacketrecv
//
//	函数功能:	mqtt数据接收类型判断
//
//	入口参数:	dataptr:接收的数据指针
//
//	返回参数:	0-成功		其他-失败原因
//
//	说明:		
//==========================================================
uint8 mqtt_unpacketrecv(uint8 *dataptr)
{
	
	uint8 status = 255;
	uint8 type = dataptr[0] >> 4;				//类型检查
	
	if(type < 1 || type > 14)
		return status;
	
	if(type == mqtt_pkt_publish)
	{
		uint8 *msgptr;
		uint32 remain_len = 0;
		
		msgptr = dataptr + mqtt_readlength(dataptr + 1, 4, &remain_len) + 1;
		
		if(remain_len < 2 || dataptr[0] & 0x01)					//retain
			return 255;
		
		if(remain_len < ((uint16)msgptr[0] << 8 | msgptr[1]) + 2)
			return 255;
		
		if(strstr((int8 *)msgptr + 2, cmd_topic_prefix) != null)	//如果是命令下发
			status = mqtt_pkt_cmd;
		else
			status = mqtt_pkt_publish;
	}
	else
		status = type;
	
	return status;

}

//==========================================================
//	函数名称:	mqtt_packetconnect
//
//	函数功能:	连接消息组包
//
//	入口参数:	user:用户名:产品id
//				password:密码:鉴权信息或apikey
//				devid:设备id
//				ctime:连接保持时间
//				clean_session:离线消息清除标志
//				qos:重发标志
//				will_topic:异常离线topic
//				will_msg:异常离线消息
//				will_retain:消息推送标志
//				mqttpacket:包指针
//
//	返回参数:	0-成功		其他-失败
//
//	说明:		
//==========================================================
uint8 mqtt_packetconnect(const int8 *user, const int8 *password, const int8 *devid,
						uint16 ctime, uint1 clean_session, uint1 qos,
						const int8 *will_topic, const int8 *will_msg, int32 will_retain,
						mqtt_packet_structure *mqttpacket)
{
	
	uint8 flags = 0;
	uint8 will_topic_len = 0;
	uint16 total_len = 15;
	int16 len = 0, devid_len = strlen(devid);
	int16 user_len = strlen(user),password_len = strlen(password);
	
	if(!devid)
		return 1;
	
	total_len += devid_len + 2;
	
	//断线后,是否清理离线消息:1-清理	0-不清理--------------------------------------------
	if(clean_session)
	{
		flags |= mqtt_connect_clean_session;
	}
	
	//异常掉线情况下,服务器发布的topic------------------------------------------------------
	if(will_topic)
	{
		flags |= mqtt_connect_will_flag;
		will_topic_len = strlen(will_topic);
		total_len += 4 + will_topic_len + strlen(will_msg);
	}
	
	//qos级别--主要用于publish(发布态)消息的,保证消息传递的次数-----------------------------
	switch((unsigned char)qos)
	{
		case mqtt_qos_level0:
			flags |= mqtt_connect_will_qos0;							//最多一次
		break;
		
		case mqtt_qos_level1:
			flags |= (mqtt_connect_will_flag | mqtt_connect_will_qos1);	//最少一次
		break;
		
		case mqtt_qos_level2:
			flags |= (mqtt_connect_will_flag | mqtt_connect_will_qos2);	//只有一次
		break;
		
		default:
		return 2;
	}
	
	//主要用于publish(发布态)的消息,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它。如果不设那么推送至当前订阅的就释放了
	if(will_retain)
	{
		flags |= (mqtt_connect_will_flag | mqtt_connect_will_retain);
	}
	
	//账号为空 密码为空---------------------------------------------------------------------
	if(!user || !password)
	{
		return 3;
	}
	flags |= mqtt_connect_user_name | mqtt_connect_passord;
	
	total_len += strlen(user) + strlen(password) + 4;
	
	//分配内存-----------------------------------------------------------------------------
	mqtt_newbuffer(mqttpacket, total_len);
	if(mqttpacket->_data == null)
		return 4;
	
	memset(mqttpacket->_data, 0, total_len);
	
/*************************************固定头部***********************************************/
	
	//固定头部----------------------连接请求类型---------------------------------------------
	mqttpacket->_data[mqttpacket->_len++] = mqtt_pkt_connect << 4;
	
	//固定头部----------------------剩余长度值-----------------------------------------------
	len = mqtt_dumplength(total_len - 5, mqttpacket->_data + mqttpacket->_len);
	if(len < 0)
	{
		mqtt_deletebuffer(mqttpacket);
		return 5;
	}
	else
		mqttpacket->_len += len;
	
/*************************************可变头部***********************************************/
	
	//可变头部----------------------协议名长度 和 协议名--------------------------------------
	mqttpacket->_data[mqttpacket->_len++] = 0;
	mqttpacket->_data[mqttpacket->_len++] = 4;
	mqttpacket->_data[mqttpacket->_len++] = 'm';
	mqttpacket->_data[mqttpacket->_len++] = 'q';
	mqttpacket->_data[mqttpacket->_len++] = 't';
	mqttpacket->_data[mqttpacket->_len++] = 't';
	
	//可变头部----------------------protocol level 4-----------------------------------------
	mqttpacket->_data[mqttpacket->_len++] = 4;
	
	//可变头部----------------------连接标志(该函数开头处理的数据)-----------------------------
    mqttpacket->_data[mqttpacket->_len++] = flags;
	
	//可变头部----------------------保持连接的时间(秒)----------------------------------------
	mqttpacket->_data[mqttpacket->_len++] = mosq_msb(ctime);
	mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(ctime);
	 
/*************************************消息体************************************************/

	//消息体----------------------------devid长度、devid-------------------------------------
	mqttpacket->_data[mqttpacket->_len++] = mosq_msb(devid_len);
	mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(devid_len);
	
	strncat((int8 *)mqttpacket->_data + mqttpacket->_len, devid, devid_len);
	mqttpacket->_len += devid_len;
	
	
//	usartprintf(usart_debug,"111: %s\r\n", proid);
//	usartprintf(usart_debug,"mqttpacket._data content: %s\n", mqttpacket->_data);

	//消息体----------------------------will_flag 和 will_msg---------------------------------
	if(flags & mqtt_connect_will_flag)
	{
		unsigned short mlen = 0;
		
		if(!will_msg)
			will_msg = "";
		
		mlen = strlen(will_topic);
		mqttpacket->_data[mqttpacket->_len++] = mosq_msb(mlen);
		mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(mlen);
		strncat((int8 *)mqttpacket->_data + mqttpacket->_len, will_topic, mlen);
		mqttpacket->_len += mlen;
		
		mlen = strlen(will_msg);
		mqttpacket->_data[mqttpacket->_len++] = mosq_msb(mlen);
		mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(mlen);
		strncat((int8 *)mqttpacket->_data + mqttpacket->_len, will_msg, mlen);
		mqttpacket->_len += mlen;
	}
	
	//消息体----------------------------use---------------------------------------------------
	if(flags & mqtt_connect_user_name)
	{
		unsigned short user_len = strlen(user);
		
		mqttpacket->_data[mqttpacket->_len++] = mosq_msb(user_len);
		mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(user_len);
		strncat((int8 *)mqttpacket->_data + mqttpacket->_len, user, user_len);
		mqttpacket->_len += user_len;
	}

	//消息体----------------------------password----------------------------------------------
	if(flags & mqtt_connect_passord)
	{
		unsigned short psw_len = strlen(password);
		
		mqttpacket->_data[mqttpacket->_len++] = mosq_msb(psw_len);
		mqttpacket->_data[mqttpacket->_len++] = mosq_lsb(psw_len);
		strncat((int8 *)mqttpacket->_data + mqttpacket->_len, password, psw_len);
		mqttpacket->_len += psw_len;
	}
		
	return 0;

}

//==========================================================
//	函数名称:	mqtt_unpacketconnectack
//
//	函数功能:	连接消息解包
//
//	入口参数:	rev_data:接收的数据
//
//	返回参数:	1、255-失败		其他-平台的返回码
//
//	说明:		
//==========================================================
uint8 mqtt_unpacketconnectack(uint8 *rev_data)
{

	if(rev_data[1] != 2)
		return 1;
	
	if(rev_data[2] == 0 || rev_data[2] == 1)
		return rev_data[3];
	else
		return 255;

}

3. onenet.c

函数onenet_devlink用于与onenet平台建立连接;函数mqttonenet_savedata将温湿度数据转换为json数据形式;函数onenet_senddata用于上传数据到平台。该代码使用了mqtt协议进行通信。

#define proid		"xxxx"  //产品id

#define auth_info	"xxxxx"  //鉴权信息

#define devid		"xxxx"   //设备名称

extern unsigned char esp8266_buf[128];

//==========================================================
//	函数名称:	onenet_devlink
//
//	函数功能:	与onenet创建连接
//
//	入口参数:	无
//
//	返回参数:	1-成功	0-失败
//
//	说明:		与onenet平台建立连接
//==========================================================
_bool onenet_devlink(void)
{
	
	mqtt_packet_structure mqttpacket = {null, 0, 0, 0};					//协议包

	unsigned char *dataptr;
	
	_bool status = 1;
	
	usartprintf(usart_debug, "onenet_devlink\r\n"
							"proid: %s,	auif: %s,	devid:%s\r\n"
                        , proid, auth_info, devid);
	
	if(mqtt_packetconnect(proid, auth_info, devid, 256, 1, mqtt_qos_level0, null, null, 0, &mqttpacket) == 0)  //修改clean_session=1
	{
		
		esp8266_senddata(mqttpacket._data, mqttpacket._len);	//上传平台
		
		dataptr = esp8266_getipd(250);	//等待平台响应
		if(dataptr != null)
		{
			if(mqtt_unpacketrecv(dataptr) == mqtt_pkt_connack)
			{
				switch(mqtt_unpacketconnectack(dataptr))
				{
					case 0:usartprintf(usart_debug, "tips:	连接成功\r\n");status = 0;break;
					
					case 1:usartprintf(usart_debug, "warn:	连接失败:协议错误\r\n");break;
					case 2:usartprintf(usart_debug, "warn:	连接失败:非法的clientid\r\n");break;
					case 3:usartprintf(usart_debug, "warn:	连接失败:服务器失败\r\n");break;
					case 4:usartprintf(usart_debug, "warn:	连接失败:用户名或密码错误\r\n");break;
					case 5:usartprintf(usart_debug, "warn:	连接失败:非法链接(比如token非法)\r\n");break;
					
					default:usartprintf(usart_debug, "err:	连接失败:未知错误\r\n");break;
				}
			}
		}
		
		mqtt_deletebuffer(&mqttpacket);		//删包
	}
	else
		usartprintf(usart_debug, "warn:	mqtt_packetconnect failed\r\n");
	
	return status;
	
}


//访问onenet需要提交json数据,就获取到的温湿度转换为json数据形式
unsigned char mqttonenet_savedata(char *t_payload)
{
	
		extern u8 temperature;
		extern u8 humidity;
	
//		u8 temperature = 12;  //调试使用
//		u8 humidity = 12;
	
	  char json[]="{\"id\":\"0\",\"version\":\"1.0\",\"params\":{\"humidity_value\":{\"value\":%d},\"temp_value\":{\"value\":%d}}}";  //更换了json数据形式,符合onenet需求
    char t_json[200];
    unsigned short json_len;
	  sprintf(t_json, json, temperature, humidity);
    json_len = strlen(t_json)/sizeof(char);
  	memcpy(t_payload, t_json, json_len);
    return json_len;	
}

//==========================================================
//	函数名称:	onenet_senddata
//
//	函数功能:	上传数据到平台
//
//	入口参数:	type:发送数据的格式
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void onenet_senddata(void)
{
	
	mqtt_packet_structure mqttpacket = {null, 0, 0, 0};		//协议包
	
	char buf[128];
	short body_len = 0, i = 0;
	usartprintf(usart_debug, "tips:	onenet_senddata-mqtt\r\n");
	memset(buf, 0, sizeof(buf));    //清空buff
	body_len=mqttonenet_savedata(buf);	
	
	if(body_len)
	{
		
		if(mqtt_packetsavedata(devid, body_len, null, 5, &mqttpacket) == 0)							//封包
		{
			
			for(; i < body_len; i++)
				mqttpacket._data[mqttpacket._len++] = buf[i];
			
			esp8266_senddata(mqttpacket._data, mqttpacket._len);									//上传数据到平台
			usartprintf(usart_debug, "send %d bytes\r\n", mqttpacket._len);
			
			mqtt_deletebuffer(&mqttpacket);															//删包
		}
		else
		{
			usartprintf(usart_debug, "warn:	edp_newbuffer failed\r\n");
		}
	}
	
}

//==========================================================
//	函数名称:	onenet_revpro
//
//	函数功能:	平台返回数据检测
//
//	入口参数:	dataptr:平台返回的数据
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void onenet_revpro(unsigned char *cmd)
{
	
	mqtt_packet_structure mqttpacket = {null, 0, 0, 0};								//协议包
	
	char *req_payload = null;
	char *cmdid_topic = null;
	
	unsigned short req_len = 0;
	
	unsigned char type = 0;
	
	short result = 0;

	char *dataptr = null;
	char numbuf[10];
	int num = 0;
	
	type = mqtt_unpacketrecv(cmd);
	switch(type)
	{
		case mqtt_pkt_cmd:		//命令下发
			
			result = mqtt_unpacketcmd(cmd, &cmdid_topic, &req_payload, &req_len);	//解出topic和消息体
			if(result == 0)
			{
				usartprintf(usart_debug, "cmdid: %s, req: %s, req_len: %d\r\n", cmdid_topic, req_payload, req_len);
				
				if(mqtt_packetcmdresp(cmdid_topic, req_payload, &mqttpacket) == 0)	//命令回复组包
				{
					usartprintf(usart_debug, "tips:	send cmdresp\r\n");
					
					esp8266_senddata(mqttpacket._data, mqttpacket._len);			//回复命令
					mqtt_deletebuffer(&mqttpacket);			//删包
				}
			}
		
		break;
			
		case mqtt_pkt_puback:			//发送publish消息,平台回复的ack
		
			if(mqtt_unpacketpublishack(cmd) == 0)
				usartprintf(usart_debug, "tips:	mqtt publish send ok\r\n");
			
		break;
		
		default:
			result = -1;
		break;
	}
	
	esp8266_clear();									//清空缓存
	
	if(result == -1)
		return;
	
	dataptr = strchr(req_payload, '}');					//搜索'}'

	if(dataptr != null && result != -1)					//如果找到了
	{
		dataptr++;
		
		while(*dataptr >= '0' && *dataptr <= '9')		//判断是否是下发的命令控制数据
		{
			numbuf[num++] = *dataptr++;
		}
		
		num = atoi((const char *)numbuf);				//转为数值形式
	}

	if(type == mqtt_pkt_cmd || type == mqtt_pkt_publish)
	{
		mqtt_freebuffer(cmdid_topic);
		mqtt_freebuffer(req_payload);
	}

}

鉴权信息和获取方式参考:onenet - 中国移动物联网开放平台 (10086.cn)icon-default.png?t=n7t8https://open.iot.10086.cn/doc/v5/fuse/detail/1464

 4. main.c

        主要包括硬件初始化、接入onenet平台、读取温湿度、发送数据等功能。其中,timecount变量用于控制发送数据的时间间隔,dataptr变量用于存储esp8266模块接收到的数据。如果timecount计数达到50,则执行发送数据的操作,将温湿度数据上传至onenet平台并清空esp8266模块缓存。同时,使用esp8266_getipd函数获取esp8266模块接收到的数据,并使用onenet_revpro函数处理该数据。

int main(void)
 { 		    
	 
	unsigned short timecount = 0;	//发送间隔变量
	unsigned char *dataptr = null;	
	 
	delay_init();	    	 //延时函数初始化	  
	usart1_init(115200);	   //串口1初始化为115200
	usart2_init(115200);     //串口2初始化为115200
	led_init();		  		 //初始化与led连接的硬件接口
	 
	usartprintf(usart_debug, " hardware init ok\r\n");
	esp8266_init();	 
 
	while(onenet_devlink())			//接入onenet
	delay_ms(500);	

	while(1)
	{	    	    
		
		dht11_read_data(&temperature,&humidity);		//读取温湿度值
		delay_ms(100);
		
		
		if(++timecount >= 50)									//发送间隔5s
				{		
					usartprintf(usart_debug, "温度:%d\r\n",temperature);
					usartprintf(usart_debug, "湿度:%d\r\n",humidity);
					usartprintf(usart_debug, "onenet_senddata\r\n");
//					data_len=mqttonenet_savedata(send_jason,temperature, humidity);
					onenet_senddata();									//发送数据
					
					timecount = 0;
					esp8266_clear();
				}				
			  dataptr = esp8266_getipd(0);
			  if(dataptr != null)
				onenet_revpro(dataptr);

	}
}

三、上报效果

 不知为何,源码始终上传不成功,需要源码请在评论区留言。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com