我们不管使用哪种协议, 哪种解决方案, 我们就目前的情况来看, 我们刚开始是使用 手动修改temp_th和 humi_th的方式, 来实现温湿度阈值的控制.但是对于投入到实际使用的话, 我们还需要使用更方便的联网控制, 所以我们首先利用Onenet的解决方案.
我们其实构建也是按照就班, 能构建出来一个工程, 但是构建完后, 有些代码就是固定的, 所以, 我们只需要知道,再次新建一个工程后, 我们修改哪里, 大致流程是哪些, 我们能够在原有的基础上, 复制黏贴即可.
详细的联网构建步骤(这里是跳转详细的从零构建,我们这里是在原有基础上改):
https://blog.csdn.net/qq_57484399/article/details/140651413
构建完成的最小温湿度阈值工程(建议直接使用可用工程,然后看步骤后,会改就行):
https://ww0.lanzoul.com/ixRys26qkmhe
本博客构建完成的温湿度阈值工程:
https://ww0.lanzoul.com/iNSJp26rom7e
(1)我们在原有联网工程上, 构建Onenet联网工程, 首先下载 构建好的基本例程, 解压
https://ww0.lanzoul.com/imskP25ct2de
(2)在这个目录下, 拿到这个构建好的最小联网例程
(3)双击这个,打开工程,
(4)联网使用的是 ESP8266-01S , 对应的 RX 连 PA2, TX连 PA3 , 对应的gnd连gnd, 3.3v连gnd。
(5)我们现在只讨论联网修改温湿度阈值, 并上传服务器, 还有服务器下发阈值信息, 单片机本地修改阈值.
(6) 大概流程就是, 初始化ESP8266-01s, 配置wifi热点 ,然后链接Onenet服务器, 上传温湿度和温湿度阈值.
下发信息的大概流程就是, 服务器下发阈值, 单片机检测到后, 使用cjson拆包, 然后得到服务器下发的阈值.
(7) 还是那句话, 我们只谈如何复制黏贴, 如何在最小例程上, 进行可行性使用.
(8)我们要把变量上传, 就首先需要在Onenet服务器上创建产品
跳转:
配置链接:https://blog.csdn.net/qq_57484399/article/details/140962964
(9)我们单片机配置wifi, 就要把变量去对标 服务器的功能标识符
<1>先编译一下最小联网示例, 方便跳转
<2> 然后我们先调整一下, 服务器的 key值, 方便和服务器对接
点击左侧的onenet.c
<3>分别进行对标
把这个标识符, 赋值给下图所示位置
<4> 这样服务器的key就配置好了, 我们是通过wifi链接的,wifi密码在esp8266.c里面
(10)我们现在和服务器对接已经完成了, 下面直接去配置Onenet的标识符变量: 在main函数里的while, OneNet_SenData();这个就是发送函数, 我们按下f12, 跳转
(11)往下翻, 接着f12
(12)就看到了,这里标识符, 我们接着对应修改, 注意事项
<1>引入上传变量
<2>严格按照下面格式进行填写:
<3>强调: 最后一项,后面没逗号, 之前都有逗号
<4>我们可以复制三行代码, 然后改动
memset(text, 0, sizeof(text));
sprintf(text, "\"temp_th\":{\"value\":%d},", temp_th);
strcat(buf, text);
<5>注意这里, 我们这里要看注意事项, 这里是有逗号的, 所以我们不能放在最后一项, 我们修改对应的标识符就行了
下面是我们修改好的
memset(text, 0, sizeof(text));
sprintf(text, "\"temp_th\":{\"value\":%d},", temp_th);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"humi_th\":{\"value\":%d}", humi_th);
strcat(buf, text);
<6>注意, 因为这个是onenet.c文件,所以我们要引入全局变量
extern int temp_th;
extern int humi_th;
此函数代码摘录:
extern int temp_th;
extern int humi_th;
unsigned char OneNet_FillBuf(char *buf)
{
char text[48];
memset(text, 0, sizeof(text));
strcpy(buf, "{\"id\":\"123\",\"params\":{");
memset(text, 0, sizeof(text));
sprintf(text, "\"temp_th\":{\"value\":%d},", temp_th);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"humi_th\":{\"value\":%d}", humi_th);
strcat(buf, text);
strcat(buf, "}}");
return strlen(buf);
}
<7> 那我们上传温湿度阈值的操作就完成了
(13)下面我们操作下发改变阈值, 跟我走
① 先编译运行一下工程, 方便我们跳转
② 然后我们跳转
③ 这里就是cjson处理函数, 我们接受到服务器发来的数据,我们通过拆包, 就可以获得具体数值, 然后我们赋值给我们本地变量就可以了.
<1>下面是固定化套路, 复制黏贴即可, 找到规律,实现功能.
定义拆包的变量, 一个是temp_h, 一个是 humi_th
//这里定义 cjson格式的变量名,例如 *led_jason cJSON *temp_th_jason, *humi_th_jason;
<2> 拆包, 通过标识符, 锁定数值
<3>判断拆包是否为空 , 然后赋值本地变量
if(temp_th_jason != NULL)
{
temp_th = temp_th_jason->valueint;
}
if(humi_th_jason != NULL)
{
humi_th = humi_th_jason->valueint;
}
修改完成的函数摘录:
//==========================================================
// 函数名称: OneNet_RevPro
//
// 函数功能: 平台返回数据检测
//
// 入口参数: dataPtr:平台返回的数据
//
// 返回参数: 无
//
// 说明:
//==========================================================
void OneNet_RevPro(unsigned char *cmd)
{
char *req_payload = NULL;
char *cmdid_topic = NULL;
unsigned short topic_len = 0;
unsigned short req_len = 0;
unsigned char qos = 0;
static unsigned short pkt_id = 0;
unsigned char type = 0;
short result = 0;
//原始数据 -> cjson数据
cJSON *raw_jason;
// cjson中摘出标识符变量
cJSON *params_jason;
//这里定义 cjson格式的变量名,例如 *led_jason
cJSON *temp_th_jason, *humi_th_jason;
type = MQTT_UnPacketRecv(cmd);
//UsartPrintf(USART_DEBUG, "688\r\n");
switch(type)
{
case MQTT_PKT_PUBLISH: //接收的Publish消息
// UsartPrintf(USART_DEBUG, "689\r\n");
result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
if(result == 0)
{
UsartPrintf(USART_DEBUG, "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",
cmdid_topic, topic_len, req_payload, req_len);
//将原始字符串信息,转化成cjson格式
raw_jason = cJSON_Parse(req_payload);//解析原始字符串数据到raw_jason
//从raw_jason中提取params字符段到params_jason
params_jason = cJSON_GetObjectItem(raw_jason,"params");
//然后再从params_jason中提取要操作的器件,
temp_th_jason = cJSON_GetObjectItem(params_jason,"temp_th");
humi_jason = cJSON_GetObjectItem(params_jason,"humi_th");
//判断对应cjson 标识符变量 是否为空, 不空,则代表有对应的下发信息
if(temp_th_jason != NULL)
{
temp_th = temp_th_jason->valueint;
}
if(humi_th_jason != NULL)
{
humi_th = humi_th_jason->valueint;
}
cJSON_Delete(raw_jason);
}
case MQTT_PKT_PUBACK: //发送Publish消息,平台回复的Ack
// UsartPrintf(USART_DEBUG, "111\r\n");
if(MQTT_UnPacketPublishAck(cmd) == 0)
// UsartPrintf(USART_DEBUG, "Tips: MQTT Publish Send OK\r\n");
break;
case MQTT_PKT_SUBACK: //发送Subscribe消息的Ack
// UsartPrintf(USART_DEBUG, "222\r\n");
if(MQTT_UnPacketSubscribe(cmd) == 0)
UsartPrintf(USART_DEBUG, "Tips: MQTT Subscribe OK\r\n");
else
UsartPrintf(USART_DEBUG, "Tips: MQTT Subscribe Err\r\n");
break;
default:
// UsartPrintf(USART_DEBUG, "333\r\n");
result = -1;
break;
}
ESP8266_Clear(); //清空缓存
if(result == -1)
return;
if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH)
{
MQTT_FreeBuffer(cmdid_topic);
MQTT_FreeBuffer(req_payload);
}
}
至此, 我们上传下发阈值信息的工程就完成了, 我们把温湿度阈值设置成全局变量, 然后我们通过调用此文件, 就可以访问全局变量, 然后修改了。
我们其余工程, 全在此工程上构建, 即可。对于详细的工程构建完成, 把之前的最小例程加上, 然后调试就可以了, 后面专一出一讲,讲解如何快速 移植联网工程和测试。