1. 智能水表系统的核心设计思路
用STM32做智能水表这件事,我前前后后折腾过不下十个版本。从最开始的简单流量统计,到现在带蓝牙远程控制的完整系统,踩过的坑都能写本技术手册了。这套系统的核心其实就三点:精准测量、实时显示和智能控制。
先说测量部分,水流量传感器选型特别关键。早期我用过霍尔效应的叶轮式传感器,便宜是便宜,但精度实在不敢恭维,误差能到±5%。后来换成YF-S201这种带椭圆齿轮的传感器,精度直接提升到±1%,虽然贵了三十多块钱,但实测数据靠谱多了。这里有个细节要注意:传感器的安装位置要离水泵至少30cm,否则水流湍流会影响测量准确性。
显示模块我坚持用LCD1602,不是最炫酷的,但胜在稳定。曾经试过OLED,户外强光下根本看不清,而且寿命堪忧。LCD1602的驱动也简单,四线模式接上就能用,关键是功耗只有0.5mA,比OLED省电十倍不止。
控制部分最折腾人。继电器选型就换了三次,最后锁定欧姆龙G5V-2,触点容量10A足够驱动家用增压泵。这里特别提醒:继电器的续流二极管一定要接,我有块板子没加这个二极管,一个月就把继电器触点烧黑了。
2. 硬件设计中的实战经验
2.1 核心电路设计要点
STM32F103C8T6这块芯片真是性价比之王,72MHz主频跑水表应用绰绰有余。画原理图时要注意几个关键点:
- 复位电路:10k上拉电阻+100nF电容是标配,但最好再加个手动复位按钮
- 晶振电路:8MHz主晶振的负载电容要根据芯片手册调整,我用的是22pF
- 电源滤波:每个VDD引脚都要配100nF去耦电容,靠近引脚放置
电源部分我吃过亏。最早用AMS1117-3.3,结果水表装在楼顶时夏天高温老重启。后来换成TPS7333,工作温度范围-40°C到125°C,再没出过问题。DC002插座建议选带锁紧功能的,防止电源线被意外拉扯脱落。
2.2 传感器接口设计
流量传感器接口要加硬件滤波,我的方案是:
// 硬件滤波电路参数 R1 = 10kΩ // 上拉电阻 C1 = 100nF // 滤波电容 R2 = 1kΩ // 限流电阻这个组合能有效滤除水泵启停时的干扰脉冲。信号线最好用双绞线,长度超过50cm时要加屏蔽层。
报警电路设计有个小技巧:蜂鸣器并联反向二极管。我有次忘记加,结果STM32的GPIO口被反电动势打坏了。LED报警灯要串接限流电阻,计算公式很简单:
电阻值 = (电源电压 - LED压降) / 所需电流普通LED压降约2V,电流10mA就够亮,所以3.3V系统用130Ω电阻正合适。
3. 软件实现的关键技术
3.1 流量计算算法
流量计算是核心中的核心。传感器每升水输出438个脉冲(YF-S201参数),我的做法是捕获上升沿中断:
void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { plu++; // 脉冲计数 EXTI_ClearITPendingBit(EXTI_Line0); } }瞬时流量计算要考虑时间窗口。我测试过1秒、500ms和200ms三种窗口,最终选择500ms平衡实时性和稳定性:
shunShiVal = (float)plu * 2 * 1000 / 438 / 60; // mL/s leiJiVal += shunShiVal; // 累计流量这里有个细节:变量要用unsigned long类型,否则连续运行几个月可能溢出。
3.2 蓝牙通信实现
HC-05蓝牙模块的配置最让人头疼,分享几个实用命令:
AT+NAME=WaterMeter // 设置设备名称 AT+PSWD=1234 // 设置配对密码 AT+UART=9600,0,0 // 设置波特率数据发送要控制频率,我设置为5秒一次,格式如下:
S:12.5L/m L:245.3L手机端可以用Serial Bluetooth Terminal这类APP接收数据。如果需要双向控制,建议定义简单的协议:
#ON // 打开水泵 #OFF // 关闭水泵 #SET1000 // 设置阈值为1000L4. 系统优化与故障排查
4.1 低功耗优化技巧
虽然市电供电不愁功耗,但做好低功耗设计能延长元器件寿命:
- 关闭未用外设时钟:RCC_APB2PeriphClockCmd()
- 降低主频:在初始化完成后调用SystemCoreClockUpdate()
- 睡眠模式:WFI指令让CPU休眠,用外部中断唤醒
实测下来,全速运行功耗约80mA,优化后待机时只有15mA。如果要用电池供电,可以考虑STM32L系列低功耗芯片。
4.2 常见问题解决方案
问题1:流量读数跳变
- 检查传感器供电是否稳定(建议5V±0.1V)
- 确认滤波电容焊接牢固
- 尝试减小计算时间窗口
问题2:蓝牙连接不稳定
- 确保模块天线没有被金属遮挡
- 检查电源纹波(最好加个47μF电容)
- 尝试降低通信波特率到4800
问题3:继电器误动作
- 检查GPIO初始化是否正确配置为推挽输出
- 测量线圈电压是否达到标称值的90%以上
- 在触点两端并联RC吸收电路(100Ω+0.1μF)
最后分享一个血泪教训:PCB布局时要把大电流路径(如继电器线圈)和小信号线路(如传感器)分开走线,我有块板子没注意这点,导致流量读数总是偏大10%。现在我的布线原则是:强电走左边,弱电走右边,数字模拟分区明确。