thiagolegrand/FX30-Controller

GitHub: thiagolegrand/FX30-Controller

一个运行在 M5Stack Cardputer 上的 Sony FX30 摄影机无线遥控器,通过 Wi-Fi Direct 和 PTP-IP 协议在片场实现录制、参数调整与状态监控。

Stars: 1 | Forks: 0

# FX30 控制器 — M5Stack Cardputer ADV 运行在 **M5Stack Cardputer ADV** (ESP32-S3) 上的 **Sony FX30 (ILME-FX30)** 控制器, 通过 **Wi-Fi Direct → PTP-IP (TCP 15740)** 进行通信。 这是一款口袋大小的摄影机控制器,专为片场设计:开机,从列表中选择摄影机,即可 直接掌控 REC、ISO、shutter、iris、WB、timecode、电池及存储卡剩余时间—— 无需打开 FX30 的菜单。 **状态:已在真实摄影机上正常运行**(FX30 固件 6.00 / 协议 v300)—— 连接稳定,实时状态显示,REC 开始/停止以及各项设置均已在片场得到行为验证。 当前版本:**v3.8**(2026-07-15)。 ### v3.6 → v3.8 更新内容 - **v3.8 — 首屏 = 已注册摄影机列表。** 每台摄影机在 NVS 中都有 别名和凭据,支持**一键**连接。`Enter` 连接, `k` 重命名,`del` 忘记设备;*+ 新建摄影机* 会扫描 Wi-Fi,并要求输入密码和 别名。如果**仅有一台**已注册的摄影机,开机时将自动连接。 - **v3.7.x — 真实的 timecode、电池和存储卡信息。** 移除了本地 TC 合成(不再有“虚假”的 TC):顶部仅显示从摄影机读取的 TC。 底部显示**摄影机**自身的电池电量(`0xD218`)以及 Cardputer 的电量, 低于 15% 时会显示红色警告,在 ≤5% 时图标闪烁,同时显示格式化后的存储卡 剩余时间(`0xD24A`,以秒为单位),与摄影机的显示方式一致。 - **v3.6.x — 通过 enum-walk 调整 ISO/shutter/iris**(`0x9205`,协议 v300),并修复了 shutter **角度** 调整方向的问题。 - **v3.5 — 人体工学改进:** 使用 `[`/`]` 进行 zoom,在主屏幕通过方向键(`;/. ,//`)进行导航,实现无闪烁屏幕(sprite/double-buffer),以及实验性的 Playback 功能(`i`),无需触碰摄影机即可查看存储卡内容。 各版本的详细更新请见 [`PROGRESS.md`](PROGRESS.md)。 项目的真实数据来源:[`docs/FX30_Cardputer_Relatorio.md`](docs/FX30_Cardputer_Relatorio.md)。 各里程碑状态:[`PROGRESS.md`](PROGRESS.md)。 逆向工程发现(真实的 property/control codes):[`docs/RE_FX30.md`](docs/RE_FX30.md) 以及 [`docs/RE_FX30_v300.md`](docs/RE_FX30_v300.md)。 ## ⚠️ 摄影机端的前置条件 该控制器使用**无加密的 PTP-IP** 进行通信。在 FX30 上: 当设置为 **ON** 时,通道会经过 SSH 加密,导致所有功能失效(表现为:日志中出现 `cmd:init-ack-timeout`)。此外需设置:`网络 → PC Remote → 方法 = Wi-Fi Direct`,固件版本需为 **3.00+**, 并且摄影机的 AP 上**只能有一个客户端**(请断开手机连接)。 **凭据 (v3.8):直接在 Cardputer 上注册,无需重新编译。** 初始屏幕是保存在 NVS 中的**摄影机列表**。在 *+ 新建摄影机* 下, 固件会扫描网络,您选择摄影机的 `DIRECT-…`,输入密码 (位于 FX30 的 "Wi-Fi Direct Info." 中)并提供一个**别名**("A-cam", "B-cam")。 此后:`Enter` 连接,`k` 重命名,`del` 忘记。如果仅注册了一台摄影机, 开机将自动连接。 ## 按键说明 (Cardputer) | 按键 | 操作 | 状态 | |---|---|---| | `a` | REC 开始/停止 | ✅ 已在 FX30 上确认 | | `b` / `n` | ISO +1 / −1 档 | ✅ 已确认 | | `c` / `v` | Shutter +1 / −1 档(若模式为 Angle,则为角度) | ✅ 已确认(*speed* 模式;在角度模式下无响应) | | `d` / `f` | Iris +1 / −1 档 | 机制相同;等待电子 iris 镜头测试 | | `w` / `q` | WB Kelvin +100 / −100 | ✅ | | `[` / `]` | Zoom OUT / IN (v3.5;原为 `u`/`z`) | 机制与已使用的 D25C 相同 | | `;` `.` `,` `/` | **方向键** (v3.5):`;/.` 在主屏幕上切换所选字段(ISO→SH→Iris→WB),`,//` 对所选字段进行 -1/+1 调整。这些按键此前已用于 Wi-Fi/Config/Video/起始界面的“方向”控制——现在同样适用于主屏幕 | 尚未在 FX30 上测试 | | `x` | 自动对焦(半按 800 ms) | 协议已接受 | | `s` | Still | 已接受,**在视频模式下无效** | | `r` | VIDEO 菜单 (fps/格式/rec/LUT/SteadyShot/TC/角度) | ✅ | | `g` | **Live View** (~3 fps) | ✅ | | `i` | **Playback** (v3.5,实验性):通过标准 PTP(非 Sony opcode)对存储卡中的照片/视频进行只读浏览 — `` ` `` 退出,`;/.`/`,//` 导航 | **尚未在 FX30 上测试** — 请参阅 PROGRESS.md | | `m` | **属性浏览器**(设备端逆向工程;高亮显示变更) | ✅ | | `k` | **摄影机** (v3.8):注册新设备 / 在起始屏幕重命名所选设备 | ✅ | | `e` | 设置(亮度、颜色、休眠) | ✅ | | `?` | **帮助**(按键映射) | ✅ | | `h` | 导出 props (SD + 串口) | ✅ | | `o` | **SDIO 探测** (v3.7):以只读方式触发 opcodes `0x9203/04/06/08/0B/0C/0D` 并记录 rc + 32 B 的返回数据 — 用于追踪 TC 来源的逆向工程工具 | 逆向工程工具 | | `p` | 开启/关闭串口逆向工程数据输出 | ✅ | | `3` | 兼容 SDIO 协议 v200/v300 | 实验性 | | `G0` (侧边按钮) | 显示屏开启/关闭(省电) | ✅ | | `` ` `` | 重新连接 / 返回起始屏幕(关闭 Live View/Playback) | ✅ | 长按调整按键(`b/n c/v d/f w/q [ ]`)可**自动重复**。 **无闪烁 (v3.5):** 绘图过程现在会输出到 RAM 中的离屏 sprite (`M5Canvas`,见 `hal/Display.h`),然后仅通过(`present()`)一次性发送到物理面板 —— 此前每次重绘都会直接在 LCD 上执行 `fillScreen`,当状态轮询、REC 计时等数据发生变化时,会明显看到黑色闪烁。 ## 架构(摘要) ``` src/ ├─ main.cpp # bootstrap; task de rede (core 0) + loop de UI (core 1) ├─ core/ Transport.h Time.h AppState.h Events.h # interfaces + estado + fila ├─ hal/ Display Keyboard Power # Cardputer (M5) ├─ net/ WiFiManager WiFiTransport # Wi-Fi + ITransport no device ├─ protocol/ │ ├─ ptpip/ Framing.h PtpIp.* # transporte PTP-IP (framework-agnóstico) │ ├─ ptp/ Ptp.* # containers/parsers ISO 15740 │ └─ sony/ SonyCamera.* # handshake SDIO + props/controls reais da FX30 ├─ controller/ CameraController.* # cola UI<->protocolo (task de rede) ├─ ui/ ScreenMain.* Menus.h # telas └─ storage/ Store.* # NVS (credenciais) + SD (dumps) test/native/ # mock PTP-IP + testes; RealCaptures.h = blobs REAIS da FX30 tools/ # pcap_ptp_decode.py, parse_prop_dump.py, serial_dump_reassemble.py docs/ # relatório (fonte de verdade) + RE_FX30 (códigos confirmados) ``` `protocol/` 层**不依赖 Arduino**:它可在 PC 上编译并针对 mock 以及**从 FX30 捕获的真实 blobs** 进行测试(真实的回归测试)。 ## 连接工作原理(已在 FX30 上验证) 1. 加入摄影机的 Wi-Fi AP(`WiFi.setSleep(false)` — 若无此项,AP 会断开客户端连接)。 2. PTP-IP 握手(InitCommand + InitEvent,TCP 15740)。 3. Sony SDIO 握手:`0x9201(1) → 0x9201(2) → 0x9202(0xC8) → 0x9201(3)`。 4. `0x9202` 广播 props 和 **control codes**(REC=`0xD2C8`,AF=`0xD2C1`,……)。 5. 每 2 秒轮询一次 `0x9209` = 屏幕上的状态显示 **以及** keep-alive(若无流量, 摄影机将在约 30 秒后断开连接)。 6. 调整:通过 `0x9207` + i8 ±1 以**步进**方式进行设置(通过 0x9205 进行绝对值设置在 ISO 上 无效 — 会触发限制/AUTO)。 ## 构建与测试 ``` # 主机测试(clang++/g++,无硬件)— 包括使用真实 blob 的回归测试: make test # 固件(PlatformIO): pio run -e cardputer-adv pio run -e cardputer-adv -t upload # upload via USB # 如果上传失败并提示 "No serial data received"(S3 的 USB-JTAG stub): python3 ~/.platformio/packages/tool-esptoolpy/esptool.py --chip esp32s3 \ --port /dev/cu.usbmodemXXXX --no-stub write_flash 0x10000 \ .pio/build/cardputer-adv/firmware.bin # RE 工具(离线): python3 tools/pcap_ptp_decode.py sua_captura.pcapng # captura Wireshark python3 tools/parse_prop_dump.py props.bin # dump 0x9209 (SD) python3 tools/serial_dump_reassemble.py cap.txt --tag D -o props.bin # dump serial ``` 串口监视器(115200):输出 `[net]`(连接),`[stat]`(状态),`[ctrl]` (命令)日志。在 macOS 上,`pio device monitor` 可能会因缺少 TTY 而失败 —— 请使用 `stty -f /dev/cu.usbmodemXXXX 115200 raw -echo -hupcl && cat /dev/cu.usbmodemXXXX` (被动连接,不会重置开发板)。 ## 伦理 / 合法性 本项目的目的是实现与自有硬件的互操作性,使用的是**摄影机自身有明确记录的设置**(Autent. Acesso OFF),并基于 **open-source** 知识(Alpha-Fairy, libgphoto2,sequoia-ptpy)。不涉及绕过 DRM,也未重新分发 Sony 的二进制文件。 本项目为**独立**项目,与 Sony 或 M5Stack 没有任何关联。"Sony"、 "FX30" 和 "Cardputer" 均为各自所有者的商标。本产品不提供任何形式的保证: 您将此固件用于您的摄影机,需自行承担风险。 ## 许可证 [MIT](LICENSE) © 2026 Thiago Falkenberg.
标签:ESP32, PTP协议, 云资产清单, 嵌入式开发, 摄影器材, 物联网, 硬件控制, 逆向工程