本文详细介绍了,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)
https://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);
}
}
三、上报效果

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