Arduino Leonardo 搭配 USB Host Shield
整套方案里最便宜的输入设备:扩展板如何装到主板上,为什么它的 SPI 线必须跳线到 ICSP 排针,如何上传 sketch,以及你需要接受的局限。
简短回答
Arduino Leonardo 加 USB Host Shield 是最便宜的可用鼠标透传方案:扩展板上的 MAX3421E 读取你的鼠标,再由 ATmega32u4 把它呈现出去。它也是最折腾的方案:大多数扩展板按 Uno 的引脚定义设计,SPI 需要跳线到 ICSP 排针上。
本页内容9
为什么必须用 Leonardo,而不是 Uno
原因在于微控制器。Leonardo 用的是 ATmega32u4,芯片内置 USB,所以板子可以直接以键盘、鼠标或串口的身份出现在电脑上。Uno 做不到,因为它的 USB 接口连的是一颗独立的桥接芯片,这颗芯片唯一的功能就是串口,所以 Uno 永远无法冒充鼠标。这一个区别就是本方案指定 Leonardo 的全部原因,也是为什么你手头已有的 Uno 不管代码怎么写都用不了。采用同款 32u4 芯片的板子,比如 Pro Micro,也是基于同样的原理工作的。
需要哪些配件
整套方案只需要两块板子和两根线。简单就是它的吸引力所在,它也确实是让光标动起来最便宜的办法。
- Arduino Leonardo
- 带原生 USB 的 ATmega32u4。负责向游戏主机呈现鼠标接口,同时承载串口链路
- USB Host Shield 2.0
- 搭载一颗 MAX3421E USB 主机控制器,通过 SPI 通信。你的真鼠标就插在这一半上
- 库
- USB Host Shield Library 2.0,负责主机端的 HID 鼠标处理
- 接游戏主机的线
- Leonardo 自带的 micro-USB 接口。这是 HID 端
- 接副机(第二台电脑)的线
- 单线方案同样走 Leonardo 的 USB 接口;如果你想让两条链路在物理上分开,就通过 UART 接一个独立的 USB 转串口适配器
- 电烙铁
- 实际上是必需品。见下一节
警告
如何连接扩展板的 SPI 线
这个方案的名声就是这一步带来的。大多数 USB Host 扩展板是为 Uno 设计的,Uno 的 SPI 引出在数字引脚 11、12 和 13 上。而在 Leonardo 上,这几个引脚根本不是 SPI,SPI 只从 6 针 ICSP 排针引出。如果你把按 Uno 引脚定义设计的扩展板直接叠插到 Leonardo 上,看起来一切正常,但主板永远无法和 MAX3421E 通信。
- 检查扩展板底部有没有 ICSP 母座。带母座的扩展板叠插到 Leonardo 上就能直接用
- 如果没有,就需要加跳线。先找到扩展板的 SPI 引脚(时钟、数据输入和数据输出)落在 Uno 排针的哪个位置
- 把这三根引脚剪掉、掰开或者用其他方式隔离,让它们不再连到 Leonardo 的数字引脚 11、12 和 13
- 从隔离出来的扩展板引脚各拉一根线,接到 Leonardo ICSP 排针上对应的引脚
- 片选线(通常是引脚 10)保持原样连接,因为片选只是普通的数字引脚,映射本来就是对的
- 给整套板子通电之前,确认扩展板能从排针上拿到 5V 和地
- 通电后运行库自带的板卡诊断示例。它会报告 MAX3421E 是否有响应,而这一步要确认的也只有这一点
如何上传 sketch
接线正确之后,上传就很简单了。但在编写或刷写任何更复杂的东西之前,先证明主机端能正常工作。
- 安装 Arduino IDE,并通过库管理器添加 USB Host Shield Library 2.0
- 依次选择 Tools、Board、Arduino Leonardo,然后选中板子所在的端口
- 上传库里的 USB 主机板卡诊断示例并打开串口监视器,它应该报告控制器存在且已完成初始化
- 上传库里的 HID 鼠标示例,把一只有线鼠标插到扩展板上,确认串口监视器能打印出移动和点击
- 确认之后,再上传你的辅助所要求的透传固件,板子和端口保持不变
- 记下 sketch 打开串口链路时使用的波特率,因为你需要在辅助里填入同样的数值
- 最后一次上传完成后,给整套板子断电再上电,不要只依赖软复位
为什么 COM 端口号总在变
在 Leonardo 上,串口是板子 USB 设备功能的一部分,而不是一颗独立的桥接芯片。因此,板子复位时 COM 号可能会变,上传过程中板子进入 bootloader 时又会再变一次。在反复刷写的板子上这很正常。确定最终固件之后,在设备管理器里找到这个端口,在“端口设置”→“高级”中把它强制设为一个较小的一位数,然后把这个号码填进辅助。如果你想让控制链路与游戏主机完全分开,就改用硬件 UART 加 USB 转串口适配器。这样游戏主机看到的就是一个纯粹的鼠标设备。
低价背后你放弃了什么
这些取舍没有一项是致命的,但每一项都是更贵的设备不会要求你承担的。
| 方面 | Leonardo + 扩展板 | 为什么重要 |
|---|---|---|
| 组装 | 通常需要焊接或跳线 | 这是方案始终无法工作的头号原因,而且没有万用表很难诊断 |
| 主机带宽 | MAX3421E 是全速主机控制器 | 用于鼠标没问题。但如果你想透传高速设备,就不该选这块板子 |
| 处理余量 | 16 MHz 的 8 位微控制器 | 转发报告够用,但几乎没有余力在设备本身上做移动平滑或轨迹修整 |
| 回报率 | 受限于全速设备接口 | 适用全速 USB 的 1 ms 间隔下限。Teensy 4.1 的高速设备端口不受同样的限制 |
| 描述符控制 | 可以改,但工具链更粗糙 | 你可以修改游戏主机看到的内容。但这里的工作量比 Teensy 多,比那些会自动帮你克隆描述符的固件更是多得多 |
| 技术支持 | 只有社区 | 出了问题没有厂商可找。好处是它的每个部分都有人写过文档 |
提示
谁适合自己动手做
这个方案适合已经有电烙铁、享受动手过程、把设备当作项目而不是商品来看待的人。如果你就是这样的人,这是个不错的周末项目,而且你对输入层的理解会超过任何直接买盒子的人。如果不是,那就买 MAKCU,因为为了省下那点差价在扩展板上耗三个晚上并不划算。一个只能用一半的输入设备还不如没有,因为它制造的故障看起来就像辅助本身的 bug。
认定它坏了之前要检查的事
- 板子是 Leonardo 或其他 ATmega32u4 板子,而不是 Uno
- 扩展板的 SPI 线通过接插件或飞线接到了 ICSP 排针上
- 库的板卡诊断报告 MAX3421E 存在
- 在 HID 鼠标示例中,一只普通有线鼠标能打印出移动数据
- Leonardo 插到游戏主机上时,游戏主机能列出一个鼠标设备
- 辅助中的 COM 号与设备管理器中一致,并且是一位数
- 辅助中的波特率与 sketch 中的数值一致
Arduino 常见问题
能用 Uno 加 USB Host 扩展板代替吗?
不能,因为 Uno 无法以 USB 鼠标的身份呈现自己:它的 USB 接口连的是串口桥接芯片,而不是主微控制器。你需要一块芯片本身带 USB 的板子,比如 32u4 系列的板子。
一定要焊接吗?
如果你的扩展板底部带 ICSP 接插件就不用,直接叠插就能用。但大多数便宜的扩展板没有这个接插件,这种情况下你必须隔离三根引脚并拉三根线。
这个设备比 KMBox 更容易被检测吗?
这里没有任何东西是检测不到的,而实际的差别比大家想象的要小。两种情况下,移动数据都是以真实 USB HID 流量的形式到达的。便宜的 DIY 方案如果保持默认设置,呈现的 USB 身份往往更弱,但这是配置上的选择,而不是价格决定的结果。
无线鼠标的接收器插在扩展板上能用吗?
通常可以,因为主机控制器会把它当作 USB HID 设备。常见的例外是会呈现额外厂商接口的接收器;另外,板载配置软件经过任何透传后一般都会失效。
为什么 COM 端口号总在变?
因为串口接口是板子 USB 设备功能的一部分,而板子在上传过程中会复位。固件定型之后,在设备管理器里强制设一个固定的小号码即可。
资料来源
我们核对过的来源清单中没有涉及 Leonardo、USB Host 扩展板或 MAX3421E 的文档,因此跳线和上传步骤都来自实际动手搭建的经验。
继续阅读
仍然没有解决?在 Discord 提交工单
全部指南