- 这个程序将 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_forward
、pin_reverse
、pin_right
和 pin_left
引脚编号,来匹配你的硬件设置,并根据需要调整鼠标移动的速度(例如更改 127
的值)。