NRF52832初学笔记1.5之hids_keyboard

2023-10-13 18:50

本文主要是介绍NRF52832初学笔记1.5之hids_keyboard,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在搞一个锁的项目,使用NRF51822芯片。基本功能,就是手机端与锁第一次配对绑定以后,在手机端不取消配对的情况,每次手机靠近锁,BLE自动回连,然后开锁,锁与手机远离以后,断开连接,锁自动锁上。功能很简单,第一眼就想到使用hids服务,因为之前也没有用过,这里也是初学,把自己的心得体会分享一下,以便大家相互学习。
本次是在NRF52832的Demo板上测试的 ,使用的是SDK12.3的hids_keyboard 例程,这次主要讲流程。我们从主函数一步一步分析讲起。

1.0 配对管理初始化。
配对信息初始化,主要是对开关机以后,软件对之前是否存在绑定设备的信息校验和初始化。因为,如果之前存在绑定信息,在绑定回调里面,会将绑定信息和手机MAC 地址保存在芯片内部flash里面(再次之前,会加入白名单里面) 。如下图:
在这里插入图片描述
1.2 GAP 外观设置
在GAP 初始化里面,增加一个外观设置,这个就是我们使用手机蓝牙搜索时候,出现的键盘图标,没什么特别的东西,大家在使用其他东西时候,也可以通过这个函数进行更改自己的图标,
在这里插入图片描述
1.3 广播初始化
在广播初始化里面,增加了定向广播,这个目的就是为了断开连接(不是取消配对造成的断开)之后,回连手机的操作。
在这里插入图片描述
1.4服务初始化
服务初始化里面,增加了 HIDS的keyboard 初始化,这个里面,最重要的就是键盘配置表,也是最难得的,对于我这种菜鸡,目前还没整明白,不过,大家如果有时间,可以自己看看,这里介绍一款软件,可以帮助学习,软件名字叫做DT
链接:https://www.usb.org/sites/default/files/documents/dt2_4.zip
还有一个文档,就是这些USB HID 所遵循的协议,也是够难的,大家自己看 。有明白和知道的评论区分享出来。
链接:https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf

