1. 项目背景与核心功能
自行车作为绿色出行工具在城市通勤和健身运动中越来越普及,但传统机械码表存在安装复杂、功能单一、数据记录不便等问题。这个基于单片机的智能检测系统正是为了解决这些痛点而生。
我在实际骑行中发现,市面上大多数码表要么功能简陋只能显示基础速度,要么价格昂贵集成一堆用不上的功能。于是决定自己开发一套具备以下核心功能的系统:
- 实时速度检测(精度±0.5km/h)
- 累计里程统计(自动存储断电不丢失)
- 超速声光报警(阈值可自定义设置)
- 数据LCD显示(带背光夜间可视)
这套系统的独特之处在于将工业级霍尔传感器应用于民用领域,配合STM32F103C8T6单片机的强大处理能力,在保证测量精度的同时实现了成本控制(BOM成本<50元)。经过三个月的实地测试,在20-50km/h速度范围内表现稳定,特别适合通勤族和骑行爱好者DIY改装。
2. 硬件系统设计详解
2.1 核心器件选型对比
主控芯片选型时我对比了三种方案:
-
STM32F103C8T6(最终选择)
- 72MHz主频满足实时计算需求
- 内置12位ADC便于信号采集
- 20KB RAM足够存储历史数据
- 市场价格仅8-10元
-
ATmega328P(Arduino方案)
- 16MHz主频略显不足
- 需要外接EEPROM存储里程
- 优势是开发环境简单
-
ESP8266(WiFi方案)
- 无线功能在本项目中非必需
- 功耗较高影响电池续航
- 适合需要联网的场景
经验提示:不要盲目追求高性能,要根据实际需求选择。STM32的性价比在本项目中完胜。
2.2 传感器安装方案
采用3144霍尔传感器检测磁铁信号,安装时需注意:
- 前轮辐条安装钕磁铁(直径5mm足够)
- 传感器固定在前叉内侧,间距控制在3-5mm
- 使用3M VHB胶带防水防震
- 信号线沿刹车线走线并用扎带固定
实测数据:车轮周长设定为2.1米(需实际测量),每检测到一次磁信号即计为转一圈。为提高精度,建议在轮圈均匀布置3块磁铁,这样采样频率可提升3倍。
2.3 电路设计关键点
电源部分采用TP4056充电模块+18650锂电池方案:
- 持续工作电流约35mA
- 2000mAh电池可续航50小时
- 充电口使用Micro USB通用接口
显示模块选用0.96寸OLED(SSD1306驱动):
- 对比度高于LCD屏
- 功耗仅0.08W
- 可视角度达160°
报警电路由有源蜂鸣器(5V/15mA)和3mmLED组成,通过三极管驱动。特别注意要加装1N4007续流二极管保护电路。
3. 软件算法实现
3.1 速度计算核心逻辑
速度计算采用时间窗口法,在定时器中断中实现:
c复制#define WHEEL_CIRCUMFERENCE 2.1 // 单位:米
#define MAGNET_NUM 3
volatile uint32_t lastTime = 0;
volatile float currentSpeed = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
uint32_t currTime = HAL_GetTick();
uint32_t interval = currTime - lastTime;
if(interval > 50) { // 过滤异常信号
currentSpeed = (WHEEL_CIRCUMFERENCE * 3600) / (interval * MAGNET_NUM);
lastTime = currTime;
}
}
算法特点:
- 使用硬件定时器捕获下降沿触发
- 加入50ms防抖滤波
- 单位转换为km/h
- 三磁铁配置提升采样率
3.2 里程存储策略
里程数据存储在STM32内部Flash的最后一页(防止被程序擦除):
- 每次骑行结束保存累计值
- 上电时读取历史数据
- 采用CRC16校验防止数据错误
- 理论擦写寿命1万次(按每天保存1次可用27年)
关键代码:
c复制#define FLASH_PAGE_ADDR 0x0801F800
void saveOdometer(float km) {
uint32_t data = (uint32_t)(km * 1000); // 转换为米存储
uint16_t crc = CRC16_Calc((uint8_t*)&data, 4);
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef erase = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.PageAddress = FLASH_PAGE_ADDR,
.NbPages = 1
};
HAL_FLASHEx_Erase(&erase, NULL);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_PAGE_ADDR, data);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_PAGE_ADDR+4, crc);
HAL_FLASH_Lock();
}
3.3 报警功能实现
超速报警采用双阈值设计:
- 初级预警(如25km/h):LED慢闪
- 严重超速(如30km/h):LED快闪+蜂鸣器鸣响
阈值可通过长按按键进入设置模式调整,参数同样保存在Flash中。特别加入了速度滞后比较算法,防止阈值附近频繁切换报警状态。
4. 制作与调试要点
4.1 PCB设计注意事项
- 霍尔传感器信号线要短(<20cm)
- 电源部分增加100μF电解电容滤波
- 所有IO口串联220Ω电阻保护
- 预留SWD调试接口
- 使用嘉立创EDA设计四层板:
- 顶层:信号线
- 内层1:GND平面
- 内层2:3.3V电源
- 底层:元器件布局
4.2 防水处理方案
- 电路板整体喷涂三防漆
- 接缝处使用704硅橡胶密封
- OLED屏加装透明亚克力保护罩
- 电池仓用防水胶圈密封
- 所有线材出口点热缩管包覆
4.3 实测性能数据
测试环境:26寸山地车,胎压50PSI
| 速度标准值(km/h) | 系统测量值(km/h) | 误差率 |
|---|---|---|
| 15 | 15.2 | +1.3% |
| 25 | 24.8 | -0.8% |
| 35 | 35.6 | +1.7% |
| 45 | 44.3 | -1.6% |
5. 常见问题解决方案
5.1 信号检测不稳定
现象:速度显示忽快忽慢
排查步骤:
- 检查磁铁与传感器间距(应3-5mm)
- 测量传感器输出波形(应有清晰的方波)
- 检查电源电压(需稳定5V)
- 软件增加数字滤波(推荐中值滤波)
5.2 里程数据丢失
可能原因:
- Flash写入前未擦除
- 供电突然中断
- CRC校验失败
解决方案: - 实现双备份存储
- 增加超级电容保持供电
- 每次写入验证数据
5.3 功耗过高
优化措施:
- 启用STM32睡眠模式(可降耗至2mA)
- OLED设置自动息屏(30秒无操作)
- 改用SGM6603升压芯片(效率93%)
- 选择低功耗蜂鸣器(3mA版本)
6. 功能扩展方向
这套基础系统还可以进一步升级:
- 蓝牙传输:添加HC-05模块连接手机APP
- GPS轨迹:集成ATGM336H模块记录路径
- 踏频检测:增加第二个霍尔传感器
- 太阳能供电:加装5V/1W光伏板
- 语音提示:使用SYN6288语音芯片
我在实际使用中发现,最实用的扩展是增加一个微型振动马达,当速度超过设定值时不仅有声光报警,车把还会震动,这在嘈杂环境中特别有效。这个改装只需增加一个NPN三极管和5mm振动电机(成本约2元),硬件连接如下:
code复制MCU_IO → 1kΩ电阻 → 8050三极管基极
三极管集电极接电机,发射极接地
电机并联1N4148二极管