4366|0

660

帖子

30

TA的资源

版主

楼主
 

当BLE遇上MEMS——HID例程介绍与DIY遥控手柄 [复制链接]

本帖最后由 lb8820265 于 2020-9-26 13:25 编辑

上一篇详细的介绍了HID的报告描述符和对应的例程,实际对于应用工程师来说没必要知道这么底层的东西,只需要知道如何正确的调用接口函数而达到效果即可。

例如我们就只需要发送上下左右四个方向键和Z、X两个字母即可。下面我们就从NRF的例程开始,先读懂例程然后修改部分代码达到我们的目标。

准备工作

NRF芯片开发板

为了更好的演示例程,我这里用了官方pca10056的开发板,芯片是NRF52840。

最好是用pca10040开发板,因为芯片是NRF52832,可是我没有。

官方开发板的好处就是四个按钮呈现遥控器四角形状,很像手柄方向键,如下图右下角的按钮:

SDK与softdevice

我使用的是15.3版本的SDK,不是最新的,其他的版本大同小异。

NRF52840芯片用的softdevice是s140_nrf52_6.1.1_softdevice.hex,

NRF52832要用s132_nrf52_6.1.1_softdevice.hex

这些都在nordicsemi官网下载:

https://www.nordicsemi.com/Software-and-tools/Software/nRF5-SDK/Download#infotabs

例程介绍

例程位置

nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_hids_keyboard

功能介绍

作用是使用蓝牙HID接口服务和电池服务,与HID相关的功能包括以下三个:

1. 按1按钮将会输模拟键盘,每按一次就会循环输入“hello”给连接设备;

2. 按2按钮不松,然后按1按钮就会依次循环输入大写的“HELLO”给连接设备;

3. 按电脑上的CapsLK按钮,开启大写锁定开发板上的LED3就会亮起,关闭就熄灭LED3。

下面来看看这三个功能分别在代码中对应的位置和代码。

第一个功能:循环输入“hello”给连接设备

在main.c文件中的bsp_event_handler函数中有如下代码:

        case BSP_EVENT_KEY_0:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
                keys_send(1, p_key);
                p_key++;
                size++;
                if (size == MAX_KEYS_IN_ONE_REPORT)
                {
                    p_key = m_sample_key_press_scan_str;
                    size  = 0;
                }
            }
            break;

代码很简单,一旦按下0按钮(开发板上的1按钮)就通过keys_send(1, p_key);函数循环发送m_sample_key_press_scan_str字符串中的字母。该字符串的内容如下,这些16进制的数就代表着字母,详细的字母表见上一篇帖子。

static uint8_t m_sample_key_press_scan_str[] = /**< Key pattern to be sent when the key press button has been pushed. */
{
    0x0b,       /* Key h */
    0x08,       /* Key e */
    0x0f,       /* Key l */
    0x0f,       /* Key l */
    0x12,       /* Key o */
    0x28        /* Key Return */
};

第二个功能:按下2按钮不松,然后按1按钮就会依次循环输入大写的“HELLO”给连接设备

这个功能实现起来其实挺简单的,就是相当于键盘上按下“Shift”的同时,按下字母,字母就变成了大写字母了。

还记得上一节介绍的报告描述符吗,发送的第一个字节的8个bit就是表示键盘上的8个功能按键,哪一bit置1,就相当于哪一个按键被按下。

实现该功能的核心代码在main.c文件中的send_key_scan_press_release函数,该函数是会被前面介绍的keys_send函数调用的。其中有如下代码:

        if (bsp_button_is_pressed(SHIFT_BUTTON_ID))
        {
            data[MODIFIER_KEY_POS] |= SHIFT_KEY_CODE;
        }

代码的含义就是每次发送数据前检测一下按键2是否被按下,如果被按下就将发送的第一个字节的第二位置1。这就代表按下了“Shift”键。然后再发送需要的键值。

第三个功能:按电脑上的CapsLK按钮,开启大写锁定开发板上的LED3就会亮起,关闭就熄灭LED3。

HID通信不单单只是单向的,也是可以双向的,还记得上一篇介绍报告描述符吗?其中有一个Usage Pg (LEDs)就是用来输出的,输出的是一个5bit的字节,用来控制LED灯。

在main.c文件中的on_hid_rep_char_write函数用来就是用来接收设备穿回来的信息,然后在函数中判断接收回来的信息类型来开关LED3。

DIY遥控手柄

这里来DIY一个可以控制方向的遥控器,实际上就是模拟键盘上的方向键。

1. 找到方向键的键值,可以从上一篇中查阅到。然后在bsp_event_handler函数中将代码修改为如下:     

case BSP_EVENT_KEY_0:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {  
              uint8_t  ch=82;//向上Key值
                keys_send(1,&ch);
            }
            break;
        case BSP_EVENT_KEY_1:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            { 
              uint8_t  ch=79;//向右Key值
                keys_send(1,&ch);
            }
            break;
        case BSP_EVENT_KEY_2:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
              uint8_t  ch=80;//向左Key值
              keys_send(1,&ch);
            }
            break;
        case BSP_EVENT_KEY_3:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
              uint8_t  ch=81;//向下Key值
                keys_send(1,&ch);
            }
            break;

代码非常简单就是一旦检测到某个按键被按下,就发送对应方向的键值过去。1按钮对应上,2按钮对应右,3按钮对应左,4按钮对应下。

2. 将send_key_scan_press_release函数中检测2按钮是否被按下的代码注释。

//        if (bsp_button_is_pressed(SHIFT_BUTTON_ID))
//        {
//            data[MODIFIER_KEY_POS] |= SHIFT_KEY_CODE;
//        }

好啦,这样一个简单的游戏手柄就做好了,可以用开发板上的上下左右四个按钮进行玩游戏了,是不是非常酷呢?

main.c源码详见附件,只改动了main.c文件,直接替换即可。

main.c

60.28 KB, 下载次数: 5

点赞 关注
个人签名QQ:252669569
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表