使用Firmata将Raspberry Pi Pico接入Quarkus
[LOADING...]
Java 应用通常与 API、数据库、消息系统和云基础设施联系在一起。但 Java 同样可以与物理世界交互——读取传感器、控制 LED、驱动电机,以及与微控制器通信。
这正是 Quarkus Firmata 的目标:一个新的 Quarkus 扩展,用于将 Quarkus 应用连接到兼容 Firmata 的开发板,例如 Raspberry Pi Pico。
该项目结合了三项技术:
- Quarkus:用于应用开发与依赖注入
- firmata4j:Firmata 客户端协议的 Java 实现
- ConfigurableFirmata:运行在微控制器上的固件
首个版本专注于一个实用的 MVP:数字输入/输出、模拟输入、PWM 输出,以及通过 USB 串口与 Raspberry Pi Pico 通信。
什么是 Firmata?
Firmata 是一种协议,允许运行在计算机上的软件与微控制器通信。
与每次应用需要改变某个引脚时都重新编译并上传固件不同,开发板运行的是通用 Firmata 固件。主机应用随后发送命令来配置引脚、写入值,并接收输入更新。
简化后的架构如下:
[LOADING...]
Firmata 使用一种受 MIDI 启发的二进制消息格式,并支持通过能力查询进行功能发现。这意味着主机可以向开发板询问每个引脚支持哪些模式,而不必完全依赖硬编码的开发板定义。更多细节请参阅 Firmata 官方协议文档。
为什么要创建 Quarkus 扩展?
在 Java 应用中直接使用 firmata4j 是可行的。不过,Quarkus 扩展可以提供更自然的应用开发体验。
Quarkus Firmata 负责:
- 创建 Firmata 设备
- 初始化串口连接
- 注册 CDI
- 应用启动与关闭
- 通过 application.properties 配置
- 校验引脚能力
- 将受检的 I/O 错误转换为一致的 API
应用只需要注入 FirmataClient,然后与开发板交互即可。
项目采用标准的 Quarkus 扩展布局:
runtime 模块包含 API、配置和连接生命周期。deployment 模块在 Quarkus 增强阶段注册扩展。项目还包含与硬件无关的测试,以及一个 Raspberry Pi Pico 示例。
Java 25 与 Quarkus
Quarkus Firmata 面向 Java 25 或更高版本。
Quarkus 3.31 开始完整支持 Java 25,包括 Java 25 运行时镜像以及使用 Mandrel 进行 native 构建。该扩展目前面向 JVM 执行,firmata4j 的 native-image 兼容性将单独研究。有关 Java 25 支持的更多细节,请参阅 Quarkus 3.31 发布公告。
构建这个项目需要:
- JDK 25 或更高版本
- Maven 3.9 或更高版本
- 一块 Raspberry Pi Pico
- ConfigurableFirmata 2.11 或更高版本
- 一根支持数据传输的 USB 线
[LOADING...]
图片由 AI 生成——标志展示了用于从 Java 应用控制 Raspberry Pi Pico 的技术栈。
构建扩展
克隆仓库并在本地安装扩展:
验证测试不需要实体开发板,因为测试配置中禁用了 Firmata 集成。
安装完成后,向 Quarkus 应用添加扩展:
配置串口连接
通过 USB 连接的 Raspberry Pi Pico 在 Linux 下通常显示为 /dev/ttyACM0。
在 application.properties 中配置扩展:
在 Windows 上,请使用对应的 COM 口:
在 macOS 上,设备通常位于 /dev/cu.*。
当启用 connect-on-startup 时,扩展会在 Quarkus 启动期间打开串口连接,并等待 Firmata 能力发现完成。应用停止时会自动关闭该连接。
如果开发板可能在之后才接入,也可以禁用自动连接:
应用随后可以调用:
控制 Raspberry Pi Pico
主要入口是 FirmataClient CDI Bean:
ConfigurableFirmata 将 Pico 板载 LED 识别为逻辑引脚 25。
[LOADING...]
区分逻辑 GPIO 编号与物理排针位置非常重要。RP2040 支持文档描述了 30 个逻辑引脚、4 个模拟输入和 16 个支持 PWM 的引脚。模拟输入使用逻辑索引 26 到 29。完整映射请参阅官方 ConfigurableFirmata 开发板支持文档。
[LOADING...]
读取模拟输入同样很简单:
PWM 接受 0 到 255 之间的 8 位值:
在执行某项操作之前,扩展会校验所选引脚是否支持所请求的 Firmata 模式。如果尝试在不支持 PWM 的引脚上使用 PWM,会得到明确的异常,而不是悄悄发送无效命令。
直接访问 firmata4j
高层 API 有意以小步快跑的方式起步,但高级用户仍然可以访问底层的 firmata4j 设备:
这个预留入口使你可以试验扩展 API 尚未覆盖的功能,包括 I²C 通信、事件监听器、底层消息以及自定义 SysEx 命令。
未来版本一旦验证了这些功能的行为和配置方式,就可以将它们提升为专用的 Quarkus API。
关于 Java 25 上的串口通信
jSerialComm 依赖原生代码访问操作系统串口。从较新的 Java 版本开始,JVM 可能要求应用显式允许原生访问。
如有必要,可以使用以下命令启动应用:
从 IDE 运行时,也可以将同样的选项添加到 VM 配置中。
项目目前固定使用 jSerialComm 2.9.3,因为 2.10 版本更改了已发布的 firmata4j 2.3.9 构件所使用的二进制方法描述符。要升级到更新的 jSerialComm 版本,需要调整或替换 firmata4j 的串口传输层。
准备 Pico 固件
Raspberry Pi Pico 必须运行兼容的 ConfigurableFirmata 程序。
固件应启用首个扩展版本所需的模块:
- 数字输入
- 数字输出
- 模拟输入
- 模拟输出 / PWM
- 能力查询
- 引脚状态查询
- 模拟映射
firmata4j 要求固件在初始化期间响应 REPORT_FIRMWARE、CAPABILITY_QUERY、PIN_STATE_QUERY 和 ANALOG_MAPPING_QUERY。
ConfigurableFirmata 从 2.11 版本开始支持 RP2040 系列。
接下来做什么?
首个版本为将 Firmata 用作 Quarkus 管理的硬件接口奠定了基础。以下几项功能自然是未来开发的方向:
- 引脚变化事件
- 舵机控制
- I²C 设备
- 自定义 SysEx 模块
- 健康检查
- 指标
- 自动重连
- 多开发板支持
- Dev UI 集成
- GraalVM native-image 支持
更大的目标,是让物理计算像 Quarkus 开发中的普通部分一样自然:配置设备、注入客户端,然后通过简洁的 Java API 与硬件交互。
Quarkus Firmata 是开源的,并托管在 GitHub 上:
github.com/igfasouza/quarkus-firmata
该项目已在 GitHub 上提供,不过我尚未将它提交为官方 Quarkus 或 Quarkiverse 扩展,因为我不想承担长期维护的义务。尽管如此,任何感兴趣的人都可以把这个仓库作为起点,将其适配到自己的项目中,扩展 API,或为更多 Firmata 特性和硬件提供支持。
此外,欢迎任何形式的贡献:在其他兼容 Firmata 的板卡上进行实验、提交 Bug 报告,以及提出 API 建议。
最后再说一个有趣的想法:我很可能是第一个使用 Quarkus 控制微控制器的人,或者至少是第一个将 Quarkus 与 Raspberry Pi Pico 一起使用的人。我无法证明这一点,但在有人向我展示更早的示例之前,我很乐意认领这段小小的 Java 与 IoT 历史。有意思的是,我浏览量最高的 博客文章 之一,就是关于将 Firmata4j 与 Spring 和 Arduino 一起使用,因此我很好奇这次 Quarkus 与 Raspberry Pi Pico 的冒险会得到怎样的反响。
本文 Bringing Raspberry Pico to Quarkus with Firmata 最初发布在 foojay 上。