开源摩托导航仪表Glimpse:ESP32圆屏硬件与蓝牙SPP全解析

📅 发布时间:2026/10/6 6:55:51
开源摩托导航仪表Glimpse:ESP32圆屏硬件与蓝牙SPP全解析
Glimpse 这个项目名字第一次看到是在开源硬件群里摩友转了个链接配文“终于有人愿意做摩托车的正经仪表了”。我骑车多年太懂这个痛点了手机支架夹在车把上太阳一晒屏幕乌漆嘛黑路一颠摄像头就疯狂对焦骑个长途还要担心手机电量。汽车上有 CarPlay摩托车这么多年愣是没个体面的方案。Glimpse 的出现算是把这条路走通了——免费开源的圆形屏幕导航仪表主控 ESP32蓝牙连手机高德导航的数据直接投到圆屏上迈速表、航向、离线地图、音乐播放全都安排上。这篇文章不聊虚的就把我从读源码到焊板子、再上车实测的完整过程拆给你看。1. 项目定位与核心价值1.1 摩托车导航为什么不能直接用手机先说一个很多人不骑车不知道的事实摩托车装手机支架体验并不好。第一个问题是阳光下的可读性。手机屏幕亮度再高在骑行途中直面阳光也是勉强能看更不用说雨天沾满水珠以后触控直接失灵导航看一眼就再也不想看第二眼。第二个问题是机械层面的伤害手机支架的震动是持续的特别是单缸车和高转车时间长了摄像头光学防抖会被震坏这个案例在摩友群里已经发生过不止一次。第三个问题才是关键摩托车的仪表盘空间非常小圆形表盘这种设计语言占据了主流手机支架反而破坏了整车的调性看着很违和。所以摩托车的导航设备本质上需要一个专门为骑行场景设计的“仪表”而不是把手机硬塞上去。这个设备必须有足够大的字体、足够清晰的对比度、能固定在车把或者油箱盖上、而且不能占用手机本身。Glimpse 的定位正好卡在这个需求点上它用一块圆形屏幕复刻了传统摩托仪表盘的造型但显示的内容从传统的转速表、油量扩展成了导航箭头、速度、航向和歌曲信息。1.2 Glimpse 的核心思路手机算圆屏显Glimpse 的架构逻辑其实很简单不做一台用来导航的独立设备而是做一个高质量的“第二屏”。手机上面继续用高德导航这类成熟应用完成路径规划和定位Glimpse 通过蓝牙接收手机推送的导航状态数据然后在圆屏上渲染出来。这种分工的好处非常明显路径规划、实时路况、地图数据这些重活都由手机扛着Glimpse 只需要做一个可靠的信息终端硬件需求一下子降下来了成本可控功耗也好做。从软件角度看这个思路也规避了一个大坑如果要在嵌入式端做完整的离线导航那就必须处理地图数据、道路拓扑、路径搜索算法这个工程量不是个人开源项目能轻易完成的。Glimpse 把“导航计算”外包给手机自己在离线地图上只做展示和轨迹叠加把人力集中在显示效果和骑行体验上这是很聪明的选择。项目免费开源意味着你可以直接打板、焊模块、刷固件也可以根据自己的需求改 UI、加传感器、换外壳自由度非常高。2. 硬件方案拆解一个圆屏背后的选型逻辑2.1 主控为什么选 ESP32Glimpse 的主控毫无悬念地选了 ESP32原因在于它几乎是这个价位里唯一能满足全部需求的芯片。ESP32 集成双核处理器、2.4G Wi-Fi、经典蓝牙和低功耗蓝牙有大量 ADC、I2C、SPI、UART 接口外设资源丰富。更重要的是ESP32 对开源生态的友好程度极高Arduino、PlatformIO、ESP-IDF 都有成熟支持社区积累的代码库让你不用从零开始造轮子。这里有个选型的关键点必须提醒如果你考虑用 ESP32-C3 或者 ESP32-S3 这类新芯片来做类似项目需要提前确认它们是否支持经典蓝牙。ESP32-C3 只支持低功耗蓝牙 BLE不支持经典蓝牙 SPP 和 A2DP。而 Glimpse 连接手机 App、接收高德导航数据、获取歌曲信息这些功能很多依赖经典蓝牙协议原版 ESP32 反而是最稳妥的选择。虽然 ESP32 是好几年前的产品但在这个场景下它的协议支持和外设配置依然是最全面的。2.2 圆屏、GPS、电子罗盘的模块搭配显示部分Glimpse 用的是常见 1.28 英寸圆形 LCD分辨率 240x240驱动芯片 GC9A01SPI 接口。这块屏幕的体积完美契合摩托车圆形仪表盘的造型显示效果在阳光直射下有背光增强模式兜底。选 GC9A01 而不是其他圆屏驱动核心原因是它不需要额外电平转换芯片3.3V 逻辑电平直接由 ESP32 驱动且 Arduino 生态中的 TFT_eSPI 库原生支持这个驱动移植成本极低。GPS 模块方面常见的方案是 ATGM336H 或者 BN-880。这两类模块都是串口输出 NMEA 0183 协议的定位数据波特率默认 9600模块自身带陶瓷天线搜星速度和定位精度对骑行导航来说完全够用。我自己用的是 BN-880因为它带电子罗盘功能不过后面会讲到航向数据我最后还是单独加了传感器来做原因在后面软件功能部分细说。电子罗盘用 QMC5883L这枚传感器通过 I2C 接口读取三轴磁场数据测量范围正负 2 高斯分辨率能到 0.1 度级别。选它的理由一是便宜二是它有一套很成熟的 Arduino 库读取和校准都有现成函数。如果你追求更高精度也可以换成 HMC5883L但要注意市面上假货比较多QMC5883L 反而更容易买到正经货。2.3 供电、防水和装车固定供电是整个项目里最容易翻车的一环。ESP32 本身功耗不低加上屏幕常亮和蓝牙持续连接峰值电流能到 300mA 以上。如果只是用锂电池直供电量很快见底如果直接用 USB 线从手机充电宝拉电又没有意义。我最终采用的是 18650 电池加 IP5306 充放电管理模块的方案IP5306 支持升压输出 5V、1A 充电、电量指示并且带有过充过放保护相当于把充电宝电路搬进了仪表盘里。电池端并联了一个 SWITCH 开关停车时可以直接断电避免待机漏电把电池拖垮。防水方面我踩过一次坑。第一次测试用的是一个 3D 打印的开放外壳结果骑到半路下小雨屏幕边缘进水直接花了。后来老老实实换成了带防水密封条的 ABS 仪表接线盒所有进出线口打热熔胶封堵按键用硅胶按键帽覆盖实测淋雨后内部干燥。屏幕边缘用透明硅酮密封胶再走一圈基本就能达到日常骑行的防水需求。装车固定方面我用的是后视镜支架加铝合金表壳的方案注意不要在骑行过程中调整设备角度出发前就要把视角调好。3. 蓝牙与手机 App 的数据链路核心中的核心3.1 为什么用经典蓝牙 SPP 而不是 BLE很多第一次接触 Glimpse 的人会问低功耗蓝牙 BLE 不是更省电吗为什么不用 BLE 做数据传输这里面的原因得从手机 App 的角度看。高德导航这类 App 在连接外部设备时走的往往是基于经典蓝牙 SPP串口透传协议的数据通道因为 SPP 的逻辑非常简单手机端把数据写成字节流设备端从串口里读出来就是完整的一包数据不需要像 BLE 那样定义 Service、Characteristic、Notification 这类抽象层。对导航卡片这种高频率、短消息的推送场景SPP 的实现成本低得多。当然BLE 也不是没有用处。Glimpse 在手把上做了一个多功能按键可以切换页面、暂停音乐、接听电话这个按键触发功能用的是 HID 协议。HID人机接口设备协议既可以通过经典蓝牙实现也可以通过 BLE 实现但是在兼容性上经典蓝牙 HID 对手机端更友好很多手机蓝牙键盘、自拍杆用的就是经典蓝牙 HID。所以项目里选择了经典蓝牙全面覆盖SPP 负责数据流HID 负责控制输入一套协议栈解决两个问题。3.2 导航数据协议的具体格式手机 App 推送给 Glimpse 的数据本质是一串结构化的状态描述。最简单高效的格式是 JSON 行协议每一行一条完整消息设备端按行解析。常见字段大概长这样{ type: navigate, action: turn_right, distance: 300, next_road: 解放大道, remain: 15分钟, speed: 68, heading: 245 }设备端收到这行数据后先判断 type是导航信息就提取 action 和 distance把转向箭头渲染在屏幕中央把剩余距离放在箭头下方剩余时间放在角落。这里有个细节action 字段最好用固定的枚举值比如 straight、turn_left、turn_right、uturn、arrive这样设备端画箭头时不需要去理解自然语言直接查表映射图标就行。速度字段在手机端能从 GPS 获取但如果设备本地接了 GPS 模块这个值也可以从本地读取双路互补。3.3 配对和连接注意事项配对流程上Glimpse 上电后会在蓝牙列表中以一个可被发现的名字出现比如 “Glimpse-Navi”。手机第一次连接时通常要求输入 PIN 码默认一般是 0000 或者 1234。连接成功后手机 App 端会显示已绑定设备之后每次上电都会自动回连。这里我遇到过几个很典型的坑。第一个是手机系统蓝牙权限的问题Android 手机上连接蓝牙设备不仅要开蓝牙还要授予 App 定位权限否则高德这类应用无法获取导航状态推送。第二个是配对记录冲突的问题如果之前手机和另一个同品牌模块配对过可能导致 Glimpse 被系统拒绝连接办法是先删除旧配对记录再重新扫描。第三个是连接成功但收不到导航数据这种情况八成是手机 App 里的外部设备开关没有打开需要到 App 的设置页面确认已经开启“连接车载蓝牙/仪表设备”之类的选项。4. 软件功能逐个拆解迈速表、航向、离线地图、音乐4.1 迈速表GPS 测速的取舍Glimpse 的迈速表数据来源有两种选择一种是用手机 GPS 获取速度再通过蓝牙推送过来另一种是接一个独立 GPS 模块在本地解析 NMEA 语句得到速度。前者实现简单省一个模块的钱但手机的 GPS 更新频率大约 1Hz城市里经过高楼遮挡时速度会跳变后者数据稳定还能在手机没电或者断连的情况下独立工作。我两套都试过实际骑行体验下来板载 GPS 模块的数据更靠谱。NMEA 0183 协议里的 GPRMC 语句包含地面速度字段单位是节乘以 1.852 就换算成公里每小时。代码里解析时要注意字符串转浮点数时的取舍别用简单的 atof容易因为固件内存不足导致解析失败。速度显示还有一个细节GPS 速度天生有滞后性所以在固件里做了一个滑动平均滤波取最近 5 秒的速度值做中位数显示的数字稳定很多不会因为隧道里信号中断瞬间掉到零再猛跳回来。4.2 航向显示电子罗盘的校准坑航向数据为什么不用手机推送的 heading 字段因为手机放在口袋里或者支架上方向传感器会受到手机姿态的影响和摩托车的车头方向并不总是一致。Glimpse 把电子罗盘固定在一个和车头朝向一致的位置直接测量车身朝向这样显示的航向才真正和仪表盘上的物理方向一致。QMC5883L 的原始读数会受周围磁场干扰尤其是车把内走线和金属支架所以上电后第一件事是校准在水平面上画 8 字或者原地慢慢转 360 度让算法算出 X 轴和 Y 轴的偏移量。这个校准值我推荐直接存进 NVS 或 SPIFFS 里下次开机不用重新校准。如果你要进阶还可以加上倾角补偿。摩托车倾斜时两轴罗盘的读数会大幅失真这时候需要再加一个三轴加速度计用倾斜角反算水平磁场分量。基础版可以不做这个功能但你要知道这个限制压弯的时候航向指针会乱飘一会儿。这个话题可以后续单独写一篇详细说明。4.3 离线地图不是你想的那种离线很多人一看到“离线地图”三个字就跑过来问能不能装全世界的高德离线包这里必须澄清一下。ESP32 的 Flash 容量撑死 16MB加上文件系统能存放的地图数据非常有限。Glimpse 的离线地图方案实质是“预生成的低分辨率区域示意地图 GPX 轨迹叠加”先用地图工具把常用骑行区域的道路简化成一张图片存进 SD 卡或 Flash 分区再通过手机 App 导出 GPX 轨迹或者在屏上绘制简化的折线路径形成一个“不需要时时刻刻联网下载”的骑行参考图。如果你想要更实用的”离线”体验更合理的方案是让手机下载高德地图的离线导航包导航计算全程离线完成Glimpse 只负责显示结果。毕竟离线地图包的体积动辄几百 MB这种重活在嵌入式端根本不现实。Glimpse 的屏幕显示像一张“路书”配合手机端的离线路径规划跑长途时完全可以做到只靠本地数据完成导航这也是项目名里敢写”离线地图”的真正底气。4.4 音乐播放用 AVRCP 做信息显示音乐播放功能背后是蓝牙的 A2DP 和 AVRCP 两个协议在配合。A2DP 负责音频流的传输AVRCP 负责控制指令和歌曲元数据。Glimpse 的逻辑是只注册 AVRCP 服务从手机接收歌曲名、歌手、专辑、播放时长、播放状态然后显示在圆屏的一个页面上同时支持通过 HID 按键发送播放、暂停、上一曲、下一曲指令。这里有一个认识误区Glimpse 本身不是一个蓝牙音箱它不输出声音。骑行时听歌是通过头盔蓝牙耳机完成的Glimpse 更像一个“遥控器 可视化面板”。如果你在手机 App 上发现开启 Glimpse 连接后手机外放或者耳机声音变得奇怪通常是因为手机把 Glimpse 误认成了 A2DP 音频接收设备。解决方法是检查手机蓝牙设置里 Glimpse 的配置文件只保留“联系人分享”或类似的数据连接取消“媒体音频”选项。4.5 屏幕 UI 布局和交互设计圆屏的可视面积其实不大240x240 的分辨率如果再塞一堆小字骑行时根本看不清。我参考了仪表盘设计的原则中央永远放最重要的信息也就是导航箭头右上角放速度数字要大至少 48 号字左下角放航向罗盘小尺寸实时指向底部一条细进度条显示剩余距离占比顶部留出电量或连接状态图标的位置。配色上用深色底配高对比黄色和白色白天强光下也能看清。交互上单机按键切换页面长按呼出菜单配合 HID 控制基本可以做到手不离把完成绝大多数操作。5. 手把手实操从元器件到上车测试5.1 元器件清单与接线表我把整个项目拆成几个模块列一份可以直接照着买的清单模块型号/规格数量说明主控ESP32 DevKitC经典版1必须用支持经典蓝牙的版本圆形屏幕1.28 英寸 GC9A01 240x2401SPI 接口可裸屏或带底板电子罗盘QMC5883L1I2C 接口三轴磁力计GPS 模块ATGM336H / BN-8801串口输出 NMEA 协议数据充放电管理IP5306 模块1升压 5V支持充电宝协议锂电池18650带保护板1容量建议 3000mAh 以上按键轻触开关硅胶帽1用于切换页面和发送控制指令防水壳ABS 仪表接线盒1尺寸要能容纳电池和主板接线可以这样对应到 ESP32 的引脚上GC9A01 的 SCL、SDA、RST、DC、CS、BLK 分别接到 GPIO18、GPIO23、GPIO4、GPIO17、GPIO5、GPIO15QMC5883L 的 SDA、SCL 用 GPIO21、GPIO22GPS 模块的 TX、RX 接到 GPIO16、GPIO17 对应的串口引脚注意交叉接线模块 TX 接主控 RX模块 RX 接主控 TX。5.2 固件编译与烧录流程我建议直接用 PlatformIO 管理工程比 Arduino IDE 方便得多。先把 TFT_eSPI 库克隆到项目的 lib 目录然后在它的配置文件里把驱动的注释从 ILI9341 改成 GC9A01并设置屏幕旋转角度、引脚定义。GC9A01 屏幕的旋转角要根据安装方式微调一般设置 0 度或者 90 度这一步会影响箭头方向后面调试的时候要反复确认。固件的烧录本身很简单用 USB 线连上 ESP32在 PlatformIO 里点击 Upload等着烧录完成就行。这里提醒一句烧录之前记得先把 GIPO0 或者 EN 按键按住确保进入下载模式有些 ESP32 开发板不支持自动复位下载手按一下更稳妥。烧录完接上串口监视器波特率设 115200能看到启动日志和蓝牙初始化信息。// 伪代码示例初始化蓝牙 SPP 并通过串口输出接收到的数据 #include BluetoothSerial.h BluetoothSerial SerialBT; void setup() { Serial.begin(115200); SerialBT.begin(Glimpse-Navi); // 设置蓝牙名称 Serial.println(Bluetooth started); } void loop() { if (SerialBT.available()) { String line SerialBT.readStringUntil(\n); Serial.println(line); // 先通过 USB 串口观察原始数据帧 } }刷完这个最简单的测试固件你应该能在手机蓝牙列表里搜到设备并连上。连接后在手机安装一个支持 SPP 的蓝牙串口调试工具发送 JSON 字符串再在电脑上观察串口输出是否完整收到了那行数据。这个测试通过后再移植到 Glimpse 的主固件里开发效率会高很多。5.3 手机 App 连接和导航数据验证固件刷好之后第一次连接手机要做的第一件事不是直接开导航而是打开一个临时的蓝牙串口调试工具手动模拟导航指令验证接收链路。先发送{type:navigate,action:turn_left,distance:200}如果屏幕上正确出现了左转箭头和 200 米字样说明 SPP 通道和 UI 渲染都正常。接着发送{type:music,artist:Beyond,title:海阔天空}确认歌曲信息页有显示。这两条测完数据链路基本就是通的。接下来再打开高德导航进入骑行导航模式。我在实测中使用的操作路径是打开高德的设置把蓝牙外部设备连接选项打开然后重新回到导航界面。手机端会出现连接确认提示允许后Glimpse 就能收到导航推送。这里有个小技巧第一次连接成功后建议在手机蓝牙设置里保存设备并设成“自动连接”以后每次打开高德导航数据会自动开始推送不用再手动重连。5.4 装车、固定和路测验证装车部分我把电源部分放在油箱盖板下方屏幕通过后视镜支架固定在车把正面GPS 模块放在表壳上方朝天的位置陶瓷天线要保持净空不要用金属外壳完全罩住。电子罗盘的安装位置尽量远离车把内的金属线束和磁铁扬声器否则校准结果会被持续干扰。所有接线完成以后先用充电宝供电测试 20 分钟观察蓝牙掉不掉线、屏幕有没有花屏、GPS 能不能正常定位确认没问题后再接锂电池上车。路测时要分阶段做。第一阶段停在空旷停车场验证静止状态下的定位、罗盘校准和箭头方向第二阶段在慢速绕圈验证转弯提示的实时性第三阶段才上城市道路做真实导航。务必给自己留出充足时间不要带着一个半成品上高速骑行中操作设备非常危险导航界面不清晰时宁可停下来调整。6. 常见问题与排查经验实录这里把我在项目过程中踩到的问题整理成一张速查表方便你遇到问题时直接对照故障现象可能原因解决方案手机搜索不到 Glimpse 蓝牙设备经典蓝牙未初始化或上次连接记录残留重启 ESP32删除手机旧配对记录检查 SerialBT.begin 是否调用成功搜索到但连接不上PIN 码错误或手机自动拒绝未知设备输入 0000/1234在手机蓝牙设置里取消“不安全的设备”限制连接成功但收不到导航数据手机 App 外设开关未开或 SPP 通道被占用检查 App 设置确认没有将 Glimpse 识别为媒体音频设备屏幕花屏或颜色不对GC9A01 驱动配置错误或 SPI 时钟过快检查 TFT_eSPI 配置降低 SPI 频率到 20MHz 以下GPS 一直定位不到模块天线被金属遮挡或处于冷启动状态将天线朝向天空在开阔地带等待 1~2 分钟完成冷启动GPS 速度跳动剧烈高楼遮挡或滤波参数过小速度取滑动窗口中位数时间窗口拉长到 5 秒罗盘方向严重偏移未校准或安装位置附近有强磁干扰重新执行 8 字校准调整安装位置避开金属件音乐页面显示乱码编码不是 UTF-8或 JSON 解析失败统一手机端和固件端的字符编码确认使用 UTF-8骑行中蓝牙掉线距离过远、电源电压不稳增加滤波电容改用 5V 稳压模块独立供电最后再分享一个小技巧Glimpse 的代码结构其实把你逼成了一个看协议的人因为你必须亲自理解手机发来的每一帧数据格式才能真正调好它。我建议你从最简单的串口透传开始先在桌子上把整个链路通一遍再上车不要一上来就想着一步到位。这套项目做下来的价值远不止省一个几百块的摩托车导航仪钱而是让你真正搞明白一辆车上那块仪表盘背后到底在干什么。国庆假期出行前如果来得及我给限定提一个愿望把导航源调到最顺眼的那个亮度祝大家跑山平安蓝牙不断连油箱永远是满的。