Esp32-HID外设 iOS
请前往 HID 外设 页面查看完整的芯片选购、固件下载、烧录教程和视频教程。
iOS 支持蓝牙固件,C3 / S3 / ESP32 Pico 等都能用。
本模块为 HID 模式专用,需要 ESP32 硬件。Agent 模式下请使用 action 模块。
位移模式 (rel / abs)
从 5.x 版开始,固件是 单 bin 双模式,同一个固件包含两套 HID 方案,开机时根据内部 NVS 标志选择其中一种工作:
| 模式 | 原理 | 优势 | 限制 |
|---|---|---|---|
| rel (相对鼠标) | 模拟普通 BLE 鼠标的相对位移 | 全 iOS 版本兼容(12+) | 需要一次性校准;新 iOS (18+) 不允许带按键移动,swipe 在 iOS 18+ 会失效 |
| abs (绝对鼠标) | HID 描述符直接用 0~4095 绝对坐标 | 无需校准,点击/滑动都稳定 | 仅 iOS 18+ 支持 |
简单来说:
- iOS ≥ 18 → 建议用 abs 模式(连上就能用,swipe 稳定)
- iOS < 18 → 只能用 rel 模式(第一次使用要校准一次)
- 固件出 厂默认 rel 模式
模式在固件里持久化,切换一次之后每次开机都是新模式,除非再次切换。切换方式有两种:
- 在 iOS App 首页「位移模式切换」按钮里选
- 脚本里调
device.set_mode(...)(见下文)
切换模式会让固件重启,广播名也会变(AS_iOS_REL_xxxx ↔ AS_iOS_ABS_xxxx)。因为 iOS 会缓存旧的 HID 描述符,切换后必须在「设置 → 蓝牙」里把旧设备「忽略此设备」,再重新配对新名字,否则能连上但点击无反应。
使用前准备
手机设置
abs 模式(iOS 18+ 推荐)只需做一件事:
1. 开启辅助触控:设置 → 辅助功能 → 触控 → 辅助触控 → 打开开关
不开启的话鼠标指针能移动但点击无效。这是 iOS 系统要求,rel / abs 两种模式都一样。
rel 模式除上面那一条外,还要把两个滑块拉满:
2. 跟踪灵敏度拉到最右:设置 → 辅助功能 → 触控 → 辅助触控 → 跟踪灵敏度 → 拉到最右
3. 跟踪速度拉到最右:设置 → 通用 → 触控板与鼠标 → 跟踪速度 → 拉到最右
rel 模式靠校准表补偿 iOS 的鼠标加速度。两个滑块都必须在最右(最快),校准和运行才是同一套系数;否则点击会偏移。
abs 模式不需要调这两项——abs 是绝对坐标直接映射,不受跟踪速度/灵敏度影响。
第一次配对
首次运行脚本时,iPhone 上会弹出一个 "蓝牙配对请求" 的弹窗,点 "配对" 就行。配对成功后屏幕上会出现一个小圆点(鼠标指针),这是正常的。
- 配对弹窗只在 App 前台时才显示,看不到时切回 App
- 日常使用不要在 iOS 设置里"忽略此设备",下次要重新配对
- 但切换 rel/abs 模式之后必须忽略旧设备重新配对(见上方警告)
- 也可以在 iOS 系统蓝牙设置里先手动配对,然后脚本里直接连
导入模块
from ascript.ios.esp32hid import BleDevice
快速上手
rel 模式(默认)
第一次使用前:
- 开启辅助触控(设置 → 辅助功能 → 触控 → 辅助触控)
- 跟踪灵敏度拉到最右(设置 → 辅助功能 → 触控 → 辅助触控 → 跟踪灵敏度)
- 跟踪速度拉到最右(设置 → 通用 → 触控板与鼠标 → 跟踪速度)
- 校准一次(在 iOS App 首页点「校准」按钮,走一遍默认流程)
之后直接用:
from ascript.ios.esp32hid import BleDevice
device = BleDevice() # 自动读屏幕大小
device.connect() # 自动扫描、连接、登录
device.click(642, 1389) # 点击屏幕某个位置(物理像素坐标)
device.home() # 回到桌面
abs 模式(iOS 18+ 推荐)
切到 abs 模式之后无需校准,连上就用:
from ascript.ios.esp32hid import BleDevice
device = BleDevice()
device.connect()
device.click(642, 1389)
device.swipe(500, 1500, 500, 500, 400) # 从下往上滑,iOS 18+ 上稳定
connect() 内部会向固件查询 getmode?,自动识别当前是 rel 还是 abs 模式。你的脚本只需要用 device.click/swipe/... 等统一接口,不用关心底层模式。
连接相关
创建设备
device = BleDevice()
会自动从 iOS 系统读屏幕大小。如果自动读取不对可以手动传:
device = BleDevice(screen_width=1284, screen_height=2778)
扫描附近芯片
devices = device.scan(timeout=5) # 返回名字列表
print(devices)
# ['AS_iOS_REL_8CD0CA63B0E4']
连接设备
device.connect() # 自动发现并连接第一个 AS_ 开头的设备
device.connect("AS_iOS_REL_8CD0CA63B0E4") # 或指定设备名
- 连接后自动登录,不需要手动
login() - 如果上次连接还在,会自动复用,速度很快
- 连接成功后 Python 会通过
getmode?确认当前固件模式,打印[BleDevice] 固件模式: rel(或abs)
断开连接
device.disconnect()
检查连接状态
if device.is_connected():
print("已连接")
位移模式切换
查询当前模式
print(device.get_mode()) # "rel" 或 "abs"
常量:
BleDevice.MODE_REL # "rel"
BleDevice.MODE_ABS # "abs"
切换模式
device.set_mode(BleDevice.MODE_ABS)
# 或
device.set_mode("abs")
切换流程:
- Python 发
setmode?abs&给固件 - 固件写 NVS → 自动
ESP.restart() - 板子重启后广播名变成
AS_iOS_ABS_xxxx(之前是AS_iOS_REL_xxxx) - Python 自动断开旧连接
- 需要你手动操作:
- iPhone 设置 → 蓝牙 → 找到旧的
AS_iOS_*设备 → 点右侧 ⓘ → 忽略此设备 - 回到 App 或脚本,重新
device.connect(),这次会自动配对新名字
- iPhone 设置 → 蓝牙 → 找到旧的
不手动忽略旧配对的话,iOS 会用缓存的旧 HID 描述符,结果是能连上但点击无反应。这是 Apple 的 GATT 缓存机制决定的,无法在代码里绕过。
脚本可以在启动时检查一下当前模式,不对就要求用户切换:
device.connect()
if device.get_mode() != BleDevice.MODE_ABS:
print("当前是 rel 模式,脚本需要 abs 模式,请切换后再运行")
# 也可以直接触发切换
# device.set_mode(BleDevice.MODE_ABS)
exit()
点击和滑动
所有坐标都是屏幕物理像素坐标,左上角是原点 (0, 0)。
不管 rel 还是 abs 模式,Python 接口统一用物理像素,不需要你做换算。