实现一个BLE HID鼠标

  • 这个程序将 ESP32 或类似设备变成了一个简单的蓝牙鼠标,通过 4 个 GPIO 引脚来控制鼠标的上下左右移动。
  • 连接到蓝牙后,按下相应的按键会发送 HID 鼠标移动事件。
  • 包含了一个简单的测试函数,用于验证鼠标的移动和点击功能。
python 复制代码
# MicroPython Human Interface Device library
# Copyright (C) 2021 H. Groefsema
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
python 复制代码
import time
from machine import SoftSPI, Pin
from hid_services import Mouse

class Device:
    def __init__(self):
        # 定义初始坐标
        self.x = 0 # 用于存储鼠标的 X 轴和 Y 轴移动量。
        self.y = 0

        self.prev_x = 0
        self.prev_y = 0

        # 定义按键引脚(GPIO)
        # 对应于鼠标的上、下、右、左移动,分别连接到 GPIO 引脚 5、23、19 和 18
        self.pin_forward = Pin(5, Pin.IN)
        self.pin_reverse = Pin(23, Pin.IN)
        self.pin_right = Pin(19, Pin.IN)
        self.pin_left = Pin(18, Pin.IN)

        # 创建鼠标设备实例
        self.mouse = Mouse("Mouse")
        # 设置状态变化回调函数 mouse_state_callback
        self.mouse.set_state_change_callback(self.mouse_state_callback)
        # 启动鼠标设备
        self.mouse.start()

    # Function that catches device status events
    # 鼠标状态回调函数,用于处理鼠标设备状态变化。可能会根据设备状态执行不同的操作。
    def mouse_state_callback(self):
        if self.mouse.get_state() is Mouse.DEVICE_IDLE: # 设备处于空闲状态
            return
        elif self.mouse.get_state() is Mouse.DEVICE_ADVERTISING: # 设备正在广播蓝牙信号,等待连接
            return 
        elif self.mouse.get_state() is Mouse.DEVICE_CONNECTED: # 设备已连接
            return
        else:
            return

    def advertise(self): #启动蓝牙广播,使设备可以被发现和连接
        self.mouse.start_advertising()

    def stop_advertise(self): #停止蓝牙广播
        self.mouse.stop_advertising()

    # Main loop
    def start(self):
        while True:
            # 根据按键状态计算 x 和 y 的变化量
            # 右键按下 (pin_right.value() == 1) 时,x = 127,表示向右移动最大速度
            self.x = self.pin_right.value() * 127 - self.pin_left.value() * 127
            self.y = self.pin_forward.value() * 127 - self.pin_reverse.value() * 127

            # 如果检测到坐标发生变化且鼠标设备已连接,则发送 HID 报告,通知移动更新。
            # 检查是否发生变化
            if (self.x != self.prev_x) or (self.y != self.prev_y):
                # 更新上一次的坐标值
                self.prev_x = self.x
                self.prev_y = self.y

                # 如果鼠标已连接,更新坐标并通知
                # If idle start advertising for 30s or until connected
                if self.mouse.get_state() is Mouse.DEVICE_CONNECTED:
                    self.mouse.set_axes(self.x, self.y)
                    self.mouse.notify_hid_report()
                # 如果设备处于空闲状态,则开始广播
                elif self.mouse.get_state() is Mouse.DEVICE_IDLE:
                    self.mouse.start_advertising()
                    i = 10
                    while i > 0 and self.mouse.get_state() is Mouse.DEVICE_ADVERTISING:
                        time.sleep(3)
                        i -= 1
                    if self.mouse.get_state() is Mouse.DEVICE_ADVERTISING:
                        self.mouse.stop_advertising()

             # 如果鼠标已连接,休眠 20ms 后退出循环,进行测试
            if self.mouse.get_state() is Mouse.DEVICE_CONNECTED:
                time.sleep_ms(20)
                break
            else:
                time.sleep(2)
        self.test()
    # 停止设备
    def stop(self):
        self.mouse.stop()

    # Test routine
    def test(self):
        self.mouse.set_battery_level(50)
        self.mouse.notify_battery_level()

        for i in range(30):
            self.mouse.set_axes(100,100) # 向右上移动 (100, 100) 并按下左键
            self.mouse.set_buttons(1)
            self.mouse.notify_hid_report()
            time.sleep_ms(500)

            self.mouse.set_axes(100,-100) # 向右下移动 (100, -100) 释放按键
            self.mouse.set_buttons()
            self.mouse.notify_hid_report()
            time.sleep_ms(500)

            self.mouse.set_axes(-100,-100) # 向左下移动 (-100, -100) 并按下右键
            self.mouse.set_buttons(b2=1)
            self.mouse.notify_hid_report()
            time.sleep_ms(500)

            self.mouse.set_axes(-100,100) # 向左上移动 (-100, 100) 释放按键
            self.mouse.set_buttons()
            self.mouse.notify_hid_report()
            time.sleep_ms(500)

        self.mouse.set_axes(0,0) # 最后将鼠标位置重置为 (0, 0),并模拟将电池电量更新为 100%
        self.mouse.set_buttons()
        self.mouse.notify_hid_report()

        self.mouse.set_battery_level(100) # 设置电池电量(模拟电池状态
        self.mouse.notify_battery_level()

if __name__ == "__main__":
    # 创建 Device 实例并启动主循环,等待蓝牙连接和处理按键输入。
    d = Device()
    d.start()

你可以通过修改 pin_forwardpin_reversepin_rightpin_left 引脚编号,来匹配你的硬件设置,并根据需要调整鼠标移动的速度(例如更改 127 的值)。

相关推荐
春日见1 天前
车辆动力学:前后轮车轴
java·开发语言·驱动开发·docker·计算机外设
PHOSKEY1 天前
光子精密QM系列闪测仪在鼠标电路板部件质量控制中的核心应用
计算机外设
墩墩冰1 天前
计算机图形学 分析选择缓冲区中的数字
计算机外设
UI设计兰亭妙微1 天前
中车株州所显示器界面设计
计算机外设·界面设计
墩墩冰1 天前
计算机图形学 多视区的显示
计算机外设
墩墩冰1 天前
计算机图形学 GLU库中的二次曲面函数
计算机外设
墩墩冰1 天前
计算机图形学 利用鼠标实现橡皮筋技术
计算机外设
企鹅侠客3 天前
鼠标键盘按键统计工具
计算机外设·键盘·鼠标
华一精品Adreamer4 天前
便携式显示器供应链与成本结构:挑战与机遇
计算机外设
开开心心就好4 天前
图片校正漂白工具永久免费,矫正实时预览
网络·人工智能·windows·计算机视觉·计算机外设·电脑·excel