一、项目描述
1.1 硬件介绍
nRF7002-DK是用于nRF7002 Wi-Fi 6协同IC的开发套件,该开发套件采用nRF5340多协议片上系统作为nRF7002的主处理器,在单一的电路板上集成了一个SEGGER J-Link板载编程器/调试器,可让开发人员轻松开启基于nRF7002的物联网项目。
1.2 项目介绍
借着Funpack活动提供的机会,我准备体验下nRF7002-DK板卡的蓝牙连接功能,设计一个蓝牙鼠标键盘复合设备,使用按键1作为鼠标点击,按键2模拟键盘输入“eetree”字符;电脑开启大写锁定时,板卡的LED亮起。
1.3 设计思路
nRF Connect SDK是一个可扩展的统一软件开发套件,提供了基于蓝牙的HID键盘和鼠标例程。完成nRF Connect SDK的安装后,在VSCode安装nRF Connect for VS Code插件,即可在VSCode环境中一站式代码编辑、编译和烧录工作,简化操作流程。
nRF Connect SDK提供基于蓝牙的HID键盘或鼠标设备。选择nRF7002-DK的兼容板卡“nrf5340dk_nrf5340_cpuapp”后,点击“Build Configuration”完成配置。删除不必要NFC功能,在dts文件中调整按键和LED的引脚后,例程可以正常工作。
但是,如何将两个例程中的HID报告拼接在一起,实现一个HID复合设备,是一个困扰我的问题,反复尝试未能解决。我只好上网搜索解决方案,惊喜地在论坛上找到了解决方案:https://devzone.nordicsemi.com/f/nordic-q-a/101671/merging-keyboard-and-mouse-hid-descriptor-causing-no-space-left-on-given-svc-error。这篇博客的作者将两个例程的HID报告整合,并且建议增加CONFIG_BT_HIDS_ATTR_MAX参数避免报错。在此基础上,经过不少时间的调试后,电脑成功识别板卡的键盘鼠标复合设备。
二、主要代码说明
注意更改设备树。nRF7002-dk的管脚与nRF5340-dk有所不同。
采用那篇博客的HID报告,经过长时间调试,发现对代码应当作出额外的修改,否则键鼠复合设备不能正常使用。
BT_HIDS_DEF(hids_obj,
OUTPUT_REPORT_MAX_LEN,
INPUT_REPORT_KEYS_MAX_LEN,
INPUT_REP_BUTTONS_LEN,
INPUT_REP_MOVEMENT_LEN,
INPUT_REP_MEDIA_PLAYER_LEN);
模拟鼠标点击。基本参照例程。
static void mouse_movement_send(bool click, bool press)
{
//uint8_t buffer2[]={0x02,0x02,0x02};
uint8_t buffer2[]={0x01,0x01,0x01};
if(click){
buffer2[0]=0x01;buffer2[1]=0x000;buffer2[2]=0x00;
}
else{
buffer2[0]=0x00;buffer2[1]=0x00;buffer2[2]=0x00;
}
for (size_t i = 0; i < CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
if (!conn_mode[i].conn) {
continue;
}
if (conn_mode[i].in_boot_mode) {
bt_hids_boot_mouse_inp_rep_send(&hids_obj,
conn_mode[i].conn,
NULL,
(int8_t) 0,
(int8_t) 0,
NULL);
} else {
bt_hids_inp_rep_send(&hids_obj, conn_mode[i].conn,
1,
buffer2, sizeof(buffer2), NULL);
if(press)
printk("Button 1 has been pressed.\n");
}
}
}
static void button_shift_changed(bool down)
{
if (down) {
mouse_movement_send(1,1);
}else {
mouse_movement_send(0,0);
}
}
模拟键盘输入。基本参照例程。
static int hid_buttons_press(const uint8_t *keys, size_t cnt)
{
while (cnt--) {
int err;
err = hid_kbd_state_key_set(*keys++);
if (err) {
printk("Cannot set selected key.\n");
return err;
}
}
return key_report_send();
}
/** @brief Release the button and send report
*
* @note Functions to manipulate hid state are not reentrant
* @param keys
* @param cnt
*
* @return 0 on success or negative error code.
*/
static int hid_buttons_release(const uint8_t *keys, size_t cnt)
{
while (cnt--) {
int err;
err = hid_kbd_state_key_clear(*keys++);
if (err) {
printk("Cannot clear selected key.\n");
return err;
}
}
return key_report_send();
}
static void button_text_changed(bool down)
{
static const uint8_t *chr = hello_world_str;
if (down) {
printk("Button 2 has been pressed.\n");
while(1){
hid_buttons_press(chr, 1);
k_sleep(K_MSEC(1));
hid_buttons_release(chr, 1);
k_sleep(K_MSEC(1));
if (++chr == (hello_world_str + sizeof(hello_world_str))) {
chr = hello_world_str;
break;
}
}
}
}
三、功能展示
详细内容请看页面上方的视频。
电脑打开大写锁定,开发板LED亮起。
按下按键1,作为蓝牙鼠标按下左键,松开按键1后松开鼠标左键。
按下按键2,作为蓝牙键盘输入指定字符串“eetree”。
四、心得体会
nRF7200-DK自带调试器,无需额外连接调试器;nRF Connect SDK结合VSCode插件,在Windows系统一站式从例程资源创建新工程、编辑代码、编译程序和烧录下载。nRF7002-DK的开发环境易于使用、体验良好。由于精力有限,尚未用到nRF7002芯片的Wi-Fi能力,希望在未来进行体验。
备注:开发环境安装说明
我仔细看了下群里的讨论,我认为在Linux下安装nRF Connect SDK操作复杂,所以用Windows平台进行开发工作。我安装了“nrfconnect-setup-4.1.2-x64.exe”和“nrf-command-line-tools-10.23.0-x64.exe”,随后在nRF Connect for Desktop中安装Programmer,由Toolchain Manager安装SDK v2.4.1。如果VSCode编译报错,有一定可能是SDK下载不全,需要再次重复SDK安装步骤。