static void hids_init(void)
{uint32_t                   err_code;ble_hids_init_t            hids_init_obj;ble_hids_inp_rep_init_t    input_report_array[1];ble_hids_inp_rep_init_t  * p_input_report;ble_hids_outp_rep_init_t   output_report_array[1];ble_hids_outp_rep_init_t * p_output_report;uint8_t                    hid_info_flags;memset((void *)input_report_array, 0, sizeof(ble_hids_inp_rep_init_t));memset((void *)output_report_array, 0, sizeof(ble_hids_outp_rep_init_t));static uint8_t report_map_data[] ={0x05, 0x01,       // Usage Page (Generic Desktop)0x09, 0x06,       // Usage (Keyboard)0xA1, 0x01,       // Collection (Application)0x05, 0x07,       // Usage Page (Key Codes)0x19, 0xe0,       // Usage Minimum (224)0x29, 0xe7,       // Usage Maximum (231)0x15, 0x00,       // Logical Minimum (0)0x25, 0x01,       // Logical Maximum (1)0x75, 0x01,       // Report Size (1)0x95, 0x08,       // Report Count (8)0x81, 0x02,       // Input (Data, Variable, Absolute)0x95, 0x01,       // Report Count (1)0x75, 0x08,       // Report Size (8)0x81, 0x01,       // Input (Constant) reserved byte(1)0x95, 0x05,       // Report Count (5)0x75, 0x01,       // Report Size (1)0x05, 0x08,       // Usage Page (Page# for LEDs)0x19, 0x01,       // Usage Minimum (1)0x29, 0x05,       // Usage Maximum (5)0x91, 0x02,       // Output (Data, Variable, Absolute), Led report0x95, 0x01,       // Report Count (1)0x75, 0x03,       // Report Size (3)0x91, 0x01,       // Output (Data, Variable, Absolute), Led report padding0x95, 0x06,       // Report Count (6)0x75, 0x08,       // Report Size (8)0x15, 0x00,       // Logical Minimum (0)0x25, 0x65,       // Logical Maximum (101)0x05, 0x07,       // Usage Page (Key codes)0x19, 0x00,       // Usage Minimum (0)0x29, 0x65,       // Usage Maximum (101)0x81, 0x00,       // Input (Data, Array) Key array(6 bytes)0x09, 0x05,       // Usage (Vendor Defined)0x15, 0x00,       // Logical Minimum (0)0x26, 0xFF, 0x00, // Logical Maximum (255)0x75, 0x08,       // Report Count (2)0x95, 0x02,       // Report Size (8 bit)0xB1, 0x02,       // Feature (Data, Variable, Absolute)0xC0              // End Collection (Application)};// Initialize HID Servicep_input_report                      = &input_report_array[INPUT_REPORT_KEYS_INDEX];p_input_report->max_len             = INPUT_REPORT_KEYS_MAX_LEN;p_input_report->rep_ref.report_id   = INPUT_REP_REF_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_output_report                      = &output_report_array[OUTPUT_REPORT_INDEX];p_output_report->max_len             = OUTPUT_REPORT_MAX_LEN;p_output_report->rep_ref.report_id   = OUTPUT_REP_REF_ID;p_output_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_OUTPUT;BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_output_report->security_mode.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_output_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                  = service_error_handler;hids_init_obj.is_kb                          = true;hids_init_obj.is_mouse                       = false;hids_init_obj.inp_rep_count                  = 1;hids_init_obj.p_inp_rep_array                = input_report_array;hids_init_obj.outp_rep_count                 = 1;hids_init_obj.p_outp_rep_array               = output_report_array;hids_init_obj.feature_rep_count              = 0;hids_init_obj.p_feature_rep_array            = NULL;hids_init_obj.rep_map.data_len               = sizeof(report_map_data);hids_init_obj.rep_map.p_data                 = report_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_kb_inp_rep.cccd_write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_inp_rep.read_perm);BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.security_mode_boot_kb_inp_rep.write_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_outp_rep.read_perm);BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_outp_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);
}

1.5 广播开始
广播开始时,会进行白名单获取和设置绑定参数信息
在这里插入图片描述
在 ble_advertising_start 里面 ,最主要的就是下面两处,这两个地方直接决定了广播的模式是快速还是定向
在这里插入图片描述
我们来看一下定向广播里面的设置,是把手机的Mac地址赋值过去 ,就可以了 !不知道我的操作有问题,还是其他的原因,我把广播初始化直接设置成定向广播,然后强制修改成我自己的手机Mac地址,它是无法回连到我的手机上,必须经过一次配对绑定才行。

2.0绑定信息存储
在绑定管理会呆里面,最重要的两个事件 :
PM_EVT_BONDED_PEER_CONNECTED :连接上已经绑定的设备。(这个事件是在回连成功以后,触发的)
PM_EVT_CONN_SEC_SUCCEEDED : 连接到绑定设备。(这个是在第一次绑定触发的)
在这里插入图片描述
看一下PM_EVT_CONN_SEC_SUCCEEDED 里面的操作,就是判断绑定链接属性,然后满足判断,就把绑定的信息保存下来,当然,这里还有一些链接秘钥等信息。
2.2 广播回调事件
在on_adv_evt 里面,关注两个事件 :BLE_ADV_EVT_WHITELIST_REQUEST 和 BLE_ADV_EVT_PEER_ADDR_REQUEST
这两个回调事件基本功能就是把绑定信息读取出来,把手机mac地址赋值给m_peer_address,这两个事件的触发也是在ble_start里面触发的,在上面已经介绍过了。这里就是为了定向广播的数据赋值做准备的。
在这里插入图片描述
3.0 结束
到这里整个过程已近介绍完了 ,如果还想看keyboard 发送数据到手机端的 ,可以自己看一下bsp_event_handler 连的发送,其他不介绍,配对绑定的过程很复杂,先要有配对才行,绑定在一些情况下会出现。这个过程大家自己网络搜索资料 或者去nrf 官网看看 。
在这里插入图片描述我这边发现有两个问题!
1、Hids_keyboard 和 mousce 例程,使用过程中会使手机端出现自动打字和鼠标图案,想了很久也没解决掉,不知道其他的hid 服务 比如 :电子笔,扫描枪,游戏柄等是否可以。需要验证一下。这些例程官网上资料少,个人还没有去实践操作。
2、不管是Hids_keyboard 还是 mousce 例程,如果手机端和 ble进行了配对绑定成功,此时,把ble关闭,手机蓝牙取消配对。然后,在打开ble和手机蓝牙,虽然ble的log显示是进行的定向广播,但是,却无法回连。我手动去连接ble(不使用nrf connect 工具),也无法连接成功。这个地方不知道是不是一个 bug。

这篇关于NRF52832初学笔记1.5之hids_keyboard的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus