MicroPythonBLEHID使用说明——蓝牙鼠标

以下是源码地址

GitCode - 全球开发者的开源社区,开源代码托管平台

GitHub - Heerkog/MicroPythonBLEHID: Human Interface Device (HID) over Bluetooth Low Energy (BLE) GATT library for MicroPython.

本篇主要讲解mouse类使用

python 复制代码
class Mouse(HumanInterfaceDevice):
    def __init__(self, name="Bluetooth Mouse"):
        super(Mouse, self).__init__(name)                                                                               # Set up the general HID services in super.
        self.device_appearance = 962                                                                                    # 962 是 HID 设备的外观 ID,代表鼠标

        self.HIDS = (                                                                                                   # Service description: describes the service and how we communicate.
            UUID(0x1812),                                                                                               # 0x1812 = Human Interface Device.
            (
                (UUID(0x2A4A), F_READ),                                                                                 # 0x2A4A = HID 信息特性(只读).
                (UUID(0x2A4B), F_READ),                                                                                 # 0x2A4B = HID 报告映射(只读).
                (UUID(0x2A4C), F_READ_WRITE_NORESPONSE),                                                                # 0x2A4C = HID 控制点(读/写).
                (UUID(0x2A4D), F_READ_NOTIFY, (                                                                         # 0x2A4D = HID 报告(读/通知).
                    (UUID(0x2902), ATT_F_READ_WRITE),                                                                   # 0x2902 = Client Characteristic Configuration.
                    (UUID(0x2908), ATT_F_READ_WRITE),                                                                   # 0x2908 = HID reference, to be read by client (allow write because MicroPython v1.20+ bug).
                )),
                (UUID(0x2A4E), F_READ_WRITE_NORESPONSE),                                                                # 0x2A4E = HID 协议模式(读/写).
            ),
        )

        # fmt: off
        # 描述 HID 输入报告:
        # 定义了鼠标输入报告的结构,包括鼠标按钮(3 个按钮)和 X、Y 轴的位移。
        # 使用字节码定义了鼠标的功能,如按钮输入、X 和 Y 轴的逻辑范围(-127 到 127)。
        self.HID_INPUT_REPORT = bytes([                                                                                 # Report Description: describes what we communicate.
            0x05, 0x01,                                                                                                 # USAGE_PAGE (Generic Desktop)
            0x09, 0x02,                                                                                                 # USAGE (Mouse)
            0xa1, 0x01,                                                                                                 # COLLECTION (Application)
            0x85, 0x01,                                                                                                 #   REPORT_ID (1)
            0x09, 0x01,                                                                                                 #   USAGE (Pointer)
            0xa1, 0x00,                                                                                                 #   COLLECTION (Physical)
            0x05, 0x09,                                                                                                 #         Usage Page (Buttons)
            0x19, 0x01,                                                                                                 #         Usage Minimum (1)
            0x29, 0x03,                                                                                                 #         Usage Maximum (3)
            0x15, 0x00,                                                                                                 #         Logical Minimum (0)
            0x25, 0x01,                                                                                                 #         Logical Maximum (1)
            0x95, 0x03,                                                                                                 #         Report Count (3)
            0x75, 0x01,                                                                                                 #         Report Size (1)
            0x81, 0x02,                                                                                                 #         Input(Data, Variable, Absolute); 3 button bits
            0x95, 0x01,                                                                                                 #         Report Count(1)
            0x75, 0x05,                                                                                                 #         Report Size(5)
            0x81, 0x03,                                                                                                 #         Input(Constant);                 5 bit padding
            0x05, 0x01,                                                                                                 #         Usage Page (Generic Desktop)
            0x09, 0x30,                                                                                                 #         Usage (X)
            0x09, 0x31,                                                                                                 #         Usage (Y)
            0x09, 0x38,                                                                                                 #         Usage (Wheel)
            0x15, 0x81,                                                                                                 #         Logical Minimum (-127)
            0x25, 0x7F,                                                                                                 #         Logical Maximum (127)
            0x75, 0x08,                                                                                                 #         Report Size (8)
            0x95, 0x03,                                                                                                 #         Report Count (3)
            0x81, 0x06,                                                                                                 #         Input(Data, Variable, Relative); 3 position bytes (X,Y,Wheel)
            0xc0,                                                                                                       #   END_COLLECTION
            0xc0                                                                                                        # END_COLLECTION
        ])
        # fmt: on

        # 初始化鼠标的 X、Y 坐标、滚轮状态(w)和三个按钮的状态。
        self.x = 0
        self.y = 0
        self.w = 0

        self.button1 = 0
        self.button2 = 0
        self.button3 = 0

        self.services = [self.DIS, self.BAS, self.HIDS]                                                                 # Override list of service descriptions.

    # Overwrite super to register HID specific service.
    def start(self):
        super(Mouse, self).start()                                                                                      # 注册服务:调用父类的 start 方法,注册设备信息(DIS)和电池信息(BAS)服务。

        print("Registering services")
        handles = self._ble.gatts_register_services(self.services)               #注册 HID 服务                         # Register services and get read/write handles for all services.
        self.write_service_characteristics(handles)                                                                     # Write the values for the characteristics.
        self.adv = Advertiser(self._ble, [UUID(0x1812)], self.device_appearance, self.device_name)                      # 创建广告对象 Advertiser,用于蓝牙广播. Only advertise the top level service, i.e., the HIDS.

        print("Server started")

    # Overwrite super to write HID specific characteristics.
    # 写入服务特性
    def write_service_characteristics(self, handles):
        super(Mouse, self).write_service_characteristics(handles)                                                       # Call super to write DIS and BAS characteristics.
                                                                                                                         
        (h_info, h_hid, h_ctrl, self.h_rep, _, h_d1, h_proto) = handles[2]                                              # 获取 HID 特性句柄(handles[2])并写入初始特性值. These correspond directly to self.HIDS. Position 2 because of the order of self.services.
        #  包括 HID 信息、HID 输入报告、HID 参考和 HID 协议模式。
        print("h_info =", h_info, "h_hid =", h_hid, "h_ctrl =", h_ctrl, "h_rep =", self.h_rep, "h_d1ref =", h_d1, "h_proto =", h_proto)

        b = self.button1 + self.button2 * 2 + self.button3 * 4
        state = struct.pack("Bbbb", b, self.x, self.y, self.w)                                                          # Pack the initial mouse state as described by the input report.

        print("Writing hid service characteristics")
        # Write service characteristics.
        self._ble.gatts_write(h_info, b"\x01\x01\x00\x02")                                                              # HID info: ver=1.1, country=0, flags=normal.
        self._ble.gatts_write(h_hid, self.HID_INPUT_REPORT)                                                             # HID input report map.
        self._ble.gatts_write(self.h_rep, state)                                                                        # HID report.
        self._ble.gatts_write(h_d1, struct.pack("<BB", 1, 1))                                                           # HID reference: id=1, type=input.
        self._ble.gatts_write(h_proto, b"\x01")                                                                         # HID protocol mode: report.

    # Overwrite super to notify central of a hid report
    #  通知 HID 报告
    def notify_hid_report(self):
        # 如果设备已连接,则调用 self._ble.gatts_notify 发送 HID 报告给连接的主设备
        if self.is_connected():
            b = self.button1 + self.button2 * 2 + self.button3
            state = struct.pack("Bbbb", b, self.x, self.y, self.w)                                                      # 将按钮状态(b)、X、Y 和滚轮状态(w)打包成字节
            self._ble.gatts_notify(self.conn_handle, self.h_rep, state)                                                 # Notify central by writing to the report handle.
            print("Notify with report: ", struct.unpack("Bbbb", state))

    # 设置鼠标轴坐标 
    def set_axes(self, x=0, y=0):
        if x > 127:
            x = 127
        elif x < -127:
            x = -127

        if y > 127:
            y = 127
        elif y < -127:
            y = -127

        self.x = x
        self.y = y

    # 设置滚轮
    def set_wheel(self, w=0):
        if w > 127:
            w = 127
        elif w < -127:
            w = -127

        self.w = w

    # 设置按钮
    def set_buttons(self, b1=0, b2=0, b3=0): # 更新按钮状态:设置三个按钮的状态(0 表示未按下,1 表示按下)
        self.button1 = b1
        self.button2 = b2
        self.button3 = b3

