本来想软件和硬件分开写的,但软件到现在还没有完成,虽然80%的功能已经有了,happy path也都没问题了,但有些细枝末节的地方还是想要处理好,争取把固件做成finished software。也因为软件没完成,所以这篇文章把硬件和软件合起来写。
硬件
在前文中提到过,由于配对过程中需要使用传统蓝牙,所以必须用原版的ESP32,带有后缀的版本都是只有BLE的。最近ESP32好像出了个高性能的版本,针对边缘计算和AI的使用场景,这个也有后缀,但有经典蓝牙5.0来着,不过考虑到我们户外场景不要求高算力,并且希望成本尽可能的低,因此这里还是推荐大家选用原版的ESP32进行开发。
由于我在电路设计方面完全没有知识和经验,在不花费较长时间进行系统性学习的前提下,我决定使用模块化的器件进行制作,好处是只需要接线即可,坏处是设计要跟着模块走,并且模块的成本比较高,因为别人也要卖模块赚钱。
ESP32选用开发模块ESP32 DevKitc,我买到的是v4版本,模组是ESP32-WROOM-32E,淘宝价格大约60到70块吧。可以通过USB供电,或通过5V IO引脚供电,二者不能同时供电,因此刷程序的时候就要断开电池,外出使用时直接用5V电源模块接到5V和GND上供电。
出于对淘宝上零售软包锂电池的不信任,以及考虑到需要乘坐飞机出行的需求,我选择18650的锂电池模块,成本大约7元,可以通过USB TypeC充电,有独立的开关引脚,固定5V输出。
GNSS模块则是固定的ublox NEO-M10-0-10,这个好像是国内厂家买10代芯片自己封装的,ublox官方并没有所谓的NEO M10封装。
最初的版本是我买了4x6cm的洞洞板,决定在上面连线,但一方面手工焊接没法量产,再一个就是GNSS模块焊接过程中受热损坏,坏一块就损失40块钱,有点心疼。于是我紧急下载了KiCAD学习PCB板的绘制。有一说一,PCB确实比建模容易多了,从下载软件到嘉立创下单,一共耗时4小时22分钟。




因为之前没有在嘉立创消费过,也不愿意用他们提供的设计软件,因此我自掏腰包花了35元打样了10块板。板自上加了按钮和LED,按钮是为了触发配对的,LED则用来指示状态,当初为了好看选了RGB,结果引脚太密了,焊接麻烦,用助焊膏可以缓解,但助焊膏加热后的蒸气又会让我头疼,这10块板子最终焊接成功8块,结果我头疼了一晚上。
总之,PCB起到一个插接板的作用,电源什么的都是从这里焊接的,与模块之间的连接,要么是排母,要么是焊接一段导线,有效解决了我焊接水平一坨而导致元件/模块过热暴毙的问题。
但硬件的问题还没有结束,我总不能把他们装到塑料袋子里带出去吧,怎么也得有个外壳。一开始想买个原型PVC管子,两边一封就好了,但后来发现充电和开关都比较麻烦,要打孔,而且只能手工来。于是我又买了一台3D打印机,并紧急学习了建模。
这部分未来准备单独写,因为买Sparkx i7的时候商家宣传好打印,实际上到手后才发现,想要打印质量好,就不可避免地要用主流开源的OrcaSlicer重新校准至少回抽、流量比例、最大体积流量和压力提前(PA值)。虽然这个有自动PA值测量,但测不准,每次开始前还要浪费时间和材料。另外还走了一些弯路,例如因为PEI板用洗洁精清洗后首层仍然不沾,误打误撞调了z offset,发现创想三维自己魔改的固件和fluidd打架,最后发现不是z offset的原因,单纯是我的洗洁精内含护手成分,用香皂或肥皂洗一下就好了。最近还换了0.6mm的喷嘴意图加速打印速度。这些经历我觉得完全可以单独整理成文章,一方面挺有趣的,另一方面也是分享给其他入门的人,希望别人能少走一些弯路。3D打印确实有意思,但并没有商家宣传的那么好,并且自己不会建模,这玩意儿买回家还不如一个普通的打印机。
至于为什么买创想三维?因为Prusa买不起,拓竹背刺社区,其他家的太贵。买Sparkx i7就是因为不想一次花太多钱,先尝尝咸淡,万一我不会建模,沉没成本也不会太大。和相机一样,等用Z502尝出咸淡了在考虑要不要买Z8。
当然,建模这一块我用的FreeCAD(因为我写代码日常用OpenSUSE,是Linux系统),虽然1.0版本有大进步,但各种小问题还是让我忍无可忍,尤其是考虑到生产力的时候。后来掏出笔记本安装了Autodesk Fusion并配置到sunshine和moonlight以便我在Linux上串流使用这个软件。学习并体验了Autodesk Fusion之后,我才知道原来外面根本没下雨,也理解了为什么Fusion这么多人骂,照样离不开它。商业软件设计的确实好用。至于个人版的限制什么的,和我淘宝十块钱买的教育版说去吧。



