1. 项目背景与核心需求
在自行车改装和电动车维修领域,精准测量行驶速度和累计里程一直是个硬需求。传统机械式码表存在结构复杂、易磨损、读数不准等问题,而市面上成品电子码表又往往价格偏高且功能固化。这个项目就是要用最基础的单片机方案,打造一个成本控制在30元以内,但精度能达到商用级水平的DIY速度里程表。
我选择STM8S003F3作为主控,这颗国产MCU价格不到2块钱,却有16MHz主频和10位ADC,完全能满足采样需求。传感器方面用了常见的霍尔元件,每转输出一个脉冲,成本仅1.5元。显示部分用了0.96寸OLED,比LCD更省电且可视角度大。整套方案算上PCB和外壳,BOM成本可以控制在25元左右。
2. 硬件设计关键点
2.1 传感器信号采集电路
霍尔传感器输出的脉冲信号需要经过两级处理:首先用1uF电容并联10k电阻做硬件消抖,防止车轮震动导致误触发;然后通过LM393比较器转换成规整的方波,比较器参考电压设为电源电压的1/3,这样既能过滤噪声又不会丢失有效信号。实测在30km/h速度下(相当于每秒5个脉冲),这套电路可以稳定识别到每个轮辐经过的瞬间。
注意:霍尔元件安装位置要距离磁铁3-5mm,太近会导致信号幅值饱和,太远又可能检测不到
2.2 低功耗设计技巧
虽然OLED本身功耗不高,但为了延长纽扣电池续航,我做了这些优化:
- 单片机平时工作在Halt模式,仅用外部中断唤醒
- 显示刷新率从默认的60Hz降到10Hz
- 速度低于1km/h超过5分钟自动关闭背光
实测采用CR2032供电时,连续工作时间可达6个月以上。电路板上特别设计了电池电压检测功能,当电压低于2.7V时会在屏幕右上角显示低电量图标。
3. 软件算法实现
3.1 速度计算模型
假设车轮周长L=2.1米(26寸山地车常见值),磁铁数量N=1。当检测到两个脉冲的时间间隔为Δt秒时,实时速度V计算公式为:
code复制V = (L/N) / Δt * 3.6 (单位km/h)
在代码中采用定时器捕获模式记录脉冲间隔,为了避免瞬时波动,实际采用滑动窗口均值滤波:保存最近5个Δt值求平均。测试数据显示,这种方法在加速/减速工况下仍能保持±0.5km/h的精度。
3.2 里程累计策略
每次检测到脉冲时,累计里程S增加一个固定值:
code复制ΔS = L/N
为了防止断电数据丢失,每行驶满1公里就将当前里程值写入EEPROM。这里有个细节要注意:STM8的EEPROM有10万次擦写寿命限制,所以不能每次脉冲都保存。实际测试中,按每天骑行20公里计算,EEPROM可以稳定使用13年以上。
4. 制作与调试要点
4.1 PCB布局注意事项
- 霍尔信号走线要尽量短,且远离电机等干扰源
- 电池正极建议铺铜加粗,避免大电流时电压跌落
- OLED接口最好用1.27mm间距的4pin插座,比直接焊接更便于维修
4.2 校准流程
- 测量实际车轮周长:在地上做标记,推动自行车完整转一圈测量距离
- 在代码config.h中修改#define WHEEL_CIRCUMFERENCE值
- 用手机GPS测速作为基准,调整软件滤波参数
- 测试急加速/急刹车时的响应延迟,优化算法参数
5. 性能优化记录
第一版设计存在两个明显问题:一是上电时偶尔会显示乱码,后来发现是OLED初始化时序问题,在复位电路加了10ms延时解决;二是低温环境下(-10℃)会出现速度跳变,通过给比较器添加正反馈形成迟滞比较特性后改善明显。
速度更新频率从最初的1Hz逐步优化到现在的2Hz,这个刷新率在视觉上已经足够流畅,同时避免了频繁刷新导致的OLED残影问题。实测数据与专业码表对比,在0-40km/h范围内误差小于3%,完全满足日常使用需求。
6. 扩展功能实现
基于这个基础框架,可以很方便地添加新功能:
- 通过长按按键切换显示模式(当前速度/平均速度/最大速度)
- 增加蓝牙模块上传骑行数据到手机
- 改用无磁铁方案,利用STM8的AWU功能实现自动唤醒计数
- 添加坡度检测功能(需要增加MPU6050传感器)
实际制作时发现,0.96寸OLED在强光下可视性不够好,后来改用反射式LCD虽然成本高了5元,但在户外阳光下显示效果提升明显。这也是DIY项目的优势——可以根据具体需求灵活调整方案。