更新时间:2024-11-20 08:51:12下载pdf
智能设备的基础功能通常包括网络连接、设备控制、设备状态上报、OTA 等。此外,还会涉及到生产相关的烧录授权、产测等功能。本文讲解如何使用涂鸦 SDK 调用相关接口函数实现相应功能,您可以参考此文档使用 SDK 进行产品功能开发。
涂鸦 SDK 完整的运行的流程图如下,实现此流程中的每个环节后,即可完成一个 IoT 硬件产品的功能开发。
系统初始化之前,将系统运行可能会用到的一些参数或功能进行配置。
如下是一段预初始化应用示例代码,完成了日志的输出等级的设置,便于在系统启动后,查看系统运行的信息,确认系统运行情况。
VOID pre_device_init(VOID)
{
PR_DEBUG("%s",tuya_iot_get_sdk_info()); //查看SDK版本
PR_DEBUG("%s:%s",APP_BIN_NAME,DEV_SW_VERSION); //查看SDK名称及固件版本
PR_NOTICE("firmware compiled at %s %s",__DATE__,__TIME__);//查看固件编译时间
PR_NOTICE("system reset reason:[%s]",tuya_hal_system_get_rst_info());//查看固件重启的原因
SetLogManageAttr(TY_LOG_LEVEL_DEBUG); //本地打印日志等级设置,方便开发调试使用
}
在产品的功能运行之前,相应功能用到的硬件或运行模式需要预先进行配置。通常是一些硬件外设的初始化和产品功能的设置等。
如下是一段应用示例代码,实现了硬件外设初始化、Wi-Fi 工作模式设置及注册产测回调函数等功能。
VOID app_init(VOID)
{
tuya_device_config(); //硬件外设初始化
app_cfg_set(tuya_hard_get_wifi_mode(),prod_test); // 设置Wi-Fi 工作模式,注册产测回调
tuya_iot_wf_timeout_set(180); //设置Wi-Fi配网超时时间
}
涂鸦 Wi-Fi SDK 将操作系统相关的功能封装,配网激活及数据收发处理等 IoT 产品核心功能的任务调度都已经实现,您无需关心具体的任务调度逻辑,调用涂鸦的初始化接口并填入相关参数、注册相关功能的回调函数即可。
如下是一段示例代码,调用 tuya_iot_wf_soc_dev_init_param(cfg,start_mode,cbs,NULL,product_key,wf_sw_ver)
初始化函数,并注册回调函数、Wi-Fi 工作模式、PID、固件版本等信息。其中,回调函数一般包括配网、固件升级、下发数据处理等,PID 是设备连接涂鸦云端激活时的身份信息,固件版本信息用于固件升级时使用。
OPERATE_RET device_init(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
tuya_hard_prod_flag(FALSE);
TY_IOT_CBS_S wf_cbs =
{
gw_status_cb,gw_ug_cb,gw_reset_cb,dev_obj_dp_cb,dev_raw_dp_cb,dev_dp_query_cb, NULL
};
op_ret =
tuya_iot_wf_soc_dev_init_param(tuya_hard_get_wifi_mode(),WF_START_SMART_FIRST,&wf_cbs,NULL,PRODUCT_KEY,DEV_SW_VERSION);
if (OPRT_OK != op_ret)
{
PR_ERR("tuya_iot_wf_soc_dev_init fail,fail_num:%d",op_ret);
return op_ret;
}
}
设备连接网络的完整链路如下图所示:
在网络连接应用中,通常设置一定的硬件触发条件,程序判断满足硬件触发条件时,调用配网函数接口,控制设备进入到配网状态。
如下是通过判断长按按键进入配网的示例代码,当检测到长按按键时,调用配网函数接口控制设备进入配网状态:
STATIC VOID key_process(tuya_pin_name_t port,PUSH_KEY_TYPE_E type,INT_T cnt)
{
PR_DEBUG("port:%d,type:%d,cnt:%d",port,type,cnt); //打印按键外设相关信息
OPERATE_RET op_ret = OPRT_OK;
if(tuya_hard_judge_key_pin(port))
{
if(LONG_KEY == type) //判断是长按按键事件,调用配网接口函数使设备进入配网状态
{
tuya_iot_wf_gw_unactive();//配网接口函数
}
else if(NORMAL_KEY == type) //判断是短按按键事件,调用按键控制函数
{
tuya_hard_key_control(); //响应短按按键功能
op_ret = tuya_hard_channel_upload(DOUBLE_TYPE); //将设备执行本地按键后的状态同步到App和云端
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] tuya_hard_channel_upload fail,fail_num:%d",__FUNCTION__,op_ret);
}
tuya_hard_channel_save();//保存当前设备的状态
}
else
{
PR_NOTICE("key type is no deal");
}
}
return;
}
完整的数据处理链路图下图所示,主要涉及到数据的上报和下发两部分应用。
下发数据处理的回调函数,需要在初始化中时注册,当云端或者 App 端有数据下发时,SDK 会自动找到相应回调函数并执行,您需要完成回调函数的具体逻辑,实现解析接收到的数据并执行相关的命令。
如下是当接收到开关数据的示例代码:
VOID dev_obj_dp_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
PR_NOTICE("app_send dp_cnt:%d",dp->dps_cnt);
OPERATE_RET op_ret = OPRT_OK;
UINT_T dp_index = 0;
UINT_T app_send_dp_num = dp->dps_cnt;
DEV_DP_TYPE_E dpid_type = DP_NOT_EXIST;
for (dp_index = 0;dp_index < app_send_dp_num;dp_index++) //循环解析下发的数据
{
dpid_type = tuya_hard_dpid_type(dp->dps[dp_index].dpid);
PR_DEBUG("dpid_type:%d",dpid_type);
switch (dpid_type) //判断接收到的DP点类型
{
case SW_TYPE: //接收到的是开关DP点,执行开关功能
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_bool);
tuya_hard_channel_control(dp->dps[dp_index].value.dp_bool);
break;
case SW_CD_TYPE://接收到的是倒计时DP点,执行倒计时功能
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_value);
tuya_hard_channel_cd_control(dp->dps[dp_index].value.dp_value);
break;
case RELAY_ST_TYPE://接收到的是上电状态设置DP点,执行状态设置功能
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_enum);
tuya_hard_relay_power_stat(dp->dps[dp_index].value.dp_enum);
break;
default:
break;
}
}
op_ret = tuya_hard_upload_all_data();//执行完控制命令后,将当前设备的状态同步到App和云端
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] tuya_hard_upload_all_data fail,fail_num:%d",op_ret);
}
return;
}
设备状态改变时,根据设备状态对应的 DP 类型,调用相应的上报接口函数,将设备状态同步到云端和 App。
如下是开关、倒计时、上电状态改变时的状态信息上报函数的示例代码:
OPERATE_RET tuya_hard_upload_all_data(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
DP_UPLOAD_S *upload_dp = NULL;
UINT_T dp_cnt = DEV_DP_NUM;
upload_dp = tuya_upload_alloc_space(dp_cnt);//为上报的状态信息申请内存空间
if (NULL == upload_dp)
{
PR_ERR("tuya_upload_alloc_space fail");
return OPRT_COM_ERROR;
}
if (g_dev_info.dev_dp.switch_dp.is_exist)//判断开关 DP 状态是否改变
{
tuya_upload_dp_bool_frame(upload_dp,g_dev_info.dev_dp.switch_dp.dpid_num,g_dev_stat.relay_stat);//开关(bool型) DP 赋值
}
if (g_dev_info.dev_dp.switch_cd_dp.is_exist)//判断倒计时 DP 状态是否改变
{
tuya_upload_dp_value_frame(upload_dp,g_dev_info.dev_dp.switch_cd_dp.dpid_num,g_dev_stat.relay_cd_sec);//倒计时(value型) DP 赋值
}
if (g_dev_info.dev_dp.app_relay_stat.is_exist)//判断上电状态 DP 是否改变
{ tuya_upload_dp_enum_frame(upload_dp,g_dev_info.dev_dp.app_relay_stat.dpid_num,g_dev_stat.relay_power_stat);//上电状态(enmu型) DP 赋值
}
// dev_report_dp_json_async(get_gw_cntl()->gw_if.id, upload_dp->dp_buf, upload_dp->cur_idx)
op_ret = dev_report_dp_json_async(get_gw_cntl()->gw_if.id,upload_dp->dp_buf,upload_dp->cur_index);//上报所有 DP 当前值
tuya_upload_delete_space(upload_dp);//释放存储DP状态的内存空间
if (OPRT_OK != op_ret)
{
PR_ERR("dev_report_dp_json_async all_data is fail,fail_num:%d",op_ret);
return op_ret;
}
PR_DEBUG("upload all dp data sucess");
return OPRT_OK;
}
涂鸦 Wi-Fi SDK 提供标准化的编译脚本,您只需要执行 Shell 命令,即可进行编译即可自动生成生产用的 bin 文件:
命令格式:
sh build.sh 代码路径 代码名称 版本号
命令示例:
sh build.sh apps/tuya_demo_elp_1plug tuya_demo_elp_1plug 1.0.0
如下是编译脚本中的入参部分的示例代码,详细信息请参考 build.app.sh
文件。
APP_PATH=$1
APP_NAME=$2
APP_VERSION=$3
USER_CMD=$4
echo APP_PATH=$APP_PATH
echo APP_NAME=$APP_NAME
echo APP_VERSION=$APP_VERSION
echo USER_CMD=$USER_CMD
...
将编译生成的生产文件烧录到芯片内,并使用涂鸦授权工具进行授权,即可验证代码功能。
不同芯片的烧录方式不同,需要参考具体芯片的烧录说明文档,授权通过串口通信,将授权信息写入到芯片特定 Flash 区域,此部分功能由涂鸦 SDK 自动完成,您无需关心具体的逻辑。
产品在批量生产时,为提高生产效率,会用代码实现批量的自动化测试,通常称为产测。
涂鸦结合多年工厂智能产品生产经验,在 SDK 内封装了扫描特定 SSID 路由器信号,通过判定信号强度确认产品射频性能的产测功能。在预初始化时,注册产测回调接口函数并完成产测逻辑代码,即可实现批量自动化测试。
如下是产测功能的示例代码:
app_cfg_set(tuya_hard_get_wifi_mode(),prod_test); // 预初始化时调用,设置Wi-Fi 工作模式,设置产测
//根据扫描到的 Wi-Fi 路由器信号强度,判定设备的射频性能是否符合要求,并执行功能测试代码。
VOID prod_test(BOOL_T flag,CHAR_T rssi)
{
PR_NOTICE("rssi:%d,flag:%d",rssi,flag);
if (flag == FALSE || rssi < -60)
{
tuya_hard_set_led_state(PROD_TEST_FAIL);
}
tuya_hard_set_led_state(ENTER_PROD_TEST);
tuya_hard_prod_flag(TRUE);
}
完整的 OTA 链路如下图所示:
涂鸦 Wi-Fi SDK 已经实现了主芯片的升级功能,您无需关心具体逻辑,在初始化时注册 OTA 升级接口函数并完成相关回调函数即可。
如下是固件升级回调函数的示例代码:
int gw_ug_cb(IN CONST FW_UG_S *fw)
{
PR_DEBUG("Rev GW Upgrade Info");
PR_DEBUG("fw->fw_url:%s", fw->fw_url);
PR_DEBUG("fw->sw_ver:%s", fw->sw_ver);
PR_DEBUG("fw->file_size:%d", fw->file_size);
return tuya_iot_upgrade_gw(fw, get_file_data_cb, upgrade_notify_cb, NULL);
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