外壳设计比较方正,因此FreeCAD操作虽然繁琐,但能做。盒子采用了比较基础的snap设计,就是盒子本体有45度角的突起,盖子有对应的凹陷,安装时用力挤压就可以像卡扣一样卡进去,拆的时候沿着长边用力,也比较容易扣开。
为了固定电池模块和PCB,底部分别设计了凹槽,PCB竖向摆放,并设计的类似护栏的结构,可以直接用胶带贴上固定。电源模块则是平放,其上预留的空位不够宽裕,因此一头直接采用类似卡扣的结构,另一头给充电口留孔,并且顺便作为固定,效果还不错。装配起来是这个样子:


就我目前的能力来看,在不花时间学习电路设计而当前提下,这应该就是我能做到的比较好的程度了。因此接下来就是软件。
软件
由于我没正经写过C++,也没正经做过硬件项目,因此大部分代码都是GLM 5.2协助编写的(那个时候还没有GLM 5.3),相比Kimi K2.7 code, 我认为GLM 5.2在嵌入式方面更强一些。我只负责功能和结构设计,也算是自费当上项目经理了。
完整的代码已经开源在 https://github.com/hurui200320/nsg/tree/master/esp32
我用的pio-arduino,因为原版的PlatformIO对ESP32支持很差。在setup方面会遇到的问题主要是Flash不够用,好像是因为硬件bug还是什么原因,总之比较快的存储区域是有限的,所以需要排除掉一些东西才行。具体我也不太清楚,反正我让LLM搞定了,看起来就是排除掉了一些项目里用不上的函数什么的,总之就是想尽办法节省宝贵的空间。
关于程序的整体架构,我设计的两种模式,一种是正常模式,一种是配对模式。在启动的时候根据条件(例如按钮是否按下,或NVS里记录了要进入的模式)启动进入一个模式。
配对模式,正如名字所示,用来配对的。但因为硬件没有屏幕,因此只能闭着眼扫描,扫到谁是谁。进入配对模式后亮红灯,如果扫到了相机并发起了配对,蓝灯亮起。BLE握手完成,等待相机确认配对码时,蓝灯会闪烁。配对成功则自动重启(进入普通模式),任意一步配对失败,RGB三个颜色的灯同时亮起,此时需要手动断电重启。
正常模式则是默认的,进入正常模式后首先亮绿灯。如果有相机建立了BLE连接,蓝灯会亮起,连接断开(例如相机熄屏或关机)时蓝灯同步熄灭。在正常模式下长按按钮3秒钟,会在NVS写入指示,让下次启动进入配对模式,然后重启。
在设备刚刚启动的时候,RGB三个灯会轮流亮1秒,确保灯泡是好的,如果开机时按住按钮,这时不管NVS怎么写的,都要进入配对模式。如果没有按下按钮,检查NVS,并进入指定模式,并清除NVS。如果NVS没说,那默认进入正常模式。
我认为以上流程在只有一个按钮,一个RGB LED的情况下,应该算是功能相对完备的交互设计了吧。而且每次重启避免了切换模式时资源泄露,简单方便又可靠。
另外由于BLE握手时间可能会比较长,尤其Z502这类不太高端的相机在熄屏状态下完成一次BLE握手可能要45秒,因此需要利用多核来防止BLE操作阻塞整个固件。因为GNSS模块等不了45秒,串口来的数据必须及时读取并处理,否则缓冲区满了就会丢数据。好在ESP32有两个核心,通常Core 0是运行ESP-IDF的东西,可以理解为系统进程之类的东西,而Core 1则是运行用户的代码。而通过将BLE操作移动到Core 0上,我们的核心代码只需要处理按钮输入、LED等和处理GNSS即可。核心代码和BLE Worker通过队列传输信息(例如有BLE连接的时候亮蓝灯,没有就熄灭,以及核心代码定时更新位置和时间信息)。虽然一个相机熄屏了,会阻塞整个BLE最长1分钟,但至少不会阻塞核心代码。
目前软件中剩下的边边角角就是一些细节了,比如遇到错误如何恢复,蓝牙协议的部分断电重启就好了。但如果NVS存放的数据损坏了,或者发生bit rot,整体还是有效数据,但内容可能发生了位反转,这该如何解决。毕竟在树林里拍小鸟的时候,总不能掏出笔记本现场给ESP32改bug吧,因此至少需要一种能够从错误状态下改出的流程,而这需要不断的实际测试。另外蓝牙和GNSS的通讯也都比较粗糙(例如我措了一个ublox协议的状态机,但没搓完整,happy path没问题,但出错的情况下就难说了),最近有人在GitHub给我提issue说相机出现问题会硬直一段时间,这期间ESP32会不停地尝试重连,导致蓝牙射频信号让GNSS模块丢失位置fix(不知道真的假的,但蓝牙重连确实需要增加一个重试时间)。这些都必须在不断的测试中发现并改正。
关于盈利
其实一开始是想靠这个盈利来着,毕竟现在没有收入了。但尽管我非常爱钱,在审慎思考下还是决定暂时推迟这个计划。因为自己做着玩儿和真的拿出去卖是两套完全不同的标准。如果只是做着玩的话,我觉得做到这种程度就完全可以了。但如果要卖的话,首先要考虑成品的外观、质感,如果以现在的成本按照50%的盈利来看,定价要来到二百三百,如果给人家寄出去一个形似中东特产的硬件,大概卖家是不会买账的。另外售卖还要有一套自己的流程,例如打包、发货、售后、客服这些环节。如果是博客的老读者,那应该都知道我做不来服务业,所以原本的打算是卖硬件,不提供软件售后。至于固件使用或调试,考虑付费咨询,一小时100元。但后来想想,能买我这个东西的,不就是图个省事,花钱就完了。人家要是自己懂得软件硬件这些,那想要复刻我这一套也并不难,甚至可以说没什么门槛。我自己觉得弄这一套硬件麻烦,是因为我不会,要是有专业对口的在校大学生或者从业人员,我觉得人家用不了一个月就能复刻出比我这个更好、成本更低、一体化程度更好的产品。所以想来想去,除非日后实在没钱了,不然暂时还不打算开店售卖。
后记
以上就是关于用ESP32替代尼康SnapBridge的系列了。最近一直在忙别的side project,所以这个项目的开发就有点懈怠了。不过好在破鼓万人捶,尼康的SnapBridge确实不受人待见,因此这个repo也喜迎多个来自社区的PR,这确实让我有些受宠若惊。不过这也确实说明我这个项目有用,也算是回馈上开源社区了。
之后可能会写一写3D打印的事情,也可能写写最近在搞的项目,比如daapu(名字是随机生成的),专注于LLM记忆的一个harness,主打一个RDF风味。再就是llm-ops,因为昆明最近开始降温了,说明冬天快要到了,这样就可以肆无忌惮地运行本地LLM来充当取暖器了。或者也可能发一下国庆期间拍的照片,如果出去玩了的话。
以上就是本文的全部内容了,感觉有点水,但想来想去总觉得不能把repo里的代码再复制粘贴一下吧,那样就更水了。总之,祝大伙假期快乐。
-全文完-

【歪门邪道】用ESP32替代尼康SnapBridge - 软件硬件篇 由 天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。