3. SIG Mesh DEMO使用说明
3.1. 概述
遵守蓝牙SIG Mesh协议,基于蓝牙5 ble实现网内节点间通讯,具体功能如下:
支持 NLC profile;
支持 DFU 远程升级(暂支持bd19/AC632N);
全节点类型支持(Relay/Proxy/Friend/Low Power);
支持以PB-GATT方式入网(手机APP配网,支持”nRF Mesh”安卓和苹果最新版本);
支持以PB-ADV方式入网(“天猫精灵”配网);
支持设备上电自配网(不用配网就可实现设备在同一网内,支持加密key自定义);
节点relay/beacon功能可修改;
节点地址自定义/信息断电保存/Reset为未配网状态;
节点发布(Publish)和订阅(Subscribe)地址可修改;
支持蓝牙SIG既有Models和用户自定义Vendor Models。
支持的板级: br25、bd19、br34、br23
支持的芯片: AC636N、AC632N、AC638N、AC635N
3.2. 工程配置
代码工程:apps/mesh/board/bd19/AC632N_mesh.cbp
▾ mesh/
▾ api/
feature_correct.h
mesh_config_common.c //mesh部分参数的定义
model_api.c //model应用函数合集
model_api.h //demo应用定义合集
▾ board/
▾ bd19/
board_ac632n_demo.c
board_ac632n_demo_cfg.h
board_ac632n_demo_global_build_cfg.h
board_ac632n_distributor.c
board_ac632n_distributor_cfg.h
board_ac632n_distributor_global_build_cfg.h
board_ac632n_target_node.c
board_ac632n_target_node_cfg.h
board_ac632n_target_node_global_build_cfg.h
board_config.h
▾ examples/
AliGenie_fan.c
AliGenie_light.c
AliGenie_socket.c
ambient_light_sensor_nlc.c
basic_lightness_ctrl_nlc.c
basic_scene_selector_nlc.c
dfu_distributor_demo.c
dfu_target_demo.c
dimming_control_nlc.c
energy_monitor_nlc.c
generic_onoff_client.c
generic_onoff_server.c
light_lightness_server.c
light_occupacy_observer_nlc.c
light_occupacy_sensor_nlc.c
provisionee.c
provisioner.c
tencent_mesh.c
TUYA_light.c
vendor_client.c
vendor_server.c
▾ mesh_dfu/
mesh_dfu_app_cmd_protocol.c
mesh_distributor_loader.c
mesh_target_node_ota.c
在api/model_api.h下,通过配置CONFIG_MESH_MODEL选择相应例子,SDK提供了21个应用实例。默认选择SIG_MESH_GENERIC_ONOFF_CLIENT,即位于examples/generic_onoff_client.c下的例子。
//< Detail in "MshPRT_v1.1" #define SIG_MESH_GENERIC_ONOFF_CLIENT 0 // examples/generic_onoff_client.c #define SIG_MESH_GENERIC_ONOFF_SERVER 1 // examples/generic_onoff_server.c #define SIG_MESH_VENDOR_CLIENT 2 // examples/vendor_client.c #define SIG_MESH_VENDOR_SERVER 3 // examples/vendor_server.c #define SIG_MESH_ALIGENIE_LIGHT 4 // examples/AliGenie_light.c #define SIG_MESH_ALIGENIE_SOCKET 5 // examples/AliGenie_socket.c #define SIG_MESH_ALIGENIE_FAN 6 // examples/AliGenie_fan.c #define SIG_MESH_LIGHT_LIGHTNESS_SERVER 7 // examples/light_lightness_server.c #define SIG_MESH_TUYA_LIGHT 8 // examples/TUYA_light.c #define SIG_MESH_TENCENT_MESH 9 // examples/tecent_mesh.c #define SIG_MESH_PROVISIONER 10 // examples/provisioner.c #define SIG_MESH_PROVISIONEE 11 // examples/provisionee.c #define SIG_MESH_OCCUPACY_SENSOR_NLC 12 // examples/light_occupacy_sensor_nlc.c #define SIG_MESH_SENSOR_OBSEVER_NLC 13 // examples/light_occupacy_observer_nlc.c #define SIG_MESH_BASIC_LIGHTNESS_CTRL_NLC 14 // examples/basic_lightness_crtl_nlc.c #define SIG_MESH_DIMMING_CONTROL_NLC 15 // examples/dimming_control_nlc.c #define SIG_MESH_ENERGY_MONITOR_NLC 16 // examples/energy_monitor_nlc.c #define SIG_MESH_BASIC_SCENE_SELECTOR_NLC 17 // examples/basic_scene_selector_nlc.c #define SIG_MESH_AMBIENT_LIGHT_SENSOR_NLC 18 // examples/ambient_light_sensor_nlc.c #define SIG_MESH_DFU_DISTRIBUTOR_DEMO 19 // examples/dfu_distributor_demo.c #define SIG_MESH_DFU_TARGET_DEMO 20 // examples/dfu_target_demo.c // more... //< Config which example will use in <examples> #define CONFIG_MESH_MODEL SIG_MESH_GENERIC_ONOFF_CLIENT
3.2.1. Mesh配置
在api/mesh_config_common.c下,可以自由配置网络和节点特性,例如LPN/Friend节点特性、Proxy下配网前后广播interval、节点信息传递时广播interval和duration等。
如下举例了节点信息传递时广播interval和duration的配置,和PB-GATT下配网前后广播interval的配置。
/** * @brief Config adv bearer hardware param when node send messages */ /*-----------------------------------------------------------*/ const u16 config_bt_mesh_node_msg_adv_interval = ADV_SCAN_UNIT(10); // unit: ms const u16 config_bt_mesh_node_msg_adv_duration = 50; // unit: ms /** * @brief Config proxy connectable adv hardware param */ /*-----------------------------------------------------------*/ const u16 config_bt_mesh_proxy_unprovision_adv_interval = ADV_SCAN_UNIT(30); // unit: ms const u16 config_bt_mesh_proxy_pre_node_adv_interval = ADV_SCAN_UNIT(10); // unit: ms _WEAK_ const u16 config_bt_mesh_proxy_node_adv_interval = ADV_SCAN_UNIT(300); // unit: ms 注意: 在常量前加上"_WEAK_"的声明, 代表这个常量可以在其它文件重定义. 如果想某一配置私有化到某一实例, 应该在该文件下在该配置前加上"_WEAK_"声明, 并在所在实例文件里重定义该常量配置.
3.2.2. board配置
在board/xxxx/board_config.h下,可以根据不同封装选择不同board,以AC63X为例:
1、默认选择CONFIG_BOARD_AC632X_DEMO作为目标板:
/** * 板级配置选择 */ #define CONFIG_BOARD_AC632N_DEMO
2、应用SIG_MESH_DFU_DISTRIBUTOR_DEMO功能,选择CONFIG_BOARD_AC632N_DISTRIBUT作为目标板:
/** * 板级配置选择 */ #define CONFIG_BOARD_AC632N_DISTRIBUTOR
3、应用SIG_MESH_DFU_TARGET_DEMO功能,选择CONFIG_BOARD_AC632N_TARGET作为目标板:
/** * 板级配置选择 */ #define CONFIG_BOARD_AC632N_TARGET
3.3. 应用实例
3.3.1. SIG Generic OnOff Client
1、简介
该实例通过手机“nRF Mesh”进行配网
-> 设备名称:OnOff_cli
-> Node Features:Proxy + Relay
-> Authentication方式:NO OOB
-> Elements个数:1
-> Model:Configuration Server + Health Server + Generic On Off Client
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PB4 作为AD按键
设备名称为“OnOff_cli”,MAC地址为“11:22:33:44:55:66”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_GENERIC_ONOFF_CLIENT -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 #define TCFG_ADKEY_ENABLE ENABLE_THIS_MOUDLE //是否使能AD按键 #define TCFG_ADKEY_PORT IO_PORTB_04 //注意选择的IO口是否支持AD功能 #define TCFG_ADKEY_AD_CHANNEL AD_CH_PB4 -> examples/generic_onoff_client.c #define BLE_DEV_NAME 'O', 'n', 'O', 'f', 'f', '_', 'c', 'l', 'i' #define CUR_DEVICE_MAC_ADDR 0x112233445566如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数。
-> examples/generic_onoff_client.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2).编译工程并下载到目标板,接好串口,接好AD按键,上电或者复位设备
3).使用手机APP“nRF Mesh”进行配网,详细操作请 ->点击这里<-
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Generic On Off Client #SIG Model ID: 0x1001
4).此时按下按键,就能将开关信息Publish到Group地址0xC000了,如果结合下一小节 SIG Generic OnOff Server,就能控制这个server设备led灯的亮和灭了
3、代码解读
3.3.2. SIG Generic OnOff Server
1、简介
该实例通过手机“nRF Mesh”进行配网
-> 设备名称:OnOff_srv
-> Node Features:Proxy + Relay
-> Authentication方式:NO OOB
-> Elements个数:1
-> Model:Configuration Server + Health Server + Generic On Off Server
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用PA1控制LED灯
设备名称为“OnOff_srv”,MAC地址为“85:22:33:44:55:67”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_GENERIC_ONOFF_SERVER -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 -> examples/generic_onoff_server.c #define BLE_DEV_NAME 'O', 'n', 'O', 'f', 'f', '_', 's', 'r', 'v' #define CUR_DEVICE_MAC_ADDR 0x852233445567 const u8 led_use_port[] = { IO_PORTA_01, };如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
-> examples/generic_onoff_server.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2).编译工程并下载到目标板,接好串口,接好演示用LED灯,上电或者复位设备
3).使用手机APP“nRF Mesh”进行配网,详细操作请 ->点击这里<-
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Generic On Off Server #SIG Model ID: 0x1000
4).结合上一小节 SIG Generic OnOff Client ,此时如果Client设备按下按键,那么本机的LED灯就会 亮或者灭了
3、代码解读
3.3.3. SIG AliGenie Socket
1、简介
该实例按照阿里巴巴“*IoT开放平台*”关于“*天猫精灵蓝牙mesh软件基础规范*”,根据“硬件品类规范”描述自己为一个“*插座*”,通过“天猫精灵”语音输入进行发现连接(配网)和控制设备。
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用PA1控制LED灯(模拟插座的开和关的操作)
设备名称为“AG-Socket”
三元组(MAC地址、ProductID、Secret)在天猫精灵开发者网站申请
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_ALIGENIE_SOCKET -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 -> examples/AliGenie_socket.c #define BLE_DEV_NAME 'A', 'G', '-', 'S', 'o', 'c', 'k', 'e', 't' *//< 三元组(本例以个人名义申请的插座类三元组)* #define CUR_DEVICE_MAC_ADDR 0x28fa7a42bf0d #define PRODUCT_ID 12623 #define DEVICE_SECRET "753053e923f30c9f0bc4405cf13ebda6" const u8 led_use_port[] = { IO_PORTA_01, };对于MAC地址,本例中一定要按照三元组里面的MAC地址传入到bt_mac_addr_set函数里
-> examples/AliGenie_socket.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(bt_addr); }2).编译工程并下载到目标板,接好串口,接好演示用LED灯,上电或者复位设备
3).天猫精灵连接到互联网上
①.上电“天猫精灵”,长按设备上的语音按键,让设备进入待连接状态
②.手机应用商店下载“天猫精灵”APP,APP上个人中心登陆
③.打开手机“WLAN”,将“天猫精灵”通过手机热点连接到互联网上
详细操作请 ->点击这里<-
4).通过天猫精灵进行配网和控制
①.配网对话
用户:“天猫精灵,搜索设备”
天猫精灵:“发现一个智能插座,是否连接”
用户:“连接”
天猫精灵:“连接成功。。。 。。。”
②.语音控制插座命令(可通过 IoT开放平台 添加自定义语音命令)
命令:“天猫精灵,打开插座” 效果:开发板上LED灯打开
命令:“天猫精灵,关闭插座” 效果:开发板上LED灯关闭
3、代码解读
1).配网
关键在于如何设置在天猫精灵开发者网站申请下来的三元组
①.天猫精灵开发者网站申请三元组,并填到下面文件相应宏定义处
例如申请到的三元组如下:
Product ID(十进制)
Device Secret:
Mac 地址
12623
753053e923f30c9f0bc4405cf13ebda6
28fa7a42bf0d
则按下面规则填写,MAC前要加上0x,Secret要用双引号包住
-> examples/AliGenie_socket.c //< 三元组(本例以个人名义申请的插座类三元组) #define CUR_DEVICE_MAC_ADDR 0x28fa7a42bf0d #define PRODUCT_ID 12623 #define DEVICE_SECRET "753053e923f30c9f0bc4405cf13ebda6"②.建立Element和Model
按照*插座软件规范*,要建立一个element,两个model
Element
Model
属性名称
Primary
Generic On/Off Server 0x1000
开关
Primary
Vendor Model 0x01A80000
故障上报
Element
Model
属性名称 |
Primary
Generic On/Off Server 0x1000
开关 |
Primary
Vendor Model 0x01A80000
故障上报/ 定时控制开关 |
相应代码操作如下:
结构体elements注册了一个primary element = SIG root_models + Vendor_server_models
结构体root_models = Cfg_Server + Generic_OnOff_Server
结构体vendor_server_models = Vendor_Client_Model + Vendor_Server_Model
//< Basic_Cfg_Server + Generic_OnOff_Server* static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV(&cfg_srv), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv, &onoff_state[0]), }; //< Vendor_Client + Vendor_Server* static struct bt_mesh_model vendor_server_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_CLI, NULL, NULL, NULL), BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_SRV, vendor_srv_op, NULL, &onoff_state[0]), }; //< Only primary element* static struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vendor_server_models), // primary element* // second element* // ... ...* };2).用户数据处理
①.SIG Generic OnOff Server回调
结构体root_models里的Generic_OnOff_Server注册了回调gen_onoff_srv_op来对用户数据进行处理
当收到BT_MESH_MODEL_OP_GEN_ONOFF_GET等注册消息时,就会调用gen_onoff_get等对应的回 调函数进行用户数据处理
static const struct bt_mesh_model_op gen_onoff_srv_op[] = { { BT_MESH_MODEL_OP_GEN_ONOFF_GET, 0, gen_onoff_get }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET, 2, gen_onoff_set }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack }, BT_MESH_MODEL_OP_END, };②.Vendor Model回调
结构体vendor_srv_op里的Vendor_Server_Model注册了回调vendor_srv_op来对用户数据进行处理
当收到VENDOR_MSG_ATTR_GET等注册消息时,就会调用vendor_attr_get等对应的回 调函数进行 用户数据处理
static const struct bt_mesh_model_op vendor_srv_op[] = { { VENDOR_MSG_ATTR_GET, ACCESS_OP_SIZE, vendor_attr_get }, { VENDOR_MSG_ATTR_SET, ACCESS_OP_SIZE, vendor_attr_set }, BT_MESH_MODEL_OP_END, };
3.3.4. SIG AliGenie Light
1、简介
该实例按照阿里巴巴“ IoT开放平台 ”关于“*天猫精灵蓝牙mesh软件基础规范*”,根据“硬件品类规范”描述自己为一个“灯”,通过“天猫精灵”语音输入进行发现连接(配网)和控制设备。
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PA1 控制LED灯(模拟灯的开和关的操作)
设备名称为“AG-Light”
三元组(MAC地址、ProductID、Secret)在天猫精灵开发者网站申请
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_ALIGENIE_LIGHT -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 -> examples/AliGenie_light.c #define BLE_DEV_NAME 'A', 'G', '-', 'L', 'i', 'g', 'h', 't' *//< 三元组(本例以个人名义申请的插座类三元组)* #define CUR_DEVICE_MAC_ADDR 0x18146c110001 #define PRODUCT_ID 7218909 #define DEVICE_SECRET "aab00b61998063e62f98ff04c9a787d4" const u8 led_use_port[] = { IO_PORTA_01, };对于MAC地址,本例中一定要按照三元组里面的MAC地址传入到bt_mac_addr_set函数里
-> examples/AliGenie_light.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(bt_addr); }2).编译工程并下载到目标板,接好串口,接好演示用LED灯,上电或者复位设备
3).天猫精灵连接到互联网上
①.上电“天猫精灵”,长按设备上的语音按键,让设备进入待连接状态
②.手机应用商店下载“天猫精灵”APP,APP上个人中心登陆
③.打开手机“WLAN”,将“天猫精灵”通过手机热点连接到互联网上
详细操作请 ->点击这里<-
4).通过天猫精灵进行配网和控制
①.配网对话 用户:“天猫精灵,搜索设备”
天猫精灵:“发现一个智能灯,是否连接”
用户:“连接”
天猫精灵:“连接成功。。。 。。。”
②.语音控制插座命令(可通过“ IoT开放平台 ”添加自定义语音命令)
命令:“天猫精灵,开灯” 效果:开发板上LED灯打开
命令:“天猫精灵,关灯” 效果:开发板上LED灯关闭
3、代码解读
1).配网
关键在于如何设置在天猫精灵开发者网站申请下来的三元组
①.天猫精灵开发者网站申请三元组,并填到下面文件相应宏定义处
例如申请到的三元组如下:
Product ID(十进制)
Device Secret:
Mac 地址
7218909
aab00b61998063e62f98ff04c9a787d4
18146c110001
则按下面规则填写,MAC前要加上0x,Secret要用双引号包住
-> examples/AliGenie_light.c //< 三元组(本例以个人名义申请的灯具类三元组) #define CUR_DEVICE_MAC_ADDR 0x18146c110001 #define PRODUCT_ID 7218909 #define DEVICE_SECRET "aab00b61998063e62f98ff04c9a787d4"②.建立Element和Model
按照*灯具件规范*,要建立一个element,三个model
Element
Model
属性名称 |
Primary
Generic On/Off Server 0x1000
开关 |
Primary
Light_Lightness_Server 0x1300
亮度 |
Primary
Vendor Model 0x01A80000
故障上报/ 定时控制开关 |
相应代码操作如下:
结构体elements注册了一个primary element = SIG root_models + Vendor_server_models
结构体root_models = Cfg_Server + Generic_OnOff_Server + Light_Lightness_Server
结构体vendor_server_models = Vendor_Client_Model + Vendor_Server_Model
//< Basic_Cfg_Server + Generic_OnOff_Server static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV(&cfg_srv), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv, &onoff_state[0]), BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, light_lightness_srv_op, &gen_onoff_pub_srv, &light), }; //< Vendor_Client + Vendor_Server static struct bt_mesh_model vendor_server_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_CLI, NULL, NULL, NULL), BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_SRV, vendor_srv_op, NULL, &onoff_state[0]), }; //< Only primary element static struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vendor_server_models), // primary element* // second element* // ... ...* };2).用户数据处理
①.SIG Generic OnOff Server回调
结构体root_models里的Generic_OnOff_Server注册了回调gen_onoff_srv_op来对用户数据进行处理
当收到BT_MESH_MODEL_OP_GEN_ONOFF_GET等注册消息时,就会调用gen_onoff_get等对应的回 调函数进行用户数据处理
static const struct bt_mesh_model_op gen_onoff_srv_op[] = { { BT_MESH_MODEL_OP_GEN_ONOFF_GET, 0, gen_onoff_get }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET, 2, gen_onoff_set }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack }, BT_MESH_MODEL_OP_END, };②.Vendor Model回调
结构体vendor_server_models里的Vendor_Server_Model注册了回调vendor_srv_op来对用户数据进行处 理
当收到VENDOR_MSG_ATTR_GET等注册消息时,就会调用vendor_attr_get等对应的回 调函数进行 用户数据处理
static const struct bt_mesh_model_op vendor_srv_op[] = { { VENDOR_MSG_ATTR_GET, ACCESS_OP_SIZE, vendor_attr_get }, { VENDOR_MSG_ATTR_SET, ACCESS_OP_SIZE, vendor_attr_set }, BT_MESH_MODEL_OP_END, };③.Light_Lightness_Server回调
结构体vendor_server_models里的Light_Lightness_Server注册了回调vendor_srv_op来对用户数据进行处 理
当收到BT_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET等注册消息时,就会调用vendor_attr_get等对 应的回调函数进行用户数据处理
static const struct bt_mesh_model_op light_lightness_srv_op[] = { { BT_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET, 0 ,lightness_get }, { BT_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET, 0, lightness_set }, { BT_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK, 0, lightness_set_unack }, BT_MESH_MODEL_OP_END, };
3.3.5. SIG AliGenie Fan
1、简介
该实例按照阿里巴巴“ IoT开放平台 ”关于“*天猫精灵蓝牙mesh软件基础规范*”,根据“硬件品类规范”描述自己为一个“风扇”,通过“天猫精灵”语音输入进行发现连接(配网)和控制设备。
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PA1 控制LED灯(模拟风扇的开和关的操作)
设备名称为“AG-Fan”
三元组(MAC地址、ProductID、Secret)在天猫精灵开发者网站申请
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_ALIGENIE_SOCKET -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORT_DP #define TCFG_UART0_BAUDRATE 1000000 -> examples/AliGenie_fan.c #define BLE_DEV_NAME 'A', 'G', '-', 'F', 'a', 'n' //< 三元组(本例以个人名义申请的风扇类三元组) #define CUR_DEVICE_MAC_ADDR 0x27fa7af002a0 #define PRODUCT_ID 7809508 #define DEVICE_SECRET "d2729d5f3898079fa7b697c76a7bfe8e" const u8 led_use_port[] = { IO_PORTA_01, };对于MAC地址,本例中一定要按照三元组里面的MAC地址传入到bt_mac_addr_set函数里
-> examples/AliGenie_fan.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(bt_addr); }2).编译工程并下载到目标板,接好串口,接好演示用LED灯(用于指示风扇开关状态和风速),上电或者复位设备
3).天猫精灵连接到互联网上
①.上电“天猫精灵”,长按设备上的语音按键,让设备进入待连接状态
②.手机应用商店下载“天猫精灵”APP,APP上个人中心登陆
③.打开手机“WLAN”,将“天猫精灵”通过手机热点连接到互联网上
详细操作请 ->点击这里<-
4).通过天猫精灵进行配网和控制
①.配网对话
用户:“天猫精灵,搜索设备”
天猫精灵:“发现一个风扇,是否连接”
用户:“连接”
天猫精灵:“连接成功。。。 。。。”
②.语音控制插座命令(可通过“ IoT开放平台 ”添加自定义语音命令)
命令:“天猫精灵,打开风扇” 效果:开发板上LED灯打开
命令:“天猫精灵,风扇调到2挡” 效果:开发板上LED灯亮度改变
命令:“天猫精灵,关闭风扇” 效果:开发板上LED灯关闭
3、代码解读
1).配网
关键在于如何设置在天猫精灵开发者网站申请下来的三元组
①.天猫精灵开发者网站申请三元组,并填到下面文件相应宏定义处
例如申请到的三元组如下:
Product ID(十进制)
Device Secret:
Mac 地址
7809508
d2729d5f3898079fa7b697c76a7bfe8e
27fa7af002a0
则按下面规则填写,MAC前要加上0x,Secret要用双引号包住
-> examples/AliGenie_fan.c //< 三元组(本例以个人名义申请的风扇类三元组) #define CUR_DEVICE_MAC_ADDR 0x27fa7af002a0 #define PRODUCT_ID 7809508 #define DEVICE_SECRET "d2729d5f3898079fa7b697c76a7bfe8e"②.建立Element和Model
按照*风扇软件规范*,要建立一个element,两个model
Element
Model
属性名称 |
Primary
Generic On/Off Server 0x1000
开关 |
Primary
Vendor Model 0x01A80000
调整风速档位/ 定时控制开关 |
相应代码操作如下:
结构体elements注册了一个primary element = SIG root_models + Vendor_server_models
结构体root_models = Cfg_Server + Generic_OnOff_Server
结构体vendor_server_models = Vendor_Client_Model + Vendor_Server_Model
//< Basic_Cfg_Server + Generic_OnOff_Server static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_CFG_SRV(&cfg_srv), BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op, &gen_onoff_pub_srv, &onoff_state[0]), }; //< Vendor_Client + Vendor_Server static struct bt_mesh_model vendor_server_models[] = { BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_CLI, NULL, NULL, NULL), BT_MESH_MODEL_VND(BT_COMP_ID_LF, BT_MESH_VENDOR_MODEL_ID_SRV, vendor_srv_op, NULL, &onoff_state[0]), }; //< Only primary element static struct bt_mesh_elem elements[] = { BT_MESH_ELEM(0, root_models, vendor_server_models), // primary element* // second element* // ... ...* };2).用户数据处理
①.SIG Generic OnOff Server回调
结构体root_models里的Generic_OnOff_Server注册了回调gen_onoff_srv_op来对用户数据进行处理
当收到BT_MESH_MODEL_OP_GEN_ONOFF_GET等注册消息时,就会调用gen_onoff_get等对应的回 调函数进行用户数据处理
static const struct bt_mesh_model_op gen_onoff_srv_op[] = { { BT_MESH_MODEL_OP_GEN_ONOFF_GET, 0, gen_onoff_get }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET, 2, gen_onoff_set }, { BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack }, BT_MESH_MODEL_OP_END, };②.Vendor Model回调
结构体vendor_srv_op里的Vendor_Server_Model注册了回调vendor_srv_op来对用户数据进行处理
当收到VENDOR_MSG_ATTR_GET等注册消息时, 就会调用vendor_attr_get等对应的回调函数进行用户数据处理
static const struct bt_mesh_model_op vendor_srv_op[] = { { VENDOR_MSG_ATTR_GET, ACCESS_OP_SIZE, vendor_attr_get }, { VENDOR_MSG_ATTR_SET, ACCESS_OP_SIZE, vendor_attr_set }, BT_MESH_MODEL_OP_END, };
3.3.6. SIG Vendor Client
1、简介
该实例会自动进行配网。
-> 设备名称: Vd_cli -> Node Features: Proxy -> Authentication方式: NO OOB -> Elements个数: 1 ->Root model: Configuration Server + Configuration Client ->Vendor model: Vendor_Client_Model
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PB4 作为AD按键端口,将PB4与ADKEY相连
设备名称为“Vd_cli” , “Node”地址为“0x0001”, “Group”地址为“0xc000”,MAC地址为“33:22:33:44:55:66”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_VENDOR_CLIENT > board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 -> examples/vendor_client.c #define BLE_DEV_NAME 'V', 'd', '_', 'c', 'l', 'i' #define CUR_DEVICE_MAC_ADDR 0x332233445566 const u8 led_use_port[] = { IO_PORTA_01, };3).编译工程并下载到目标板上,接好串口,PB4接好AD_key,上电或者复位设备
4).此时按下按键,就能把开关信息Publish到Group地址0xC000了,结合下一小节 SIG Vendor Server, 就可以控制server设备上的LED灯的亮灭了
3、代码解读
1).配网流程
1.配置节点信息与元素组成
int bt_mesh_init(const struct bt_mesh_prov *prov,const struct bt_mesh_comp *comp); // parameters: // 本实例中的prov: static const struct bt_mesh_prov prov = { uuid = dev_uuid, output_size = 0, output_actions = 0, output_number = 0, complete = prov_complete, .reset = prov_reset, }; // 本实例中的comp: static const struct bt_mesh_comp composition = { .cid = BT_COMP_ID_LF, .elem = elements, .elem_count = ARRAY_SIZE(elements), }; // return 返回值: int 型, 返回0代表成功, 其他代表出错2.配置节点地址与网络通信密钥
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, u32_t iv_index, u16_t addr, const u8_t dev_key[16]); parameters: addr 节点地址 net_key 网络密钥, 用于保护网络层的通信 net_idx net_key网络密钥的索引 dev_key 设备密钥, 用于保护节点和配置客户端之间的通信 return_value: int 型, 返回0代表成功, 其他代表出错3.为节点添加app_key
添加的AppKey必须与NetKey成对使用,AppKey用于对接收和发送的消息进行身份验证和加密
int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16], u8_t *status); parameters: addr 节点地址 app_key 应用密钥, 用于保护上层传输层的通信 key_app_idx app_key的索引 return_value: int 型, 返回0代表成功, 其他代表出错4.小结
本实例中配置的net_key/dev_key/app_key必须与server的相同否则无法正常进行通信
2).model配置
1.将model绑定到该节点添加的app_key,将应用密钥与元素的模型绑定在一起
int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,u16_t mod_app_idx, u16_t mod_id, u16_t cid,u8_t *status); parameters: addr 节点地址 elem_addr 配置为该模型的元素地址 mod_id 模型的标识本例中的mod_id: BT_MESH_VENDOR_MODEL_ID_CLI key_app_idx app_key的索引 cid 公司标识符 return_value: int 型2.为model添加publish行为,配置模型的发布状态
int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,u16_t mod_id, u16_t cid,struct bt_mesh_cfg_mod_pub *pub, u8_t *status); parameters: addr 本节点的地址, 即node_addr elem_addr 配置为pub中的发送属性的元素地址 pub pub结构体存放publish行为的相关属性 本实例中的pub结构体: struct bt_mesh_cfg_mod_pub pub; pub.addr = dst_addr; //publish的目的地址 pub.app_idx = app_idx; //app_key的索引 pub.cred_flag = 0; //friendship的凭证标志 pub.ttl = 7; //生命周期, 决定能被relay的次数 pub.period = 0; //定期状态发布的周期 pub.transmit = 0; //每次 publish msg的重传次数(高3位) + 重传输之间50ms的步骤数(低5位) status 请求消息的状态3).节点行为
client的Publish行为
当按键按下时进入 input_key_handle 函数,该函数会获取按键的键值和按键的状态,进行按键处理
void input_key_handler(u8 key_status, u8 key_number)根据按键的不同状态 input_key_handle 函数会将相应的状态信息(点击为1,长按为0)通过结构体struct _switch *sw传入client_publish函数
static void client_publish(struct switch *sw)client_publish 函数会对要发送的msg进行处理,接下来会详细介绍client_publish中主要函数的作用及msg的构成
首先 client_publish 函数根据key_number获取存在mod_cli_sw结构体里相应的 vendor_model,这个 vendor_model 的发送属性在上一节的 bt_mesh_cfg_mod_pub_set_vnd 函数里已经进行了配置之后使用bt_mesh_model_msg_init函数初始化一个结构体msg并存入3字节的操作码
void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode);接下来会使用buffer_add_u8_at_tail函数添加一个状态值到msg尾部,用于server端控制LED状态
u8 *buffer_add_u8_at_tail(void *buf, u8 val);然后使用buffer_memset函数将msg中剩下的空的部分用0x02填满,msg剩下的空的部分可以也可以由用户自定义内容
void *buffer_memset(struct net_buf_simple *buf, u8 val, u32 len);之后就用bt_mesh_model_publish把包含msg的信息发送出去
int bt_mesh_model_publish(struct bt_mesh_model *model);
client的回调函数
结构体vendor_client_models里的BT_MESH_VENDOR_MODEL_ID_CLI注册了vendor_cli_op来进行数据处理
当收到对面的ack msg并匹配上BT_MESH_VENDOR_MODEL_OP_STATUS时就会调用 vendor_status回调函数对数据进行处理
static const struct bt_mesh_model_op vendor_cli_op[] = { { BT_MESH_VENDOR_MODEL_OP_STATUS, ACCESS_OP_SIZE, vendor_status }, BT_MESH_MODEL_OP_END, };vendor_status 函数的功能:显示作为ack msg的发送方server端的地址及其所受到client控制的情况
static void vendor_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
3.3.7. SIG Vendor Server
1、简介
该实例会自动进行配网。
-> 设备名称: Vd_srv -> Node Features: Proxy -> Authentication方式: NO OOB -> Elements个数: 1 -> Root model: Configuration Server + Configuration Client -> Vendor model: Vendor_Server_Model
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PB4 作为AD按键端口,将PA1与LED相连
设备名称为“Vd_srv” , “Node”地址为“0x0002”, “Group”地址为“0xc000”,MAC地址为“44:22:33:44:55:66”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_VENDOR_SERVER > board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 -> examples/vendor_server.c #define BLE_DEV_NAME 'V', 'd', '_', 's', r', 'v' #define CUR_DEVICE_MAC_ADDR 0x442233445566 const u8 led_use_port[] = { IO_PORTA_01, };2).编译工程并下载到目标板上,接好串口,接好 LED 灯,PB4接好AD_key,上电或者复位设备
3).此时若 client 端按下按键,server 设备上的 LED 灯就会根据按键的点击还是长按而点亮或熄灭了
3、代码解读
1).配网流程
配置节点的信息与元素组成
int bt_mesh_init(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp); parameters: prov 节点的配置信息 本实例中的prov: static const struct bt_mesh_prov prov = { .uuid = dev_uuid, .output_size = 0, .output_actions = 0, .output_number = 0, .complete = prov_complete, .reset = prov_reset, }; comp 节点的元素组成 本实例中的comp: static const struct bt_mesh_comp composition = { .cid = BT_COMP_ID_LF, .elem = elements, .elem_count = ARRAY_SIZE(elements), }; return 值: int 型, 返回0代表成功, 其他代表出错配置节点地址与网络通信密钥
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, u32_t iv_index, u16_t addr, const u8_t dev_key[16]); parameters: addr 节点地址 net_key 网络密钥, 用于保护网络层的通信 net_idx net_key的索引 dev_key 设备密钥 用于保护节点和配置客户端之间的通信. return_value: int 型, 返回0代表成功, 其他代表出错
为节点添加app_key
添加的AppKey必须与NetKey成对使用,AppKey用于对接收和发送的消息进行身份验证和加密
int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16], u8_t *status); parameters: addr 节点地址 key_app_idx app_key的索引 app_key 应用密钥, 用于保护上层传输层的通信 status 请求消息的状态 return_value: int 型
小结
本实例中配置的net_key/dev_key/app_key必须与server的相同否则无法正常进行通信
2).model配置
将model绑定到该节点添加的app_key, 将应用密钥与元素的模式绑定在一起
int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid, u8_t *status); parameters: addr 节点地址 elem_addr 配置为该模型的元素地址 mod_id 模型的标识 本例中的mod_id: BT_MESH_VENDOR_MODEL_ID_CLI key_app_idx app_key的索引 cid 公司标识符 status 请求消息的状态 return_value: int 型为model添加Subscription地址
配置模型的订阅地址,用于接收 client 端 publish 的msg
int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid, u8_t *status); parameters: addr 本节点的地址 elem_addr 元素地址, 此处填入订阅控制信息对应元素的地址 sub_addr 订阅的地址 mod_id 模型的标识 status 请求消息的状态 return_value: int 型3).节点行为
server的回调函数
结构体 vendor_client_models 里的 BT_MESH_VENDOR_MODEL_ID_CLI 注册了 vendor_cli_op 来进行数据处理
当收到对面的ack并匹配上 BT_MESH_VENDOR_MODEL_OP_STATUS 时就会调用 vendor_set 回调函数对数据进行处理
static void vendor_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)vendor_set 函数中使用 buffer_pull_u8_from_head 函数提取msg中存放的led状态信息
u8 buffer_pull_u8_from_head(void *buf);之后使用 gpio_pin_write 函数进行点灯或者灭灯操作
void gpio_pin_write(u8_t led_index, u8_t onoff) parameters: led_index GPIO口的索引 onoff LED的亮灭状态进行点灯操作后要组织信息作为ack反馈给 client 端,首先使用 bt_mesh_model_msg_init 函数
初始化一个 net_buf_simple 类型对象 ack_msg 并在其中添加3字节的操作码
void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode)之后使用 buffer_add_u8_at_tail 函数在 ack_msg 函数的尾部添加LED的状态
u8 *buffer_add_u8_at_tail(void *buf, u8 val);然后使用 buffer_memset 函数将 ack_msg 填满
void *buffer_memset(struct net_buf_simple *buf, u8 val, u32 len);最后就使用 bt_mesh_model_send 函数将反馈信息发送给 client 端
int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data); parameters: model 发送信息所属的模型 ctx 消息的环境信息, 包括通信的密钥, 生命周期, 远端地址等 msg 反馈信息ack_msg cb 可选的消息发送的回调, 此实例为空 cb_data 要传递给回调的用户数据, 此实例为空
3.3.8. SIG Provisioner
1、简介
该实例为SIG mesh中的配网者,充当“nRF mesh app”的角色,通过“PB-ADV”的方式完成组网。
-> 设备名称:Provisioner
-> Elements个数:1
-> Model:Configuration Server + Configuration Client + Generic On Off Client
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PB4 作为AD按键
设备名称为“Provisioner”,MAC地址为“11:22:33:44:00:00”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_PROVISIONER -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 #define TCFG_ADKEY_ENABLE ENABLE_THIS_MOUDLE //是否使能AD按键 #define TCFG_ADKEY_PORT IO_PORTB_04 //注意选择的IO口是否支持AD功能 #define TCFG_ADKEY_AD_CHANNEL AD_CH_PB4 -> examples/provisioner.c #define BLE_DEV_NAME 'P', 'r', 'o', 'v', 'i', 's', 'i', 'o', 'n', 'e', 'r' #define CUR_DEVICE_MAC_ADDR 0x112233440000配网者支持配网节点个数为3,支持子网个数为3,支持app_key个数为3
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
-> examples/provisioner.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); mesh_setup(mesh_init); }配置好需要进行配网的节点设备的uuid,本实例中与该节点设备的mac地址进行对应
-> examples/provisioner.c #define PROVISIONEE_DEVICE_MAC_ADDR 0x112233445566 static const u8_t match_dev_uuid[16] = {MAC_TO_LITTLE_ENDIAN(PROVISIONEE_DEVICE_MAC_ADDR)};2).编译工程并下载到目标板,接好串口,PB4接好AD_key,上电或者复位设备
3).此时按下按键K5,就能对设备进行配网了,如果结合下一小节 SIG Provisionee,就能对设备进行配网和控制led灯的亮和灭了
3、代码解读
3.3.9. SIG Provisionee
1、简介
该实例为SIG mesh中的节点角色,可以通过“PB-ADV”/“PB-GATT”的方式完成组网。
-> 设备名称:Provisionee
-> Elements个数:1
-> Model:Configuration Server + Generic On Off Server
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PA1 控制LED灯
设备名称为“Provisionee”,MAC地址为“11:22:33:44:55:66”
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_PROVISIONEE -> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 #define TCFG_ADKEY_ENABLE ENABLE_THIS_MOUDLE //是否使能AD按键 #define TCFG_ADKEY_PORT IO_PORTB_04 //注意选择的IO口是否支持AD功能 #define TCFG_ADKEY_AD_CHANNEL AD_CH_PB4 -> examples/provisionee.c #define BLE_DEV_NAME 'P', 'r', 'o', 'v', 'i', 's', 'i', 'o', 'n', 'e', 'e' #define CUR_DEVICE_MAC_ADDR 0x112233445566如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
-> examples/provisionee.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
3).如果结合上一小节 SIG Provisioner,此时provisioner按下按键K5,就能对provisionee进行配网和控制led灯的亮和灭了
3、代码解读
3.3.10. SIG NLC Profile
1、简介
该实例为SIG mesh中的蓝牙网络照明控制(NLC),是一套蓝牙Mesh配置文件,用于标准化灯具、传感器和控制设备的接口。
NLC 是无线照明控制的全栈标准,涵盖无线电层、协议层和设备层的标准化,实现了无线照明控制的多厂商互操作性和大规模应用。
NLC 配置文件定义了以下设备类型的标准:
-> 环境光传感器:对应实例为 SIG_MESH_AMBIENT_LIGHT_SENSOR_NLC
-> 基本亮度控制器:对应实例为 SIG_MESH_BASIC_LIGHTNESS_CTRL_NLC
-> 基本场景选择器:对应实例为 SIG_MESH_BASIC_SCENE_SELECTOR_NLC
-> 调光控制器:对应实例为 SIG_MESH_DIMMING_CONTROL_NLC
-> 能源监控器:对应实例为 SIG_MESH_ENERGY_MONITOR_NLC
-> 占用传感器:对应实例为 SIG_MESH_OCCUPACY_SENSOR_NLC
所有实例都可通过手机“nRF Mesh”进行配网.
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
使用 PA1 控制LED灯
-> board/xxxx/board_xxxx_demo_cfg.h #define TCFG_UART0_TX_PORT IO_PORTA_00 #define TCFG_UART0_BAUDRATE 1000000 #define TCFG_ADKEY_ENABLE ENABLE_THIS_MOUDLE //是否使能AD按键 #define TCFG_ADKEY_PORT IO_PORTB_04 //注意选择的IO口是否支持AD功能 #define TCFG_ADKEY_AD_CHANNEL AD_CH_PB4如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2.1).环境光传感器
-> Elements个数:1
-> Model:Configuration Server + Health Server + Sensor Server
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_AMBIENT_LIGHT_SENSOR_NLC -> examples/ambient_light_sensor_nlc.c #define BLE_DEV_NAME 'A', 'm', 'b', 'i', 'e', 'n', 't', 'L', 'i', 'g', 'h', 't', 'S', 'e', 'n', 's', 'o', 'r', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x112233445575 /** Ambient Light Sensor NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_AMBIENT_LIGHT_SENSOR 0x1600 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_AMBIENT_LIGHT_SENSOR, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };2.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
2.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Sensor Server #SIG Model ID: 0x1100
Sensor Setup Server #SIG Model ID: 0x1101
3.1).基本亮度控制器:
-> Elements个数:2
-> Element1:Configuration Server + Health Server +
Generic Level Server + Generic OnOff Server + Generic Default Transition Timer Server +
Generic Power On Off Server + Generic Power On Off Setup Server +
Light Lightness Server + Light Lightness Setup Server + Scene Server + Scene Setup Server
-> Element2: Generic On Off Server + Light LC Server + Light LC Setup Server
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_BASIC_LIGHTNESS_CTRL_NLC -> examples/basic_lightness_crtl_nlc.c #define BLE_DEV_NAME 'B', 'a', 's', 'i', 'c', 'L', 'i', 'g', 'h', 't', 'n', 'e', 's', 's', 'C', 't', 'r', 'l', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x112233445571 /** Basic Lightness Controller NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_BASIC_LIGHTNESS_CONTROLLER 0x1601 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_BASIC_LIGHTNESS_CONTROLLER, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };3.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
3.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Generic Level Server #SIG Model ID: 0x1002
Generic OnOff Server #SIG Model ID: 0x1000
Generic Default Transition Timer Server #SIG Model ID: 0x1004
Generic Power On Off Server #SIG Model ID: 0x1006
Generic Power On Off Setup Server #SIG Model ID: 0x1006
Light Lightness Server #SIG Model ID: 0x1300
Light Lightness Setup Server #SIG Model ID: 0x1301
Scene Server #SIG Model ID: 0x1203
Scene Setup Server #SIG Model ID: 0x1204
▾ Element
Generic OnOff Server #SIG Model ID: 0x1000
Light LC Server #SIG Model ID: 0x130F
Light LC Setup Server #SIG Model ID: 0x1310
3.4).如果结合小节 调光控制器,可以控制基本亮度控制器的led灯逐渐变亮或逐渐变暗。
4.1).基本场景选择器
-> Elements个数:1
-> Model:Configuration Server + Health Server + Scene Client
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_BASIC_SCENE_SELECTOR_NLC -> examples/basic_scene_selector_nlc.c #define BLE_DEV_NAME 'B', 'a', 's', 'i', 'c', 'S', 'c', 'e', 'n', 'e', 'S', 'e', 'l', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x112233445573 /** Basic Scene Selector NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_BASIC_SCENE_SELECTOR 0x1602 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_BASIC_SCENE_SELECTOR, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };4.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
4.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Scene Client #SIG Model ID: 0x1205
5.1).调光控制器
-> Elements个数:1
-> Model:Configuration Server + Health Server + Generic Level Client
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_DIMMING_CONTROL_NLC -> examples/dimming_control_nlc.c #define BLE_DEV_NAME 'D', 'i', 'm', 'm', 'i', 'n', 'g', 'C', 't', 'r', 'l', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x112233445570 /** Dimming Control NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_DIMMING_CONTROL 0x1603 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_DIMMING_CONTROL, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };5.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
5.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Generic Level Client #SIG Model ID: 0x1003
5.4).如果结合小节 基本亮度控制器,调光控制器完成配网并且设置发布地址后按下按键K1,控制基本亮度控制器的led灯逐渐变亮;按下按键K2,控制基本亮度控制器的led灯逐渐变暗。
6.1).能源监控器
-> Elements个数:1
-> Model:Configuration Server + Health Server + Sensor Server + Sensor Setup Server
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_ENERGY_MONITOR_NLC -> examples/energy_monitor_nlc.c #define BLE_DEV_NAME 'E', 'n', 'e', 'r', 'g', 'y', 'M', 'o', 'n', 'i', 't', 'o', 'r', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x112233445572 /** Energy Monitor NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_ENERGY_MONITOR 0x1604 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_ENERGY_MONITOR, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };6.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
6.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Sensor Server #SIG Model ID: 0x1100
Sensor Setup Server #SIG Model ID: 0x1101
7.1).占用传感器
-> Elements个数:1
-> Model:Configuration Server + Health Server + Sensor Server + Sensor Setup Server
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_OCCUPACY_SENSOR_NLC -> examples/light_occupacy_sensor_nlc.c #define BLE_DEV_NAME 'L', 'i', 'g', 'h', 't', 'O', 'c', 'c', 'p', 'a', 'c', 'y', 'S', 'e', 'n', 's', 'o', 'r', 'N', 'l', 'c' #define CUR_DEVICE_MAC_ADDR 0x762233445566 /** Occupancy Sensor NLC Profile 1.0 */ #define BT_MESH_NLC_PROFILE_ID_OCCUPANCY_SENSOR 0x1605 // composition page 2 static const uint8_t cmp2_elem_offset1[1] = {0}; static const struct bt_mesh_comp2_record comp_rec[1] = { { .id = BT_MESH_NLC_PROFILE_ID_OCCUPANCY_SENSOR, .version.x = 1, .version.y = 0, .version.z = 0, .elem_offset_cnt = 1, .elem_offset = cmp2_elem_offset1, .data_len = 0 } }; static const struct bt_mesh_comp2 comp_p2 = { .record_cnt = 1, .record = comp_rec };7.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
7.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Sensor Server #SIG Model ID: 0x1100
Sensor Setup Server #SIG Model ID: 0x1101
7.4).如果结合小节 占用传感器监测,此时 占用传感器 设备点击k2会定时发送当前占用模型状态, 占用传感器监测 设备在完成配网和消息订阅后可以持续收到占用模型状态信息。
8.1).占用传感器监测
-> Elements个数:1
-> Model:Configuration Server + Health Server + Sensor Client
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_SENSOR_OBSEVER_NLC -> examples/light_occupacy_observer_nlc.c #define BLE_DEV_NAME 'L', 'i', 'g', 'h', 't', 'O', 'c', 'c', 'p', 'a', 'c', 'y', 'O', 'b', 's', 'e', 'r', 'v', 'e', 'r' #define CUR_DEVICE_MAC_ADDR 0x992233445567 // composition data page static const struct bt_mesh_comp comp = { .cid = BT_COMP_ID_LF, .elem = elements, .elem_count = ARRAY_SIZE(elements), };8.2).编译工程并下载到目标板,接好串口,PA1接好LED,PB4接好AD_key,上电或者复位设备
8.3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_keyset publish addrset Subscribe addr。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Sensor Client #SIG Model ID: 0x1102
8.4).如果结合小节 占用传感器,此时 占用传感器 设备点击k2会定时发送当前占用模型状态, 占用传感器监测 设备在完成配网和消息订阅后可以持续收到占用模型状态信息。
3、代码解读
3.3.11. SIG DFU Distributor
1、简介
该实例为SIG mesh dfu中的分发器角色,可以通过手机“nRF Mesh”完成组网。
分发器向目标节点提供新的固件映像,并监视固件更新的进度。
-> 设备名称:DFU_dist_demo
-> Elements个数:1
-> Model:Configuration Server + Health Server +
Blob Transfer Client + Firmware Update Client + Blob Transfer Server + Firmware Distribution Server
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_DFU_DISTRIBUTOR_DEMO -> board/bd19/board_config.h /** * 板级配置选择 */ #define CONFIG_BOARD_AC632N_DISTRIBUTOR -> board/bd19/board_ac632n_distributor_global_build_cfg.h #define CONFIG_RESERVED_AREA1_LEN 0x3C000 //可升级的bin size为240K -> examples/dfu_distributor_demo.c #define BLE_DEV_NAME 'D', 'F', 'U', '_', 'd', 'i', 's', 't', '_', 'd', 'e', 'm', 'o' #define CUR_DEVICE_MAC_ADDR 0xbb2233445567如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
-> examples/dfu_distributor_demo.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2).编译工程并下载到目标板,接好串口,上电或者复位设备
3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_key。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Blob Transfer Client #SIG Model ID: 0x1401
Firmware Update client #SIG Model ID: 0x1403
Blob Transfer Server #SIG Model ID: 0x1400
Firmware Distribution Server #SIG Model ID: 0x1404
4).如果结合小节 SIG DFU Target,可以完成单播DFU或多播DFU,即 1个 distributor + 多个 target的dfu环境,具体可看下一章节。
3、代码解读
3.3.12. SIG DFU Target
1、简介
该实例为SIG mesh dfu中的目标角色,可以通过手机“nRF Mesh”完成组网。
目标节点角色接收固件更新。
-> 设备名称:DFU_target_demo
-> Elements个数:1
-> Model:Configuration Server + Health Server + Blob Transfer Server + Firmware Update Server
2、实际操作
1).基本配置
使用 IO_PORTA_00 作为串口debug脚,波特率为1000000
-> api/model_api.h #define CONFIG_MESH_MODEL SIG_MESH_TARGET_DEMO -> board/bd19/board_config.h /** * 板级配置选择 */ #define CONFIG_BOARD_AC632N_TARGET -> examples/dfu_target_demo.c #define BLE_DEV_NAME 'D', 'F', 'U', '_', 't', 'a', 'r', 'g', 'e', 't', '_', 'd', 'e', 'm', 'o' #define CUR_DEVICE_MAC_ADDR 0x632233445567如果想用默认的蓝牙广播名称,应不使用配置工具来配置蓝牙广播名称。
对于MAC地址,如果想不同设备在第一次上电时使用随机值,可以按照以下操作,将NULL传入 bt_mac_addr_set函数
如果想用配置工具配置MAC地址,应不调用bt_mac_addr_set函数
-> examples/dfu_target_demo.c void bt_ble_init(void) { u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)}; bt_mac_addr_set(NULL); }2).编译工程并下载到目标板,接好串口,上电或者复位设备
3).使用手机APP“nRF Mesh”进行配网,以‘OnOff_srv’为演示参考,详细操作请 ->点击这里<-
分别bind app_key。
配网完成后节点结构如下:
▾ Elements
▾ Element
Configuration Server #SIG Model ID: 0x0000
Health Server #SIG Model ID: 0x0002
Blob Transfer Server #SIG Model ID: 0x1400
Firmware Update Server #SIG Model ID: 0x1402
4).如果结合小节 SIG DFU Distributor,可以完成单播DFU或多播DFU,即 1个 distributor + 多个 target的dfu环境,具体操作流程如下:
4.1).对target设置“0x0011”的地址配网(对于多台设备,则配网地址逐1累加,方便添加后续升级设备,目前支持同时升级设备数为10);
将“Blob Transfer Server”和“Firmware Update Server”绑定app key;
在“subscriptions”下点击“subscribe”将设备订阅到一个组里,如0xC001。
4.2).target端接上设备log,点击开发板K1键,设备会打印”Current composition data hash: 0xXXX”,记录下该数据,用于后续APP输入参数。(注意:对于有相同元素的设备只需操作一次)
4.1).distributor端通过手机”nRF mesh app”配网完成,
并将“Blob Transfer Client”“Firmware Update Client”“Blob Transfer Server”和“Firmware Distribution Server”绑定app key;
4.2).使用“jieli mesh dfu app”对distributor进行连接,APP安装包下载请 ->点击这里<-
APP使用详细操作请 ->点击这里<-
4.3).“jieli mesh dfu app”可以与distributor端一直处于连接状态,这样可以随时获取DFU状态。DFU完成后,distributor端会通知target端更新bin文件。
4.4).至此,mesh dfu流程完成。
3、代码解读