nordic 52832添加HID服务实现手机蓝牙自拍杆功能 附遇到的问题和解决方法

本文主要是介绍nordic 52832添加HID服务实现手机蓝牙自拍杆功能 附遇到的问题和解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

此教程基于SD 2.0

原理:添加HID服务模拟外设滑鼠给手机发送音量加或减实现控制相机拍照,参照SDK工程->ble_app_hids_mouse

需要添加的功能

1.HID服务

2.设备管理机制DM

3.储存设备信息pstorage

流程

1.蓝牙初始化内添加device_manager_init(0);参数0代表保存以往连接设备,方便自动连接

void device_manager_init(bool erase_bonds)
{uint32_t               err_code;dm_init_param_t        init_param = {.clear_persistent_data = erase_bonds};dm_application_param_t register_param;// Initialize peer device handle.err_code = dm_handle_initialize(&m_bonded_peer_handle);APP_ERROR_CHECK(err_code);// Initialize persistent storage module.err_code = pstorage_init();APP_ERROR_CHECK(err_code);err_code = dm_init(&init_param);APP_ERROR_CHECK(err_code);memset(&register_param.sec_param, 0, sizeof(ble_gap_sec_params_t));register_param.sec_param.bond         = SEC_PARAM_BOND;register_param.sec_param.mitm         = SEC_PARAM_MITM;register_param.sec_param.lesc         = SEC_PARAM_LESC;register_param.sec_param.keypress     = SEC_PARAM_KEYPRESS;register_param.sec_param.io_caps      = SEC_PARAM_IO_CAPABILITIES;register_param.sec_param.oob          = SEC_PARAM_OOB;register_param.sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;register_param.sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;register_param.evt_handler            = device_manager_evt_handler;register_param.service_type           = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;err_code = dm_register(&m_app_handle, &register_param);APP_ERROR_CHECK(err_code);
}

2.services_init()内增加HID服务hids_init();

