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 bits0x95, 0x01,                                                                                                 #         Report Count(1)0x75, 0x05,                                                                                                 #         Report Size(5)0x81, 0x03,                                                                                                 #         Input(Constant);                 5 bit padding0x05, 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_COLLECTION0xc0                                                                                                        # END_COLLECTION])# fmt: on# 初始化鼠标的 X、Y 坐标、滚轮状态(w)和三个按钮的状态。self.x = 0self.y = 0self.w = 0self.button1 = 0self.button2 = 0self.button3 = 0self.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 * 4state = 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.button3state = 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 = 127elif x < -127:x = -127if y > 127:y = 127elif y < -127:y = -127self.x = xself.y = y# 设置滚轮def set_wheel(self, w=0):if w > 127:w = 127elif w < -127:w = -127self.w = w# 设置按钮def set_buttons(self, b1=0, b2=0, b3=0): # 更新按钮状态:设置三个按钮的状态(0 表示未按下,1 表示按下)self.button1 = b1self.button2 = b2self.button3 = b3

总结

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

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

应用场景

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW 实现 find_nearest_neighbors 功能(二维平面上的最近邻查找)

1. 背景介绍 在数据分析和图像处理领域&#xff0c;经常需要查找给定点的最近邻居点。在LabVIEW中&#xff0c;计算二维平面上多个点之间的欧氏距离&#xff0c;并返回距离最近的几个点是一种常见操作。find_nearest_neighbors 函数用于实现这个功能。 2. 欧氏距离计算 在二维…

后端:Aop 面向切面编程

文章目录 1. Aop 初步学习面向切面编程&#xff0c;EnableAspectJAutoProxy2. AOP的核心概念3. 前置通知&#xff08;Before&#xff09;4. 后置通知&#xff08;After&#xff09;5. 返回通知&#xff08;AfterReturning&#xff09;6. 异常通知&#xff08;AfterThrowing&…

无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、Mp3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

管家婆财贸ERP BB045.销售批量收款

最低适用版本: 财贸系列 22.8 插件简要功能说明: 销售类单据支持批量收款,简化收款做单流程更多细节描述见下方详细文档插件操作视频: 进销存类定制插件--销售批量收款 插件详细功能文档: 1. 应用中心增加菜单【销售批量收款】 a. 参考23.0应用中心-移动管理-物联宝-【…

基于MATLAB+opencv人脸疲劳检测

我们可以通过多种方式从现实世界中获取数字图像&#xff0c;比如&#xff1a;数码相机、扫描仪、计算机扫描和磁共振成像等等。在这些情况中&#xff0c;虽然我们肉眼看到的是图像&#xff0c;但是当需要将图像在数字设备中变换传输时&#xff0c;图像的每个像素则对应一个数值…

Prompt 工程

Prompt 工程 1. Prompt 工程简介 “预训练-提示预测”范式是近年来自然语言处理&#xff08;NLP&#xff09;领域的一个重要趋势&#xff0c;它与传统的“预训练-微调-预测”范式相比&#xff0c;提供了一种更为灵活和高效的模型应用方式。 Prompt工程是指在预训练的大型语言…

【Python TensorFlow】进阶指南(续篇一)

在前两篇文章中&#xff0c;我们介绍了TensorFlow的基础知识及其在实际应用中的初步使用&#xff0c;并探讨了更高级的功能和技术细节。本篇将继续深入探讨TensorFlow的高级应用&#xff0c;包括但不限于模型压缩、模型融合、迁移学习、强化学习等领域&#xff0c;帮助读者进一…

yolov7论文翻译

YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors 论文&#xff1a;https://arxiv.org/abs/2207.02696 代码&#xff1a;https://github.com/WongKinYiu/yolov7 摘要 YOLOv7 在速度和准确性方面均超越了所有已知的目标检测器&a…

Java基于SpringBoot+Vue的宠物共享平台的设计与实现(附源码,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

对称加密与非对称加密:密码学的基石及 RSA 算法详解

对称加密与非对称加密&#xff1a;密码学的基石及 RSA 算法详解 在当今数字化的时代&#xff0c;信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术&#xff0c;为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…

43.第二阶段x86游戏实战2-提取游戏里面的lua

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

基于matlab的CNN食物识别分类系统,matlab深度学习分类,训练+数据集+界面

文章目录 前言&#x1f393;一、数据集准备&#x1f393;二、模型训练&#x1f340;&#x1f340;1.初始化&#x1f340;&#x1f340;2.加载数据集&#x1f340;&#x1f340;3.划分数据集&#xff0c;并保存到新的文件夹&#x1f340;&#x1f340;4.可视化数据集&#x1f34…

【webrtc】 RTP 中的 MID(Media Stream Identifier)

RTP 中的 MID(Media Stream Identifier) RID及其与MID的区别 cname与mid的对比【webrtc】CNAME 是rtprtcp中的Canonical Name(规范化名称) 同样都是RTP头部扩展: 基于mediasoup的最新的代码,学习,发现mid在创建RtpSendStream时是必须传递的参数: 例如 D:\XTRANS\soup\…

Node.Js+Knex+MySQL增删改查的简单示例(Typescript)

数据库: CREATE DATABASE MyDB; CREATE TABLE t_users (user_id int(11) NOT NULL,user_name varchar(10) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8; 项目结构: package.json如下&#xff0c;拷贝并替换你们本地的package.json后运行 npm install 命令安装所需要的依赖。…

【MATLAB代码】二维平面上的TDOA,使用加权最小二乘法,不限制锚点数量,代码可复制粘贴

本文所述的MATLAB代码实现了一个基于两步加权最小二乘法的二维目标定位算法,利用多个锚点(基站)和时间差到达(TDOA)数据来估计未知目标的位置。 订阅专栏后可以看到完整代码,复制到MATLAB空脚本上面即可直接运行。若需要单独下载,可通过下面的链接:https://download.cs…

python数据写入excel文件

主要思路&#xff1a;数据 转DataFrame后写入excel文件 一、数据格式为字典形式1 k e &#xff0c; v [‘1’, ‘e’, 0.83, 437, 0.6, 0.8, 0.9, ‘好’] 1、这种方法使用了 from_dict 方法&#xff0c;指定了 orient‘index’ 表示使用字典的键作为行索引&#xff0c;然…

【深度学习】LSTM、BiLSTM详解

文章目录 1. LSTM简介&#xff1a;2. LSTM结构图&#xff1a;3. 单层LSTM详解4. 双层LSTM详解5. BiLSTM6. Pytorch实现LSTM示例7. nn.LSTM参数详解 1. LSTM简介&#xff1a; LSTM是一种循环神经网络&#xff0c;它可以处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM通…

使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径

在进行WPF开发时&#xff0c;System.Windows.Forms.FolderBrowserDialog的选择文件夹功能不支持输入路径&#xff1a; 希望能够获得下图所示的选择文件夹功能&#xff1a; 于是&#xff0c;通过NuGet中安装Ookii.Dialogs.Wpf包&#xff0c;并创建一个简单的工具类&#xff1a; …

【leetcode练习·二叉树】用「分解问题」思维解题 II

本文参考labuladong算法笔记[【强化练习】用「分解问题」思维解题 II | labuladong 的算法笔记] 技巧一 类似于判断镜像二叉树、翻转二叉树的问题&#xff0c;一般也可以用分解问题的思路&#xff0c;无非就是把整棵树的问题&#xff08;原问题&#xff09;分解成子树之间的问…