:::warning 基于涂鸦NB-IoT模组的植物监测仪 :::
一、我们要做什么?
本项目作为我们在智慧农业中的第一个探索性项目,项目的出发点很简单,即监测环境并且采集数据,这两者是农业数字化的起点。通过监测农业环境的状态,我们能够了解植物的生长状态,以及对异常情况作出及时的处理等;通过持续的数据采集和大量的数据分析,我们能够优化种植的策略,从而提高农产品的质量和产量。
基于这个目的,我们将会采集农业环境中的环境温湿度、光照度、土壤湿度、土壤酸碱度和土壤氮磷钾含量这几个最重要的参数,并且发送到云端服务器,云端服务器一方面记录这些数据以供后续的数据分析;另一方面发送到手机App,当这些参数出现异常状况时,手机App给用户推送提醒。
二、系统演示与架构设计
1.总体设计
本技术方案的架构设计如下图所示。
本技术方案主要由边缘计算终端、IoT云平台以、手机App和Web管理后台这几部分组成。
2..边缘计算终端
(1)边缘计算终端内置STM32嵌入式微处理器,具备一定的边缘计算能力,边缘计算终端的原型开发板如图所示。
为了方便前期快速开发和适应需求变化,本系统选用了现成的原型开发板进行开发,其中内置了诸如转串口芯片、拨码开关和排针等辅助器件,后期在成品产品电路中去除这些辅助器件即可,软件代码无需修改
(2)边缘计算终端搭载环境温湿度传感器、光照强度传感器(光敏电阻模块)、土壤湿度传感器、土壤PH值传感器和土壤氮磷钾传感器,能够全方位感知植物的生长环境状态。这些传感器支持可插拔,即可以随意安装自己所需的传感器,而不会影响系统正常工作。
(3)在产品规划阶段中,我们设计了两种供电方式组合,即A.内置锂电池+USB线二合一供电;B.内置锂电池+太阳能供电,如图所示。
然而,我们采取的策略是在确定硬件器件选型后,软件开发先行,然后硬件设计、外观设计跟上。基于现有的原型开发板以及确定相关元器件的成本后,这种策略是可行的。因此,在基于原型开发板阶段,暂时只需要支持Micro USB线缆+外置电池供电即可,在后续可在硬件层面支持上述的A版本或B版本的供电方式。
(4)边缘计算终端支持监测电池电量状态。
(5)边缘计算终端内置涂鸦智能NB-IoT模组,支持把各个传感器信息、电池电量信息以及主板本身的状态信息通过NB-IoT网络上传到涂鸦智能IoT云平台。
4.手机App
(1)手机App支持查看由边缘计算终端发送过来的实时数据,以环境温湿度数据为例,如图所示。
实时环境温湿度
(2)移动端App支持针对环境温湿度、环境光照强度、土壤湿度、土壤PH值、土壤碳磷钾含量设置上限和下限阈值,当实际值高于上限阈值或低于下限阈值的时候,能够发出警报信息。以温度的设置为例,如下演示视频所示。
设备间智能联合控制
5.云平台
(1)IoT平台支持接收来自边缘计算终端的数据并且保存下来,支持在手机App查看这些数据,支持在基于涂鸦智能的Web管理后台中各种数据行进管理。
历史温湿度数据查看
涂鸦智能Web管理后台
三、终端的主要硬件组成
- 主芯片:STM32F030F4P6
- NB-IoT模组:涂鸦智能 NE1 https://developer.tuya.com/cn/docs/iot/ne1-module-datasheet?id=K9t001ddkmio2
- NB-IoT移动网络卡:中国移动NB-IoT卡
- 网络天线:善学坊NB-IoT超级天线 CrossAir L01
- 环境温湿度传感器:http://aosong.com/products-104.html
- 光敏电阻模块:https://zhuanlan.zhihu.com/p/483620112
- 土壤湿度传感器:https://zhuanlan.zhihu.com/p/483599993
- 土壤PH值传感器:https://www.kancloud.cn/aiot/solution/2628607
土壤碳磷钾传感器:https://www.kancloud.cn/aiot/solution/2677011
四.主要技术参数
1.主控芯片技术参数
STM32F030采用ARM Cortex内核,运算速度高达48 MHz。另外,STM32F030具有全套外设,例如高速12位ADC、先进且灵活的定时器、日历RTC和通信接口。该组合轻松超越了现有的8位架构,让所有应用设计者均能得益于先进32位内核的简单性和高效率。STM32F030超值系列提供多种存储容量和引脚数组合,能与之匹敌的器件少之又少,从而进一步优化项目成本。
2.NB-IoT模组技术参数
NE1 是由涂鸦智能开发的一款低功耗嵌入式 NB-IoT 系列 LPWA 模组。支持 NB-IoT 无线电通信协议(3GPP Rel.14)。它由一个高集成度的 Soc EC616(内置了应用处理器、低功耗多波段窄带物联网收发器和电源管理单元PMU)和少量外围器件构成。NE1 内嵌低功耗 32 位Cortex-M3 CPU,支持 MPU,集成 272KB 晶圆内SRAM,4MB NOR Flash,还支持包括 UART、I2C、SPI、PWM、4 通道 12-bit AUXADC、32KHz RTC timer和 USIM 等接口。
特点内置低功耗32位 Cortex-M3 处理器
- 供电
- 工作电压范围:2.2~4.5V
- 典型工作电压:3.3V
- 外设:17×GPIOs,3×UARTs, 6×PWMs,1×ADC,1×SPI,1×I2C
- SIM: 3V/1.8V SIM card
- NB-IoT 网络
- Cat NB1/Cat NB2
- 3GPP R14 NB-IoT 标准
- B3/B5/B8
- 最大发射功率 23dBm±2dB
- 接收灵敏度 <-127.3dBm/15kHz(非重传)
- 50Ω 特征阻抗,天线需第三方提供
- 数据速率:
- R13:
- Single-tone:25.5kbps(下行),16.7kbps(上行)
- Multi-tone:25.5kbps(下行),62.5kbps(上行)
- R14:
- Multi-tone:102kbps(下行),157kbps(上行)
- R13:
- 网络协议特性:UDP/TCP/CoAP/LWM2M/ PPP/SSL/DTLS/FTP/ HTTP/MQTT/HTTPS*
- 正常工作温度:-35°C ~ +75°C
- 扩展工作温度:-40°C ~ +85°C
- 存储温度:-40°C ~+90°C
- 升级通过主串口,FOTA
3.中国移动NB-IoT卡类型
类型为cmnbiot,这是中国移动推出的支持终端控制PSM和eDRX的NB-IoT卡类型,详细介绍可参考https://ec.iot.10086.cn/onelink/pages/nbiot.html
3.NB-IoT超级天线 CrossAir L01
CrossAir L01是一款SMT自动焊接的微型天线,详细参数如图所示。
五、系统选型优势
1.NB-IoT模组对比
本方案中默认选取了涂鸦智能NE1模组,我们拿国内的另外的NB-IoT模组来对比一下。
价格对比
对于大多数的企业来说,元器件的价格是一个重要的参考因素,涂鸦智能NE1模组的价格仅为14元(含3元的云平台使用授权费),如图所示。(价格查询时间为2022年3月15日)
涂鸦智能NE1模组价格
而国内的其他模组零售价如图所示。据我们过往采购的经验来看,采购量在1000片以内时,价格比零售价便宜约1~3元,可见涂鸦智能的NE1几乎是全网最便宜的!(价格查询时间为2022年3月15日,查询链接:点击自动跳转淘宝搜索)
资源对比
涂鸦智能NE1模组的资源上文已经罗列过,此处我们给出在淘宝销量第1的模组的资源说明,如图所示。(图片来自其官网)
可见双方的资源和技术参数有一定差异,但是均能满足本技术方案的需求。
稳定性对比
稳定性是很重要的参考指标,但作为模块的用户,我们非常难去测试,因此大部分的情况下,我们只能从模块厂商的知名度、模块本身的出货量等方面去简介评估模块的稳定性。
从厂商的知名度来看,据涂鸦智能官网介绍,它是“全球IoT云平台上市第1股”(参考链接:https://www.tuya.com/cn/?_source=d441cd2712521cfcb4c151e9e58d4c8b),知名度可见一斑。
2.IoT云平台对比
涂鸦智能NE1模组能够直连涂鸦智能云平台,而其他模组一般需要对接第三方云平台。我们把涂鸦智能云平台与第3方云平台做一个简单的对比,见表。
项目 | 涂鸦智能云平台 | 主流第3方云平台 |
---|---|---|
资费 | 无(使用模组即可连接云平台) | 按通信数据量、连接时长或设备数量收费 |
通信模组提供方 | 自营 | 第3方 |
终端设备开发 | 0代码,支持自定义开发 | 支持二次开发 |
手机App端开发 | 0代码,支持二次开发 | 支持二次开发 |
微信小程序端开发 | 提供SDK供二次开发 | 支持二次开发 |
云平台端开发 | 0代码,支持云云对接 | 支持二次开发 |
总的来说,如果涂鸦智能的标准设备模型如果满足功能需要,那么从终端设备、手机App、云平台端的开发量将会非常少,非常适用于希望减少开发工作量和加快产品上市时间的团队。
六、云平台与手机App的实现
登录涂鸦智能官网https://www.tuya.com/,然后点击“登录IoT平台”,如图所示。
输入账号密码,如图所示。
选择产品,如图所示。
点击创建产品,如图所示。
依次选择传感、植物监测仪,如图所示。
选择产品开发,如图所示。
选择自定义方案,如图所示。
输入名称,并且选择NB-IoT、DRX,然后点击创建产品,如图所示。
选择红框中的功能点,然后点击确定,如图所示。
点击下一步设备交互,如图所示。
选择默认的Studio面板,如图所示。
点击下一步硬件开发,如图所示。
选择NE1模组,如图所示。
点击下一步产品配置,如图所示。
点击下一步测试服务,如图所示。
至此,云平台和App端的配置已经初步完成,读者可以初步测试一下App端的效果。点击设备交互,并且使用”智能生活“App扫描页面中的二维码,即可体验,如图所示。
七、设备终端的实现
7.1 涂鸦智能MCU SDK下载
点击硬件开发,如图所示。
下翻到页面底部,然后下载功能点调试文件、快速入门指南、MCU SDK等资料,如图所示。
解压其中的MCU SDK文件,得到如下内容。
把这个SDK添加进自有的工程中,这里以STM32F030F4P6 + Keil MDK工程为例,如图所示。
7.2 终端代码架构设计
7.2.1 MVC 架构简介
经典的MVC是一种常用的代码架构设计思想,其中M表示Model(模型),V表示View(视图),C表示控制器(Controller),相关含义如下:
- Model(模型):封装了数据和对数据的操作,是实际进行数据处理的地方
- View(视图):负责程序和用户之间的交互,例如负责把数据在在屏幕上显示出来
- Controller(控制器):用于操作模型和视图
7.2.2 SDK 设计模式
SDK可以分解成3个层次,自定向下分别是:
- HAL: HAL(Hardware Abstraction Layer,硬件抽象层),前面课程已经一步一步地带读者实现了部分HAL API。
- Service:服务组件,对HAL进行服务化抽象和管理。HAL的重点是操作和管理某一个硬件,例如串口和显示器等。然而,Service的重点是为上层提供服务,例如Log组件为上层提供日志打印服务,这个组件既能通过串口写入日志数据,又能通过显示器上显示日志;又例如Sender组件为上层提供NB-IoT数据发送服务,上层无需理会使用哪个型号的NB-IoT模组去发送的,因此这个组件会自行去处理这些细节。
- Task:是指某种更贴合用户需求的任务,例如定时地获取传感器的数值,并上报给指定的服务器。
7.2.3 终端代码详解
代码下载链接:https://pan.baidu.com/s/1uw5YxxaHSd8IqVTRMqTvkw 密码:d8io
完整的结构如图所示。
其中较为重要的的分别是HalPort、Users和Tuya。HalPort负责硬件驱动与抽象,Users负责处理终端的业务逻辑,而Tuya中存放的是Tuya MCU SDK。
其中的Tuya MCU SDK,我们主要需要修改的是protocol.c文件,修改后的代码如下:
/****************************************Copyright (c)*************************
** 版权所有 (C), 2015-2020, 涂鸦科技
**
** http://www.tuya.com
**
**--------------文件信息-------------------------------------------------------
**文 件 名: protocol.c
**描 述: 下发/上报数据处理函数
**使 用 说 明 :
*******非常重要,一定要看哦!!!********
** 1、用户在此文件中实现数据下发/上报功能
** 2、DP的ID/TYPE及数据处理函数都需要用户按照实际定义实现
** 3、当开始某些宏定义后需要用户实现代码的函数内部有#err提示,完成函数后请删除该#err
**-----------------------------------------------------------------------------
******************************************************************************/
#include "nbiot.h"
/******************************************************************************
移植须知:
1:MCU必须在while中直接调用mcu_api.c内的nbiot_uart_service()函数
2:程序正常初始化完成后,建议不进行关串口中断,如必须关中断,关中断时间必须短,关中断会引起串口数据包丢失
3:请勿在中断/定时器中断内调用上报函数
******************************************************************************/
/******************************************************************************
第一步:初始化
1:在需要使用到nbiot相关文件的文件中include "nbiot.h"
2:在MCU初始化中调用mcu_api.c文件中的nbiot_protocol_init()函数
3:将MCU串口单字节发送函数填入protocol.c文件中uart_transmit_output函数内,并删除#error
4:在MCU串口接收函数中调用mcu_api.c文件内的uart_receive_input函数,并将接收到的字节作为参数传入
5:单片机进入while循环后调用mcu_api.c文件内的nbiot_uart_service()函数
******************************************************************************/
/******************************************************************************
1:dp数据点序列类型对照表
**此为自动生成代码,如在开发平台有相关修改请重新下载MCU_SDK**
******************************************************************************/
const DOWNLOAD_CMD_S download_cmd[] =
{
{DPID_SOIL_HUMIDITY, DP_TYPE_VALUE},
{DPID_SOIL_PH, DP_TYPE_VALUE},
{DPID_AIR_HUMIDITY, DP_TYPE_VALUE},
{DPID_AIR_TEMP, DP_TYPE_VALUE},
{DPID_RAIN_INTENSITY, DP_TYPE_VALUE},
{DPID_SUN_INTENSITY, DP_TYPE_VALUE},
{DPID_LIQUID_TEMP, DP_TYPE_VALUE},
{DPID_LIQUID_TURBIDITY, DP_TYPE_VALUE},
};
/******************************************************************************
2:串口单字节发送函数
请将MCU串口发送函数填入该函数内,并将接收到的数据作为参数传入串口发送函数
******************************************************************************/
/*****************************************************************************
函数名称 : uart_transmit_output
功能描述 : 发数据处理
输入参数 : value:串口收到字节数据
返回参数 : 无
使用说明 : 请将MCU串口发送函数填入该函数内,并将接收到的数据作为参数传入串口发送函数
*****************************************************************************/
void uart_transmit_output(unsigned char value)
{
halUartWrite(&value, 1);
// #error "请将MCU串口发送函数填入该函数,并删除该行"
/*
//示例:
extern void Uart_PutChar(unsigned char value);
Uart_PutChar(value); //串口发送函数
*/
}
/******************************************************************************
第二步:实现具体用户函数
1:APP下发数据处理
2:数据上报处理
******************************************************************************/
/******************************************************************************
1:所有数据上报处理
当前函数处理全部数据上报(包括可下发/可上报和只上报)
需要用户按照实际情况实现:
1:需要实现可下发/可上报数据点上报
2:需要实现只上报数据点上报
此函数为MCU内部必须调用
用户也可调用此函数实现全部数据上报
******************************************************************************/
//自动化生成数据上报函数
/*****************************************************************************
函数名称 : all_data_update
功能描述 : 系统所有dp点信息上传,实现APP和muc数据同步
输入参数 : 无
返回参数 : 无
使用说明 : 此函数SDK内部需调用;
MCU必须实现该函数内数据上报功能;包括只上报和可上报可下发型数据
*****************************************************************************/
void all_data_update(void)
{
// #error "请在此处理可下发可上报数据及只上报数据示例,处理完成后删除该行"
if(DHT20_Alive())// 如果DHT20传感器存在,则读取温湿度数据
{
DHT20_ReadHT();//读取AHT20的 20Bit原始数据
StandardUnitCon();//实际标准单位转换
mcu_dp_value_update(DPID_AIR_HUMIDITY,(unsigned long)DHT20_Humi()); //VALUE型数据上报;
mcu_dp_value_update(DPID_AIR_TEMP,(unsigned long)DHT20_Temp()); //VALUE型数据上报;
}
//此代码为平台自动生成,请按照实际数据修改每个可下发可上报函数和只上报函数
mcu_dp_value_update(DPID_SOIL_HUMIDITY,get_Soil()); //VALUE型数据上报;
mcu_dp_value_update(DPID_SOIL_PH,get_PH());
mcu_dp_value_update(DPID_RAIN_INTENSITY,get_Rain());
mcu_dp_value_update(DPID_SUN_INTENSITY,get_Sun()); //VALUE型数据上报;
mcu_dp_value_update(DPID_LIQUID_TURBIDITY,get_Turbidity()); //VALUE型数据上报;
mcu_dp_value_update(DPID_LIQUID_TEMP,halDS18B20GetTemp()); //VALUE型数据上报;
}
/*****************************************************************************
函数名称 : dp_record_combine_update
功能描述 : 记录型数据组合上报
输入参数 : time : 时间数据长度7,首字节表示是否传输标志位,其余依次为年、月、日、时、分、秒
dp_bool : bool型dpid号, v_bool:对应值
dp_enum : enum型dpid号, v_enum:对应值
dp_value : value型dpid号, v_value:对应值
dp_string: string型dpid号, v_string:对应值,len:string长度
返回参数 : 无
*****************************************************************************/
unsigned char dp_record_combine_update(unsigned char time[],
unsigned char dp_bool,unsigned char v_bool,
unsigned char dp_enum,unsigned char v_enum,
unsigned char dp_value,unsigned char v_value,
unsigned char dp_string,unsigned char v_string[],unsigned char len)
{
unsigned short length = 0;
if(stop_update_flag == ENABLE)
return SUCCESS;
//local_time
length = set_nbiot_uart_buffer(length,(unsigned char *)time,7);
//bool
length = set_nbiot_uart_byte(length,dp_bool);
length = set_nbiot_uart_byte(length,DP_TYPE_BOOL);
length = set_nbiot_uart_byte(length,0);
length = set_nbiot_uart_byte(length,1);
if(v_bool == FALSE)
{
length = set_nbiot_uart_byte(length,FALSE);
}
else
{
length = set_nbiot_uart_byte(length,1);
}
//enum
length = set_nbiot_uart_byte(length,dp_enum);
length = set_nbiot_uart_byte(length,DP_TYPE_ENUM);
length = set_nbiot_uart_byte(length,0);
length = set_nbiot_uart_byte(length,1);
length = set_nbiot_uart_byte(length,v_enum);
//value
length = set_nbiot_uart_byte(length,dp_value);
length = set_nbiot_uart_byte(length,DP_TYPE_VALUE);
length = set_nbiot_uart_byte(length,0);
length = set_nbiot_uart_byte(length,4);
length = set_nbiot_uart_byte(length,v_value >> 24);
length = set_nbiot_uart_byte(length,v_value >> 16);
length = set_nbiot_uart_byte(length,v_value >> 8);
length = set_nbiot_uart_byte(length,v_value & 0xff);
//string
length = set_nbiot_uart_byte(length,dp_string);
length = set_nbiot_uart_byte(length,DP_TYPE_STRING);
length = set_nbiot_uart_byte(length,len / 0x100);
length = set_nbiot_uart_byte(length,len % 0x100);
length = set_nbiot_uart_buffer(length,(unsigned char *)v_string,len);
nbiot_uart_write_frame(STATE_RC_UPLOAD_CMD,length);
return SUCCESS;
}
/******************************************************************************
WARNING!!!
2:所有数据上报处理
自动化代码模板函数,具体请用户自行实现数据处理
******************************************************************************/
/******************************************************************************
WARNING!!!
此代码为SDK内部调用,请按照实际dp数据实现函数内部数据
******************************************************************************/
#ifdef SUPPORT_MCU_RTC_CHECK
/*****************************************************************************
函数名称 : mcu_write_rtctime
功能描述 : MCU校对本地RTC时钟
输入参数 : 无
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void mcu_write_rtctime(unsigned char time[])
{
#error "请自行完成RTC时钟写入代码,并删除该行"
/*
time[0]为是否获取时间成功标志,为 0 表示失败,为 1表示成功
time[1] 为 年 份 , 0x00 表 示2000 年
time[2]为月份,从 1 开始到12 结束
time[3]为日期,从 1 开始到31 结束
time[4]为时钟,从 0 开始到23 结束
time[5]为分钟,从 0 开始到59 结束
time[6]为秒钟,从 0 开始到59 结束
time[7]为星期,从 1 开始到 7 结束,1代表星期一
*/
if(time[0] == 1)
{
//正确接收到模块返回的本地时钟数据
}
else
{
//获取本地时钟数据出错,有可能是当前模块未联网
}
}
#endif
/*****************************************************************************
函数名称 : nbiot_update_handle
功能描述 : MCU请求mcu固件升级返回函数
输入参数 : status:校验标志
返回参数 : 无
使用说明 : MCU主动调用 nbiot_update_request 函数完成后该函数内可获取升级当前状态
*****************************************************************************/
void nbiot_update_handle(unsigned char status)
{
// #error "请自行完成模块升级状态返回代码,并删除该行"
switch (status)
{
case 0:
{
//开始检查固件更新
break;
}
case 1:
{
//已经是最新固件
break;
}
case 2:
{
//正在更新固件
break;
}
case 3:
{
//固件更新成功
break;
}
case 4:
{
//固件更新失败
break;
}
default:
break;
}
}
#ifdef SUPPORT_MCU_FIRM_UPDATE
/*****************************************************************************
函数名称 : mcu_firm_update_handle
功能描述 : MCU进入固件升级模式
输入参数 : value:固件缓冲区
position:当前数据包在于固件位置
length:当前固件包长度(固件包长度为0时,表示固件包发送完成)
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
// #error "请自行完成MCU固件升级代码,完成后请删除该行"
if(length == 0)
{
//固件数据发送完成
//#error "请完成crc32校验,结果返回0或者1,完成后请删除该行"
//mcu_firm_update_data_ack(1, 0); //请根据crc32校验情况,去回复crc成功或者失败
}
else
{
//mcu_firm_update_data_ack(0, 0);
//固件数据处理
}
return SUCCESS;
}
/*****************************************************************************
函数名称 : mcu_file_update_handle
功能描述 : MCU文件下载数据处理
输入参数 : value:固件缓冲区
position:当前数据包在于固件位置
length:当前固件包长度(固件包长度为0时,表示固件包发送完成)
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
unsigned char mcu_file_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
//#error "请自行完成MCU文件下载数据处理,完成后请删除该行"
if(length == 0)
{
//文件数据接收完成
// #error "请完成crc32校验,crc32_result结果返回0或者1,完成后请删除该行"
//mcu_file_data_ack(1, 0); //请根据crc32校验情况,去回复crc成功或者失败
}
else
{
//mcu_file_data_ack(0, 0);
//固件数据处理
}
return SUCCESS;
}
#endif
#ifdef SUPPORT_NBIOT_DONGLE_SERVICE
/*****************************************************************************
函数名称 : get_nb_active_info_response
功能描述 : 复合产品下 NB返回的激活所需的设备信息
输入参数 : NB返回的激活信息
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void get_nb_active_info_response(unsigned char nb_active_info[], unsigned short active_info_len)
{
//nb_active_info[0]为是否获取激活信息成功标志,为 0 表示失败,为 1表示成功
//nb_active_info[1] - nb_active_info[active_info_len-1] 为数据内容
//{"pv":"2.0","bv":"3.0","sv":"1.0.0","i":"860102040125729","opt":0,"h":28800}
if(nb_active_info[0] == 1)
{
//返回激活信息成功 后续可进行NB的激活 并调用mcu_set_nb_active_response 回复给NB
}
else
{
//返回激活信息成失败
}
}
/*****************************************************************************
函数名称 : get_mcu_active_response
功能描述 : 复合产品下 NB返回的 为MCU激活的结果
输入参数 : NB返回的激活信息
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void get_mcu_active_response(unsigned char mcu_active_ack[], unsigned short active_ack_len)
{
//mcu_active_info[0]为是否获取激活信息成功标志,为 0 表示失败,为 1表示成功
//mcu_active_info[1] - mcu_active_info[active_info_len-1] 为数据内容
//例如:{"localkey":"12345678"}
if(mcu_active_ack[0] == 1)
{
//获取MCU激活信息成功
}
else
{
//获取MCU激活信息失败
}
}
#endif
/******************************************************************************
WARNING!!!
以下函数用户请勿修改!!
******************************************************************************/
/*****************************************************************************
函数名称 : dp_download_handle
功能描述 : dp下发处理函数
输入参数 : dpid:DP序号
value:dp数据缓冲区地址
length:dp数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERRO
使用说明 : 该函数用户不能修改
*****************************************************************************/
unsigned char dp_download_handle(unsigned char dpid,const unsigned char value[], unsigned short length)
{
/*********************************
当前函数处理可下发/可上报数据调用
具体函数内需要实现下发数据处理
完成用需要将处理结果反馈至APP端,否则APP会认为下发失败
***********************************/
unsigned char ret;
switch(dpid)
{
default:
break;
}
return ret;
}
/*****************************************************************************
函数名称 : get_download_cmd_total
功能描述 : 获取所有dp命令总和
输入参数 : 无
返回参数 : 下发命令总和
使用说明 : 该函数用户不能修改
*****************************************************************************/
unsigned char get_download_cmd_total(void)
{
return(sizeof(download_cmd) / sizeof(download_cmd[0]));
}
补充一句
如果你也想尝试使用涂鸦云平台开发物联网项目,可联系他们的工作人员进行咨询,工作人员个人号:qtbb121