我一直有个执念:希望每一张照片的 EXIF 里都带上准确的 GPS 位置。这样以后在地图上回看,哪年哪月在哪儿按下的快门一目了然。可惜大部分相机并不内置 GPS,为了这件小事我折腾了一圈方案,从手表轨迹回填、低功耗 App,到自己写了一款 App,最后才找到一个几乎完美的硬件解法。这篇就把整个过程和最终方案完整记录一下。
现状与痛点
大部分数码相机,尤其是无反,还是没有内置 GPS。照片导出来以后,EXIF 里少的就是经纬度。
厂商一般会把这个问题丢给手机 App:手机通过蓝牙连相机,把当前位置同步过去,相机按下快门时顺手写进 EXIF。这个设计在纸面上没什么毛病,但一到旅行场景就很烦。相机不可能一直开着,走几步拍几张,关机、休眠、再唤醒,蓝牙连接很容易就断了。等它慢吞吞重新连上时,刚才那几张已经拍完了。
手机这边也不省心。App 放到后台久了以后,系统随时可能把它收掉,iOS 尤其明显。定位一停,后面拍出来的照片就又变成没有坐标的状态。最难受的是,拍的时候你通常还以为它在正常工作,回家导图才发现 GPS 信息有一段没一段。
先试过后期回填
我一开始想的是,不走相机厂商这套蓝牙同步,改成后期补。
一种办法是用 Garmin 手表全程记录 GPS 轨迹,导出 GPX。回来以后写个脚本,按照片的拍摄时间去轨迹里查坐标,再写回 EXIF。
另一种是 Lakr233 之前推荐过的「一生足迹」。让手机低功耗记录轨迹,最后再用他写的程序回填照片位置。
这两条路本质上都是先录轨迹,再按时间对齐。技术上当然可行,精度也够。但我后来发现,这种方案很吃「自觉」。
出门前要记得开记录。忘了开,这一天就没轨迹可用。回来以后还要导轨迹、跑脚本、检查时区。刚开始觉得还好,多来几次就懒了。它解决的是「照片里最终能不能有 GPS」的问题,没有解决「我拍完就希望它已经有 GPS」的问题。
我写过一个 App:Koko
后来我在 GitHub 上看到 gkoh/furble。这个项目很厉害,作者把不少相机厂商的蓝牙协议都逆向出来了。也就是说,开发者可以绕过官方 App,直接给相机发送 GPS 坐标。
我顺着这个项目写了一款 iOS App,叫 Koko。名字来自日语「ここ(koko)」,意思是「这里」。它做的事情也很直接:配对相机以后,在按下快门那一刻,把手机当前的位置写进 RAF / JPEG 的 EXIF。
Koko 集成了 furble 里已有的协议,理论上支持富士 X / GFX 系列、索尼 Alpha / ZV 系列、佳能 EOS / PowerShot 系列等机型。
另外,Ricoh GR 这边也可以稍微期待一下。furble 的 Issue #267 里已经有人在做 GR 的蓝牙支持,后面还提交了 PR #268。目前这个 PR 主要是连接、配对、重连和基础快门控制,作者说已经在 Ricoh GR III HDF 真机上测过。GPS 写入还没一起做进去,只是先留了 stub,等快门这部分稳定以后再单独补。所以它还不是「今天刷完就能给 GR 写 GPS」的状态,但至少这条路已经有人在推了,GR 用户可以先关注一下。
顺便说一句:Koko 支持的相机型号是按协议推的,但我手头只有富士 X-S20 一台机器,所以只在 X-S20 上实测过。其他型号理论上都能用,但因为没有设备,我没办法逐一验证,介意的话请谨慎尝试。
Koko 比官方 App 清爽很多,后台常驻也更稳一些。但它最后还是没能把问题彻底解决掉。原因很简单:不管 App 怎么写,它仍然走的是「手机 ↔ 相机」这条蓝牙链路。相机休眠会断,唤醒后不一定马上重连,手机系统也可能杀后台。这些不是写几行代码就能绕开的。
后来发现硬件方案
真正让我觉得可以不用再折腾的,是 furble README 里提到的一套硬件玩法。
思路反而很朴素:既然手机不适合当中间人,那就换一个只做这件事的小设备。这个设备自己接 GPS 模块定位,再通过蓝牙直接连相机。它不需要联网,也不需要手机参与。配对好以后,开机就连,相机醒着的时候它就一直给坐标。
有意思的是,这套东西不是需要自己画板焊接,而是可以直接买 M5Stack 的现成模块。我已经在他们官方店下单了。
需要买的两样东西
| 硬件 | 作用 | 美元价 | 国内价(淘宝官方旗舰店) |
|---|---|---|---|
| M5StickS3(ESP32-S3 Mini IoT Dev Kit) | 主控 + 屏幕 + 电池 + 蓝牙 | US$21.50 | ¥149 |
| M5Stack GPS Unit v1.1(AT6668) | GPS / 北斗定位模块 | US$9.95 | ¥65 |
两样加起来三十多美元,国内官方店两百出头人民币。比起为了 GPS 去换一台带定位的机身,这个成本基本可以忽略。GPS 模块尤其便宜,AT6668 还是 GPS + 北斗双模。
GPS Unit 用 HY2.0-4P 线接到 StickS3 上就行。组装完大概就是这么一小坨,揣兜里没什么压力:
为什么选 M5StickS3
furble 的 README 里推荐了好几款主控,比如 M5StickC Plus、M5StickC Plus2、M5Core2、M5Core Basic 等。我最后选 M5StickS3,主要是两个原因。
第一,它是新款,芯片是 ESP32-S3,内置电池 250mAh,比常被推荐的 StickC Plus2(200mAh)还大一点。第二,README 里那些旧型号现在有些已经停产,或者不太好买。与其到处淘库存,不如买一个还在正常销售的新款。
StickS3 这块小东西其实性能挺夸张,双核 LX7 @ 240MHz、8MB Flash、1.14 寸彩屏、USB-C。拿来只当相机 GPS 模块,确实有点大材小用。
250mAh 到底能撑多久?
这是我下单前最关心的一点。
furble 作者给过一个参考:ESP32 保持蓝牙连接时功耗大约 30mA。单看这个数字:
- M5StickC Plus2(200mAh):约 6 小时
- M5StickC Plus(120mAh):约 4 小时
StickS3 是 250mAh,如果只是纯蓝牙遥控,不挂 GPS,按比例估算大概能到 7 到 8 小时。但这套方案还要外接 GPS Unit,AT6668 会从 StickS3 的电池里取电,屏幕如果常亮也会继续耗电,所以不能按纯蓝牙的数字算。
综合现有反馈,带 GPS 连续工作大概按 4 到 5 小时预期比较稳。小半天够用,拍一整天就得补电。
好在 StickS3 是 USB-C,可以边充边用。真要从早拍到晚,带个小充电宝就行。再把屏幕超时、亮度这些设置调一下,还能再省一点。
操作流程
整套东西到手以后,刷机和配置都不复杂:
- 把 GPS Unit 用 HY2.0-4P 线接到 StickS3 的 PORT.A。
- 用 Chrome / Edge 打开 furble 官方刷机网站:web-installer.furble.net。
- StickS3 用 USB-C 连电脑,在网页上选择对应型号,一键刷入官方固件。全程在浏览器里完成,不用装 IDE 或 SDK。
- 进设备菜单打开 GPS,开启自动连接、自动重连之类的选项,再和相机配一次对。
设置好以后,每次开机,StickS3 + GPS Unit 都会自动连相机并开始发送坐标。相机休眠以后再唤醒,它也会自己重连。至少从机制上看,这比手机 App 靠谱太多。
小提示:furble 的 GPS 地理标记目前主要支持富士和索尼机型(快门遥控、对焦、间隔拍摄等功能覆盖更广)。下单前最好先去 README 的支持列表里确认下自己的机器。
后期考虑
现在这套东西还是有点散装。StickS3 和 GPS Unit 靠一根线连着,拍的时候只能揣兜里或者拿在手上,能用,但不够舒服。
我后面打算给它做一个 3D 打印支架,把这两个小东西固定成一体,然后直接卡到相机热靴口上。这样 GPS 模块朝天,信号应该更好;线也能收进支架里,看起来不会那么狼狈。等做完了再单开一篇,把结构和打印文件一起放出来。
小结
为了让每张照片都带 GPS,我从 Garmin 轨迹回填、低功耗记录 App,一路折腾到自己写 Koko。绕了一圈之后,结论反而很简单:只要还让手机夹在相机和 GPS 中间,这件事就很难稳定。
后期回填能用,但每次出门和回来都要多做一步。Koko 可以把官方 App 的体验改善一些,但它还是逃不出手机后台和蓝牙重连的问题。furble + M5StickS3 这套方案最吸引我的地方,就是把手机从链路里拿掉了。
三十多美元,一个小盒子,自己定位,自己连相机,拍完照片坐标已经在 EXIF 里。对我这种相机 GPS 强迫症来说,这大概就是目前最接近「不用管它」的解法。