MicroPythonBLEHID使用说明——蓝牙鼠标

news2024/11/13 16:12:00

以下是源码地址 

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

 

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

本篇主要讲解mouse类使用

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 鼠标设备。例如,可以将该代码与物理按键结合,实现自制蓝牙遥控鼠标设备。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

斯坦福泡茶机器人DexCap源码解析:涵盖收集数据、处理数据、模型训练三大阶段

前言 因为我司「七月在线」关于dexcap的复现/优化接近尾声了(每月逐步提高复现的效果)&#xff0c;故准备把dexcap的源码也分析下&#xff0c;11月​下旬则分析下iDP3的源码——为队伍「iDP3人形的复现/优化」助力 最开始&#xff0c;dexcap的源码分析属于此文《DexCap——斯…

【软件工程】ATAM架构权衡评估方法

ATAM架构权衡评估方法 概述质量属性有哪些&#xff1f;质量属性的效用树怎么构建&#xff1f;如何确定质量属性的优先级&#xff1f; 概述 ATAM&#xff08;Architecture Tradeoff Analysis Method&#xff09;是一种系统架构评估方法&#xff0c;由卡梅隆大学软件工程协会提出…

BPMNJS设计器开发核心功能分析

系统功能 在开发一个前端工作流设计器&#xff0c;尤其是基于BPMN&#xff08;业务流程建模与标注&#xff09;或类似于钉钉的设计器时&#xff0c;主要需求可以总结为以下几个关键点&#xff1a; 1. 流程节点与边的设计 节点类型多样化&#xff1a;支持基础节点&#xff08…

快递100 物流查询API全面解析

一.基础准备 1.物流查询痛点 如何通过物流单号实时查询物流信息?如何实时查看物流地图轨迹? 使用快递 100&#xff0c;用户可以通过简单地输入快递单号来获取快递的详细物流状态&#xff0c;不仅能看到包裹目前的位置信息&#xff0c;还可以了解它的运输进展。 快递 100API…

多角度审视推荐系统

参考自《深度学习推荐系统》——王喆&#xff0c;用于学习和记录 介绍 推荐工程师需要从不同的维度审视推荐系统&#xff0c;不仅抓住问题的核心&#xff0c;更要从整体上思考推荐问题。 具体包括以下内容&#xff1a; &#xff08;1&#xff09;推荐系统如何选取和处理特征…

网络自动化04:python实现ACL匹配信息(主机与主机信息)

目录 背景分析代码代码解读代码总体结构1. load_pattern_from_excel 函数2. match_and_append_pattern 函数3. main 函数总结 最终的效果&#xff1a; 今天不分享netmiko&#xff0c;今天分享一个用python提升工作效率的小案例&#xff1a;acl梳理时的信息匹配。 背景 最近同事…

如何查看电脑关机时间

要查看电脑的关机时间&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 打开事件查看器&#xff1a;按下键盘上的Windows键R键&#xff0c;然后在弹出的运行对话框中输入"eventvwr.msc"&#xff0c;并按下Enter键。 2. 在事件查看器窗口中&#xff0c;单击左侧窗…

3DTiles之i3dm介绍

3DTiles之i3dm介绍 3D Tiles 是一种用于高效存储和传输三维城市、建筑、地形、点云等空间数据的开放标准格式。i3dm&#xff08;Intel 3D Model&#xff09;是 3D Tiles 中用于表示三维模型&#xff08;如建筑物或其他对象&#xff09;的一个子格式。i3dm 格式的出现&#xff…

Java | Leetcode Java题解之第559题N叉树的最大深度

题目&#xff1a; 题解&#xff1a; class Solution {public int maxDepth(Node root) {if (root null) {return 0;}Queue<Node> queue new LinkedList<Node>();queue.offer(root);int ans 0;while (!queue.isEmpty()) {int size queue.size();while (size &g…

【机器学习入门】(1) 线性回归算法

学习目标&#xff1a; 线性回归是一种基本的统计学习方法&#xff0c;主要用于分析一个或多个自变量与因变量之间的线性关系。以下是关于线性回归的一些关键点&#xff1a;线性回归的四要素&#xff1a; &#xff08;1&#xff09;假设(hypothesis)&#xff1b;&#xff08;2&…

视频会议接入GB28181视频指挥调度,语音对讲方案

传统的视频会议指挥调度系统目前主流的互联网会议大部分都是私有协议&#xff0c;功能都很独立。目前主流的视频监控国标都最GB平台&#xff0c;新的需求要求融合平台要接入监控等设备&#xff0c;并能实现观看监控接入会议&#xff0c;实时语音设备指挥现场工作人员办公实施。…

一文1800字使用Jmeter进行http接口性能测试!

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 为什么要做接口测试&#xff1f; 越底层发现b…

搭建监控系统Prometheus + Grafana

公司有个技术分享会&#xff0c;但是业务忙&#xff0c;没时间精心准备&#xff0c;所以就匆匆忙忙准备分享一下搭建&#xff08;捂脸哭&#xff09;。技术含量确实不多&#xff0c;但是分享的知识确实没问题。 以下是搭建过程&#xff1a; 一、讲解 Prometheus Prometheus 最…

ArkTS中的自定义构建函数、Tab栏和组件状态共享

一、自定义构建函数 1.构建函数 Builder 1.1 介绍 文档地址&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5?catalogVersionV5 概念&#xff1a;ArkUI提供了一种轻量的UI元素复用机制Builder&#xff0c;可以将重复使用的U…

二维、三维情况下的锚点优选方法

多锚点定位时&#xff0c;锚点的选择对定位精度有重要影响。下面介绍基于误差最小化的锚点选择的相应公式和MATLAB代码示例&#xff0c;并进行详细分析 文章目录 方法描述代码MATLAB代码示例代码运行结果 总结 方法描述 选择能够最小化定位误差的锚点组合。通过计算锚点位置与…

CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳

2024年11月9日至10日&#xff0c;以“湾区聚力 开源启智”为主题的2024年中国计算机学会中国开源大会&#xff08;CCF ChinaOSC&#xff09;将在深圳召开。大会将汇聚国内外学术界、顶尖科技企业、科研机构及开源社区的精英力量&#xff0c;共同探索人工智能技术和人类智慧的无…

力扣102:二叉树的层次遍历

给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&#xff1a; 输入&a…

数学建模模型算法-Python实现

一、评价决策类 1、层次分析法&#xff08;AHP&#xff09; 层次分析法用来评价或选择一个更好更优的决策或方案 通过找到可以衡量其好坏的指标&#xff0c;进而衡量指标&#xff0c;再形成评价体系 归一化处理 让指标在同一数量级&#xff0c;且保证在同一指标下其差距保持…

linux-vlan(1)

# VLAN # 1.topo # 2.创建命名空间 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns1-veth0 type veth peer name ns21-veth0 ip link add ns3-veth0 type veth peer name ns23-veth0 # 4.veth设备放入命名空间,启动接口 ip link set n…

spring cloud 入门笔记1(RestTemplate,Consul)

最大感受&#xff1a; spring cloud无非是将spring boot中的各个工作模块拆分成独立的小spring boot&#xff0c;各个模块之间&#xff0c;不再是通过导包什么的&#xff0c;调用而是通过网路进行各个模块之间的调用 工具一&#xff1a;RestTemplate 在Java代码中发送HTTP请…