MicroPythonBLEHID使用说明——蓝牙鼠标

以下是源码地址 

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙动画开发06——打断动画

1、前 言 UI界面除了运行动画之外&#xff0c;还承载着与用户进行实时交互的功能。当用户行为根据意图变化发生改变时&#xff0c;UI界面应做到即时响应。 例如用户在应用启动过程中&#xff0c;上滑退出&#xff0c;那么启动动画应该立即过渡到退出动画&#xff0c;而不应该…

运算放大器的学习(一)输入阻抗

输入阻抗 最近需要对运算放大器进行学习&#xff0c;我们后面逐一对其参数进行了解。 首先了解下输入阻抗。 放大电路技术指标测试示意图&#xff1a; 输入电阻&#xff1a; 从放大电路的输入端看进去的等效电阻称为放大电路的输入电阻&#xff0c;如上图&#xff0c;此处考虑…

【测试框架篇】单元测试框架pytest(1):环境安装和配置

一、pytest简介 Pytest是Python的一种单元测试框架&#xff0c;与Python自带的unittest测试框架类似&#xff0c;但是比 unittest框架使用起来更简洁&#xff0c;效率更高。 二、pytest特点 Pytest是一个非常成熟的Python测试框架,主要特点有以下几点&#xff1a; 非常容易…

蓝桥杯竞赛单片机组备赛【经验帖】

本人获奖情况说明 笔者本人曾参加过两次蓝桥杯电子赛&#xff0c;在第十二届蓝桥杯大赛单片机设计与开发组获得省级一等奖和国家级二等奖&#xff0c;在第十五届嵌入式设计开发组获得省级二等奖。如果跟着本帖的流程备赛&#xff0c;只要认真勤奋&#xff0c;拿个省二绝对没问…

力扣 LeetCode 541. 反转字符串II(Day4:字符串)

解题思路&#xff1a; i可以成段成段的跳&#xff0c;而不是简单的i class Solution {public String reverseStr(String s, int k) {char[] ch s.toCharArray();// 1. 每隔 2k 个字符的前 k 个字符进行反转for (int i 0; i < ch.length; i 2 * k) {// 2. 剩余字符小于 …

密码学知识点整理二:常见的加密算法

常用的加密算法包括对称加密算法、非对称加密算法和散列算法。 对称加密算法 AES&#xff1a;高级加密标准&#xff0c;是目前使用最广泛的对称加密算法之一&#xff0c;支持多种密钥长度&#xff08;128位、192位、256位&#xff09;&#xff0c;安全性高&#xff0c;加密效率…

css:修改盒子样式

圆角边框 在css3中新增了圆角边框样式&#xff0c;这样我们的盒子就可以长得奇形怪状了 像csdn上的发布就是圆角边框 还有这些 .x,.y {background-color: cornflowerblue;width: 200px;height: 200px;margin: 0 auto;text-align: center;border-radius: 10px;} 10px是什么意思…

连续九届EI稳定|江苏科技大学主办

【九届EI检索稳定|江苏科技大学主办 | IEEE出版 】 &#x1f388;【截稿倒计时】&#xff01;&#xff01;&#xff01; ✨徐秘书&#xff1a;gsra_huang ✨往届均已检索&#xff0c;已上线IEEE官网 &#x1f38a;第九届清洁能源与发电技术国际学术会议&#xff08;CEPGT 2…

机器学习 - 为 Jupyter Notebook 安装新的 Kernel

https://ipython.readthedocs.io/en/latest/install/kernel_install.html 当使用jupyter-notebook --no-browser 启动一个 notebook 时&#xff0c;默认使用了该 jupyter module 所在的 Python 环境作为 kernel&#xff0c;比如 C:\devel\Python\Python311。 如果&#xff0c…

DVWA靶场通关——SQL Injection篇

一&#xff0c;Low难度下unionget字符串select注入 1&#xff0c;首先手工注入判断是否存在SQL注入漏洞&#xff0c;输入1 这是正常回显的结果&#xff0c;再键入1 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for…

无人机飞手执照处处需要,森林、石油管道、电力巡检等各行业都需要

无人机飞手执照在多个行业中确实具有广泛的应用需求&#xff0c;包括森林、石油管道、电力巡检等领域。以下是对这些领域无人机飞手执照需求的具体分析&#xff1a; 一、森林领域 在森林领域&#xff0c;无人机飞手执照对于进行高效、准确的森林资源管理和监测至关重要。无人机…

基于YOLO11/v10/v8/v5深度学习的水面垃圾智能检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

家政服务小程序,家政行业数字化发展下的优势

今年以来&#xff0c;家政市场需求持续增长&#xff0c;市场规模达到了万亿级别&#xff0c;家政服务行业成为了热门行业之一&#xff01; 家政服务种类目前逐渐呈现了多样化&#xff0c;月嫂、保姆、做饭保洁、收纳、维修等家政种类不断出现&#xff0c;满足了居民日益增长的…

音视频入门基础:MPEG2-TS专题(3)——TS Header简介

注&#xff1a;本文有部分内容引用了维基百科&#xff1a;https://zh.wikipedia.org/wiki/MPEG2-TS 一、引言 本文对MPEG2-TS格式的TS Header进行简介。 进行简介之前&#xff0c;请各位先下载MPEG2-TS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-TS的官方文档。但是ITU提供的…

Spring Boot框架:构建符合工程认证的计算机课程

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

【ubuntu16.04】机器人学习笔记遇到的问题及解决办法:仿真小海龟

18版本的后面会出问题&#xff0c;避免万一我还是用了之前的16版本&#xff0c;虽然还没有解决粘贴的问题&#xff0c;但是安装ros很成功 可参考该文章博主讲的很详细&#xff0c;成功画出海龟 最后要把鼠标停在第三个终端&#xff0c;再去点击键盘&#xff0c;海龟才会动哦

Unity学习---IL2CPP打包时可能遇到的问题

写这篇主要是怕自己之后打包的时候出问题不知道怎么搞&#xff0c;所以记录一下。 问题一&#xff1a;类型裁剪 IL2CPP打包后会自动对Unity工程的dll进行裁剪&#xff0c;将代码中没有引用到的类型裁剪掉。特别是通过反射等方式调用一些类的时候&#xff0c;很容易出问题。 …

批量将MySQL中的MyISAM引擎,改成InnoDB引擎

一、InnoDB和MyISAM的区别 MySQL中InnoDB和MyISAM是两种常用的存储引擎&#xff0c;具有以下不同的特点&#xff1a; 序号InnoDBMyISAM说明事务支持支持不支持InnoDB可以处理更复杂的业务逻辑&#xff0c;而MyISAM在处理大量并发写入时可能会遇到问题‌锁定机制行级锁定表级锁…

认证鉴权框架SpringSecurity-1--概念和原理篇

1、基本概念 Spring Security 是一个强大且高度可定制的框架&#xff0c;用于构建安全的 Java 应用程序。它是 Spring 生态系统的一部分&#xff0c;提供了全面的安全解决方案&#xff0c;包括认证、授权、CSRF防护、会话管理等功能。 2、认证、授权和鉴权 &#xff08;1&am…

C++11新特性(二)

目录 一、C11的{} 1.初始化列表 2.initializer_list 二、可变参数模版 1.语法与原理 2.包扩展 3.empalce接口 三、新的类功能 四、lambda 1.语法 2.捕捉列表 3.原理 五、句装器 1.function 2.bind 一、C11的{} 1.初始化列表 C11以后想统⼀初始化⽅式&#xff0…