自制智能镜之——产品创建及开发环境搭建篇(限时活动进行中)
Posted 三明治开发社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制智能镜之——产品创建及开发环境搭建篇(限时活动进行中)相关的知识,希望对你有一定的参考价值。
(限时活动突击上线!3步学会创建产品,还可获得奖品。跟着下面步骤一起,将创建好的产品PID发至下面官方小助手,领取你的专属惊喜吧!)
前言
如何给一面普通的镜子赋予更多的功能?本期系列文章将会教给大家怎样通过涂鸦平台及涂鸦wifi模组快速实现一款智能镜产品。
创建产品
- 首先登录涂鸦智能IoT平台,点击 “创建产品”,在标准类目栏的最下方找到 “找不到品类”,点击进入自定义产品创建页面。
-
输入产品名称和描述,通讯协议选择 WIFI+蓝牙,点击 创建产品。
-
在功能定义一栏添加DP点,如下图所示,本demo添加了标准功能:“开关”、“灯光开关”、“灯光模式”、“亮度值”、“电量状态”、“人体感应状态”、“人体感应开关”等功能;功能点可以根据需求自行增减,功能点名称以及属性也可根据需求自行修改。
-
进入设备面板,可以选择自己喜欢的模板或者自己自定义面板,调试阶段推荐选择开发调试面板,便于测试。
-
选择硬件开发平台,可以根据需要自行选择开发平台。注意,需要选择芯片平台并上传固件后,面板才能够使用;固件标识名要和上传的固件名称需保持一致,否则烧录授权时将无法通过。
- 至此,产品创建阶段已经基本完成,此时可以通过“涂鸦智能”app和虚拟设备体验dp数据的接收和发送。
嵌入式系统搭建
产品创建完毕后,接下来需要实现产品模组固件,首先要做的就是搞定开发环境。
开发环境
本案例是基于BK7231N平台进行的SOC开发,开发所用的涂鸦通用SDK编译需要linux环境,首先要安装linux开发环境,然后从涂鸦仓库拉取包含SDK环境的demo例程。。
-
下载Tuya IoTOS Embeded WiFi & BLE sdk
$ cd "your directory" $ git clone https://github.com/tuya/tuya-iotos-embeded-sdk-wifi-ble-bk7231n
在自己建立的目录中git下来demo,里面有附带有SDK环境,同时“apps”目录中也有几个应用案例,我们就使用apps/tuya_demo_template这个demo为开发模板,在此基础上增减代码,实现一个嵌入式系统框架。
实现配网连接涂鸦平台的最简嵌入式系统框架
在正式开始智能镜应用代码开发前,我们可以先搭建一个基本的嵌入式框架,实现设备联网,与平台建立上报下发通道。
- 在现有的demo基础上搭建系统框架
当前tuya_demo_template应用程序的文件组成如下:
├── src
| └── tuya_device.c //应用层入口文件
|
├── include //头文件目录
| └── tuya_device.h
|
└── output //编译产物
- 将 tuya_demo_template 文件夹更名为 bk7231n_mirror_demo,修改 include 文件夹中的 tuya_device.h 里的 PRODECT_ID 宏定义,修改为我们刚刚创建的智能镜产品的 pid。
- 创建一个 tuya_app.c 文件,做为智能镜应用代码的主要文件
创建后的demo文件目录如下:
├── src
| └── tuya_device.c //应用层入口文件
| └── tuya_app.c //主要应用文件
|
├── include //头文件目录
| └── tuya_device.h
| └── tuya_app.h
|
└── output //编译产物
- tuya_app.h中涉及到 DP 点宏定义以及 DP 点上报、下发数据处理函数的声明。
#ifndef __TUYA_APP_H__
#define __TUYA_APP_H__
#include "uni_log.h"
#include "tuya_cloud_error_code.h"
#include "tuya_cloud_com_defs.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***********************************************************
*************************variable define********************
***********************************************************/
typedef enum{
APP_MIRROR_NORMAL, //normal mode
APP_MIRROR_PRODTEST //prodact test mode
}APP_MIRROR_MODE;
#define DPID_SWITCH 1
#define DPID_SWITCH_LED 2
#define DPID_LIGHT_MODE 4
#define DPID_LIGHT_VALUE 5
#define DPID_BATTERY_STATUS 101
#define DPID_PIR_MODE 103
#define DPID_PIR_STATE 105
/********************************************************************************
* FUNCTION: app_mirror_init
* DESCRIPTION: application initialization
* INPUT: mode:application mode
* OUTPUT: none
* RETURN: none
* OTHERS: none
* HISTORY: 2021-01-12
*******************************************************************************/
OPERATE_RET app_mirror_init(IN APP_MIRROR_MODE mode);
/********************************************************************************
* FUNCTION: deal_dp_proc
* DESCRIPTION: deal the data sented by app
* INPUT: root:app issued data structure
* OUTPUT: none
* RETURN: none
* OTHERS: none
* HISTORY: 2021-01-12
*******************************************************************************/
VOID deal_dp_proc(IN CONST TY_OBJ_DP_S *root);
/*********************************************************************************
* FUNCTION: app_report_all_dp_status
* DESCRIPTION: report all dp date
* INPUT: none
* OUTPUT: none
* RETURN: none
* OTHERS: dp_cnt needs to be modified when adding or deleting the dp function
* HISTORY: 2021-01-12
*******************************************************************************/
VOID app_report_all_dp_status(VOID);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __TUYA_APP_H__*/
- tuya_app.c 中需实现下发 dp 点数据处理函数:deal_dp_proc 和 dp 数据上报函数:app_report_all_dp_status 。这里由于涂鸦SDK在上报 dp 数据时会做筛选处理,所有可以一次性把所有dp点全部上报。
//接收下发数据,解析 dp id 和 dp 内容
VOID deal_dp_proc(IN CONST TY_OBJ_DP_S *root)
{
UCHAR_T dpid;
dpid = root->dpid;
PR_DEBUG("dpid:%d",dpid);
switch (dpid) {
case DPID_SWITCH:
//获取dp内容值
mirror_ctrl_data.Mirror_switch = root->value.dp_bool;
break;
case DPID_SWITCH_LED:
......
break;
case DPID_LIGHT_MODE:
......
break;
case DPID_LIGHT_VALUE:
......
break;
case DPID_PIR_MODE:
......
break;
default:
break;
}
app_report_all_dp_status();
return;
}
//dp数据上报,判断已经连接涂鸦平台后,上报所有 dp 点。
VOID app_report_all_dp_status(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
GW_WIFI_NW_STAT_E wifi_state = 0xFF;
op_ret = get_wf_gw_nw_status(&wifi_state);
if (OPRT_OK != op_ret) {
PR_ERR("get wifi state err");
return;
}
if (wifi_state <= STAT_AP_STA_DISC || wifi_state == STAT_STA_DISC) {
return;
}
INT_T dp_cnt = 0;
dp_cnt = 7;
if(!mirror_ctrl_data.Wifi_state) {
return;
}
TY_OBJ_DP_S *dp_arr = (TY_OBJ_DP_S *)Malloc(dp_cnt*SIZEOF(TY_OBJ_DP_S));
if(NULL == dp_arr) {
PR_ERR("malloc failed");
return;
}
memset(dp_arr, 0, dp_cnt*SIZEOF(TY_OBJ_DP_S));
dp_arr[0].dpid = DPID_SWITCH;
dp_arr[0].type = PROP_BOOL;
dp_arr[0].time_stamp = 0;
dp_arr[0].value.dp_value = mirror_ctrl_data.Mirror_switch;
dp_arr[1].dpid = DPID_SWITCH_LED;
dp_arr[1].type = PROP_BOOL;
dp_arr[1].time_stamp = 0;
dp_arr[1].value.dp_value = mirror_ctrl_data.Light_switch;
dp_arr[2].dpid = DPID_LIGHT_MODE;
dp_arr[2].type = PROP_ENUM;
dp_arr[2].time_stamp = 0;
dp_arr[2].value.dp_value = mirror_ctrl_data.Light_mode;
dp_arr[3].dpid = DPID_LIGHT_VALUE;
dp_arr[3].type = PROP_VALUE;
dp_arr[3].time_stamp = 0;
dp_arr[3].value.dp_value = mirror_ctrl_data.Light_value;
dp_arr[4].dpid = DPID_BATTERY_STATUS;
dp_arr[4].type = PROP_ENUM;
dp_arr[4].time_stamp = 0;
dp_arr[4].value.dp_value = mirror_ctrl_data.Battery_remain;
dp_arr[5].dpid = DPID_PIR_MODE;
dp_arr[5].type = PROP_BOOL;
dp_arr[5].time_stamp = 0;
dp_arr[5].value.dp_value = mirror_ctrl_data.PIR_switch;
dp_arr[6].dpid = DPID_PIR_STATE;
dp_arr[6].type = PROP_ENUM;
dp_arr[6].time_stamp = 0;
dp_arr[6].value.dp_value = mirror_ctrl_data.PIR_state;
op_ret = dev_report_dp_json_async(NULL,dp_arr,dp_cnt);
Free(dp_arr);
if(OPRT_OK != op_ret) {
PR_ERR("dev_report_dp_json_async relay_config data error,err_num",op_ret);
}
PR_DEBUG("dp_query report_all_dp_data");
return;
}
- 修改 tuya_device.c 中的几处回调,将上面实现的 dp 上报和下发处理函数填进去。
VOID dev_obj_dp_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
PR_DEBUG("dp->cid:%s dp->dps_cnt:%d",dp->cid,dp->dps_cnt);
UCHAR_T i = 0;
for(i = 0;i < dp->dps_cnt;i++) {
deal_dp_proc(&(dp->dps[i]));
dev_report_dp_json_async(get_gw_cntl()->gw_if.id, dp->dps, dp->dps_cnt);
}
}
VOID hw_report_all_dp_status(VOID)
{
app_report_all_dp_status();
}
STATIC VOID dev_dp_query_cb(IN CONST TY_DP_QUERY_S *dp_qry)
{
PR_NOTICE("Recv DP Query Cmd");
hw_report_all_dp_status();
}
至此一个基本的配网上报下发接收框架就搭建好了,可以在 dp 下发处理函数中不做任何操作,只执行打印日志,以便测试整个通信链路是否正常。
程序的编译和烧录
-
在SDK根目录下执行以下命令开始编译:
sh build_app.sh apps/bk7231n_mirror_demo bk7231n_mirror_demo 1.0.0
-
固件烧录授权相关信息请参考:Wi-Fi + BLE 系列模组烧录授权
-
设备连接与实验
烧录授权完成后即可打开涂鸦智能app搜索设备进行配网绑定,绑定完成后就可以用 app 下发指令控制设备了。模组日志将输出在串口2。
系统框架建立完成
此时设备已经和app端进行了连接实现了通信,接下来就可以着手开始实现智能镜的具体功能了。
具体功能实现过程将在后续的文章详细介绍。
后续内容
以上是关于自制智能镜之——产品创建及开发环境搭建篇(限时活动进行中)的主要内容,如果未能解决你的问题,请参考以下文章