总结

这个 Mouse 类用于实现 BLE 蓝牙鼠标设备,并通过 BLE HID 协议与主设备(如手机、电脑等)通信。它能够:

  • 广播 BLE 服务,使主设备可以发现和连接。
  • 通过 BLE HID 报告发送鼠标的按键状态、坐标变化和滚轮滚动。
  • 支持鼠标按钮(最多三个)、X/Y 坐标位移和滚轮操作。

应用场景

这段代码可以应用在各种嵌入式设备中,特别是使用 ESP32 等支持 BLE 的开发板,实现一个无线 BLE 鼠标设备。例如,可以将该代码与物理按键结合,实现自制蓝牙遥控鼠标设备。

相关推荐
UI设计兰亭妙微17 小时前
中车株州所显示器界面设计
计算机外设·界面设计
墩墩冰18 小时前
计算机图形学 多视区的显示
计算机外设
墩墩冰19 小时前
计算机图形学 GLU库中的二次曲面函数
计算机外设
墩墩冰20 小时前
计算机图形学 利用鼠标实现橡皮筋技术
计算机外设
企鹅侠客3 天前
鼠标键盘按键统计工具
计算机外设·键盘·鼠标
华一精品Adreamer4 天前
便携式显示器供应链与成本结构:挑战与机遇
计算机外设
开开心心就好4 天前
图片校正漂白工具永久免费,矫正实时预览
网络·人工智能·windows·计算机视觉·计算机外设·电脑·excel
开开心心就好4 天前
免费批量抠图软件大模型,复杂倒影精准去除
网络·windows·pdf·计算机外设·电脑·硬件架构·材料工程
Jwest20216 天前
工业显示器在铁路智能充电柜中的应用
计算机外设
木梯子6 天前
罗技G系列游戏外设全解析及G304X入门游戏鼠标推荐
计算机外设·鼠标