void hids_init(void)
{uint32_t                  err_code;ble_hids_init_t           hids_init_obj;ble_hids_inp_rep_init_t   inp_rep_array[INPUT_REPORT_COUNT];ble_hids_inp_rep_init_t * p_input_report;uint8_t                   hid_info_flags;static uint8_t rep_map_data[] ={0x05, 0x01,                     // Usage Page (Generic Desktop)0x09, 0x02,                     // Usage (Mouse)0xA1, 0x01,                     // Collection (Application)// Report ID 1: Mouse buttons + scroll/pan0x85, 0x01,       //     Report Id 10x09, 0x01,       //     Usage (Pointer)0xA1, 0x00,       //     Collection (Physical)0x95, 0x05,       //         Report Count (3)0x75, 0x01,       //         Report Size (1)0x05, 0x09,       //         Usage Page (Buttons)0x19, 0x01,       //             Usage Minimum (01)0x29, 0x05,       //             Usage Maximum (05)0x15, 0x00,       //             Logical Minimum (0)0x25, 0x01,       //             Logical Maximum (1)0x81, 0x02,       //             Input (Data, Variable, Absolute)0x95, 0x01,       //             Report Count (1)0x75, 0x03,       //             Report Size (3)0x81, 0x01,       //             Input (Constant) for padding0x75, 0x08,       //             Report Size (8)0x95, 0x01,       //             Report Count (1)0x05, 0x01,       //         Usage Page (Generic Desktop)0x09, 0x38,       //             Usage (Wheel)0x15, 0x81,       //             Logical Minimum (-127)0x25, 0x7F,       //             Logical Maximum (127)0x81, 0x06,       //             Input (Data, Variable, Relative)0x05, 0x0C,       //         Usage Page (Consumer)0x0A, 0x38, 0x02, //             Usage (AC Pan)0x95, 0x01,       //             Report Count (1)0x81, 0x06,       //             Input (Data,Value,Relative,Bit Field)0xC0,             //     End Collection (Physical)// Report ID 2: Mouse motion0x85, 0x02,       //     Report Id 20x09, 0x01,       //     Usage (Pointer)0xA1, 0x00,       //     Collection (Physical)0x75, 0x0C,       //         Report Size (12)0x95, 0x02,       //         Report Count (2)0x05, 0x01,       //         Usage Page (Generic Desktop)0x09, 0x30,       //             Usage (X)0x09, 0x31,       //             Usage (Y)0x16, 0x01, 0xF8, //             Logical maximum (2047)0x26, 0xFF, 0x07, //             Logical minimum (-2047)0x81, 0x06,       //             Input (Data, Variable, Relative)0xC0,             //     End Collection (Physical)0xC0,             // End Collection (Application)// Report ID 3: Advanced buttons0x05, 0x0C,       // Usage Page (Consumer)0x09, 0x01,       // Usage (Consumer Control)0xA1, 0x01,       // Collection (Application)0x85, 0x03,       //     Report Id (3)0x15, 0x00,       //     Logical minimum (0)0x25, 0x01,       //     Logical maximum (1)0x75, 0x01,       //     Report Size (1)0x95, 0x01,       //     Report Count (1)0x09, 0xCD,       //     Usage (Play/Pause)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x0A, 0x83, 0x01, //     Usage (AL Consumer Control Configuration)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x09, 0xB5,       //     Usage (Scan Next Track)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x09, 0xB6,       //     Usage (Scan Previous Track)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x09, 0xEA,       //     Usage (Volume Down)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x09, 0xE9,       //     Usage (Volume Up)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x0A, 0x25, 0x02, //     Usage (AC Forward)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0x0A, 0x24, 0x02, //     Usage (AC Back)0x81, 0x06,       //     Input (Data,Value,Relative,Bit Field)0xC0              // End Collection};memset(inp_rep_array, 0, sizeof(inp_rep_array));// Initialize HID Service.p_input_report                      = &inp_rep_array[INPUT_REP_BUTTONS_INDEX];p_input_report->max_len             = INPUT_REP_BUTTONS_LEN;p_input_report->rep_ref.report_id   = INPUT_REP_REF_BUTTONS_ID;p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);p_input_report                      = &inp_rep_array[INPUT_REP_MOVEMENT_INDEX];p_input_report->max_len             = INPUT_REP_MOVEMENT_LEN;p_input_report->rep_ref.report_id   = INPUT_REP_REF_MOVEMENT_ID;p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);p_input_report                      = &inp_rep_array[INPUT_REP_MPLAYER_INDEX];p_input_report->max_len             = INPUT_REP_MEDIA_PLAYER_LEN;p_input_report->rep_ref.report_id   = INPUT_REP_REF_MPLAYER_ID;p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);hid_info_flags = HID_INFO_FLAG_REMOTE_WAKE_MSK | HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK;memset(&hids_init_obj, 0, sizeof(hids_init_obj));hids_init_obj.evt_handler                    = on_hids_evt;hids_init_obj.error_handler                  = NULL;hids_init_obj.is_kb                          = false;hids_init_obj.is_mouse                       = true;hids_init_obj.inp_rep_count                  = INPUT_REPORT_COUNT;hids_init_obj.p_inp_rep_array                = inp_rep_array;hids_init_obj.outp_rep_count                 = 0;hids_init_obj.p_outp_rep_array               = NULL;hids_init_obj.feature_rep_count              = 0;hids_init_obj.p_feature_rep_array            = NULL;hids_init_obj.rep_map.data_len               = sizeof(rep_map_data);hids_init_obj.rep_map.p_data                 = rep_map_data;hids_init_obj.hid_information.bcd_hid        = BASE_USB_HID_SPEC_VERSION;hids_init_obj.hid_information.b_country_code = 0;hids_init_obj.hid_information.flags          = hid_info_flags;hids_init_obj.included_services_count        = 0;hids_init_obj.p_included_services_array      = NULL;BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.rep_map.security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.rep_map.security_mode.write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.hid_information.security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.hid_information.security_mode.write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.cccd_write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_protocol.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_protocol.write_perm);BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.security_mode_ctrl_point.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_ctrl_point.write_perm);err_code = ble_hids_init(&m_hids, &hids_init_obj);APP_ERROR_CHECK(err_code);
}

3.ble_evt_dispatch内添加

 dm_ble_evt_handler(p_ble_evt);
ble_hids_on_ble_evt(&m_hids, p_ble_evt);

4.sys_evt_dispatch内添加

pstorage_sys_event_handler(sys_evt);

5.添加UUID

static ble_uuid_t                       m_adv_uuids[] = {{BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE, BLE_UUID_TYPE_BLE}																											}; 

6.增加发送音量函数

void media_player_control(uint8_t control)
{uint32_t err_code;uint8_t buffer[1];buffer[0] = control;err_code = ble_hids_inp_rep_send( &m_hids,INPUT_REP_MPLAYER_INDEX,1,buffer );if(( err_code != NRF_SUCCESS ) &&( err_code != NRF_ERROR_INVALID_STATE ) &&( err_code != BLE_ERROR_NO_TX_PACKETS ) &&( err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING )){NRF_LOG_PRINTF("-step1error-");APP_ERROR_HANDLER( err_code );}buffer[0] = 0;err_code = ble_hids_inp_rep_send( &m_hids,INPUT_REP_MPLAYER_INDEX,1,buffer );if(( err_code != NRF_SUCCESS ) &&( err_code != NRF_ERROR_INVALID_STATE ) &&( err_code != BLE_ERROR_NO_TX_PACKETS ) &&( err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING )){NRF_LOG_PRINTF("-step-2-error-\r\n");APP_ERROR_HANDLER( err_code );}}

这里兼容IOS和Android,触发了2次发送

7.device_manager_cnfg.h修改CCCD连接数

#define DM_GATT_CCCD_COUNT               6

8.可能的问题和解决方法

 

1.连接了一台设备,断开他后其他设备搜不到设备的广播。

办法:device_manager_init(0);DEVICE_MANAGER_MAX_CONNECTIONS改大;DEVICE_MANAGER_MAX_BONDS改大。

2.手机系统拒绝配对。

办法:on_ble_evt函数内将BLE_GAP_EVT_SEC_PARAMS_REQUEST下的内容全部注释掉

3.每次正常使用都需要重新配对。

办法:CCCD设置太少,DM_GATT_CCCD_COUNT改大

4.程序下到板子后一直重启。办法:

1.注意SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);是否多次使用

2.步骤5.添加UUID时注意内容,有时候添加多个UUID会死机

3.注意gap_params_init();设置

4.services_init();和advertising_init();的先后顺序

感谢这些哥们:

https://blog.csdn.net/sinat_20059415/article/details/80777813 

https://blog.csdn.net/pig10086/article/details/72402066

https://blog.csdn.net/everestzhang/article/details/47165417

https://blog.csdn.net/gyb510/article/details/70188616

https://blog.csdn.net/weixin_40204595/article/details/81179361

 

 

这篇关于nordic 52832添加HID服务实现手机蓝牙自拍杆功能 附遇到的问题和解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335372

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施: