1. 项目概述
作为一名在嵌入式领域摸爬滚打多年的工程师,我最近完成了一个特别实用的宿舍智能水表系统。这个项目源于一个真实痛点:去年我们宿舍楼因为有人忘关水龙头,导致整个楼层被淹,维修费用高达上万元。这种"水漫金山"的惨剧,相信不少人都经历过。
传统水表只能机械计数,而我们的智能水表系统实现了两大创新功能:一是防忘关水自动保护,二是用水数据分析。系统以STM32F103C8T6为主控,配合YF-S201流量传感器和电磁阀,成本不到200元,却能有效解决宿舍用水管理难题。
1.1 核心需求解析
宿舍场景的用水问题主要体现在三个方面:
- 忘关水龙头导致的持续流水(常见于洗漱、洗衣后)
- 管道漏水难以及时发现
- 缺乏用水数据,无法分析异常用水行为
我们的系统设计目标很明确:
- 实时监测水流状态,当检测到异常长时间小流量(如5分钟以上)时,自动关闭阀门并报警
- 记录详细用水数据,支持时段统计和异常用水行为分析
- 系统稳定可靠,安装简便,适合宿舍环境
2. 硬件系统设计与选型
2.1 核心硬件选型思路
选型时我主要考虑三个因素:可靠性、成本、易用性。经过多次对比测试,最终确定的硬件方案如下:
2.1.1 主控芯片:STM32F103C8T6
选择这款"蓝莓派"最小系统板的原因:
- 性价比极高(约15元)
- 72MHz主频,20KB RAM,64KB Flash,性能足够
- 丰富的外设接口(3个USART、2个SPI、2个I2C)
- 多达7个定时器,非常适合脉冲计数
- 广泛的社区支持和开发资料
提示:虽然Arduino更易上手,但STM32在性能、外设和价格上更有优势,适合需要精确计时和复杂逻辑的项目。
2.1.2 流量传感器:YF-S201
这款霍尔式流量计的特点:
- 测量范围0.3-60L/min,精度±10%
- 输出脉冲信号(每升水约450个脉冲)
- 工作压力≤1.75MPa,适合自来水系统
- 黄铜壳体,耐用性好
- 价格约25元,性价比突出
实测中发现,脉冲信号在低流量时会有抖动,需要在软件中做消抖处理。
2.1.3 水路控制:DC12V常闭电磁阀
选用常闭型电磁阀的考虑:
- 断电自动关闭,安全性高
- 工作压力0.02-0.8MPa
- 接口尺寸DN15(1/2英寸),通用性强
- 功耗约5W,需配合继电器使用
- 价格约35元
2.2 辅助模块选型
2.2.1 无线通信:ESP8266-01S
选用这款WiFi模块的原因:
- 支持802.11 b/g/n协议
- 内置TCP/IP协议栈
- 串口AT指令控制,开发简单
- 价格仅12元左右
2.2.2 电源方案
系统需要三种电压:
- 电磁阀:12V/1A
- STM32:5V/500mA
- 其他模块:3.3V/300mA
最终采用:
- 12V/2A电源适配器(主供电)
- LM2596降压模块(12V→5V)
- AMS1117-3.3(5V→3.3V)
2.3 硬件连接要点
完整的接线示意图如下:
code复制[水流方向]
水管 → YF-S201传感器 → 电磁阀 → 出水口
[电路连接]
12V电源 → LM2596(5V) → STM32
│
└─ 继电器 → 电磁阀
YF-S201 → STM32 PA0(脉冲输入)
ESP8266 → STM32 USART1
蜂鸣器 → STM32 PB8
LED指示灯 → STM32 PB9
特别注意:
- 电磁阀要加续流二极管(1N4007)
- WiFi模块的RX/TX要接STM32的TX/RX
- 流量传感器信号线要加上拉电阻(10KΩ)
- 所有信号线长度不超过50cm,避免干扰
3. 软件设计与实现
3.1 系统软件架构
整个系统采用模块化设计,主要包含以下功能模块:
- 流量检测与计算
- 异常用水判断
- 电磁阀控制
- 数据记录与统计
- WiFi通信
- 用户提示(声光报警)
3.2 核心算法实现
3.2.1 流量计算算法
YF-S201的输出是脉冲信号,需要转换为实际流量:
c复制// 定义常量
#define PULSES_PER_LITER 450 // 每升水对应的脉冲数
// 中断服务程序
void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
pulse_count++;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
// 计算瞬时流量(L/min)
float get_instant_flow() {
uint32_t current_count = pulse_count;
pulse_count = 0;
float flow = (current_count * 60.0) / PULSES_PER_LITER;
return flow;
}
这个算法通过定时器中断每1秒采集一次脉冲数,转换为瞬时流量。
3.2.2 异常用水判断逻辑
防忘关水的核心是识别异常小流量持续:
c复制#define MIN_FLOW_THRESHOLD 0.5 // 最小流量阈值(L/min)
#define MAX_DURATION 300 // 最大允许持续时间(秒)
void check_abnormal_flow() {
float flow = get_instant_flow();
if(flow > MIN_FLOW_THRESHOLD) {
if(!is_flowing) {
is_flowing = 1;
start_time = get_current_time();
} else {
if(get_current_time() - start_time > MAX_DURATION) {
trigger_alarm();
close_valve();
}
}
} else {
is_flowing = 0;
}
}
3.2.3 用水数据统计
用水数据按小时和天两个维度统计:
c复制typedef struct {
uint32_t daily_use[24]; // 每小时用水量(mL)
uint32_t total_day; // 当日总用水量(mL)
uint32_t avg_day; // 日均用水量(mL)
uint32_t max_day; // 单日最大用水量(mL)
} WaterUsageData;
void update_water_stats(float flow) {
uint8_t current_hour = get_current_hour();
water_data.daily_use[current_hour] += (uint32_t)(flow * 1000 / 60); // mL
// 每天0点重置数据
if(current_hour == 0 && !is_reset) {
water_data.total_day = 0;
for(int i=0; i<24; i++) {
water_data.total_day += water_data.daily_use[i];
}
update_history_data();
memset(water_data.daily_use, 0, sizeof(water_data.daily_use));
is_reset = 1;
} else if(current_hour != 0) {
is_reset = 0;
}
}
3.3 WiFi通信实现
ESP8266通过AT指令与STM32通信,实现数据上传:
c复制void wifi_send_data() {
char buffer[128];
sprintf(buffer, "{\"flow\":%.2f,\"total\":%lu}", current_flow, water_data.total_day);
USART_SendString(USART1, "AT+CIPSTART=\"TCP\",\"192.168.1.100\",8080\r\n");
delay_ms(1000);
USART_SendString(USART1, "AT+CIPSEND=");
USART_SendString(USART1, itoa(strlen(buffer), temp, 10));
USART_SendString(USART1, "\r\n");
delay_ms(500);
USART_SendString(USART1, buffer);
USART_SendString(USART1, "\r\n");
}
服务器端可以用Node.js搭建一个简单的HTTP服务接收数据。
4. 系统调试与优化
4.1 硬件调试要点
-
流量传感器安装:
- 必须水平安装,箭头方向与水流一致
- 前后需保留10cm直管段
- 初次使用需通水冲洗内部杂质
-
电磁阀测试:
- 先手动通电测试开关是否正常
- 注意水压不能超过额定值
- 开关频率不宜过高(间隔>3秒)
-
电源测试:
- 满载时测量各电压点是否稳定
- 注意LM2596的散热问题
4.2 软件调试技巧
-
流量校准:
- 用已知容量的容器(如1L矿泉水瓶)接水
- 记录脉冲数,调整PULSES_PER_LITER值
- 重复3次取平均值
-
异常判断优化:
- 增加流量波动过滤(移动平均算法)
- 不同时段设置不同阈值(如夜间阈值更低)
-
数据存储优化:
- 重要数据写入Flash时先擦除整个扇区
- 采用备份扇区机制防止数据丢失
4.3 实测性能数据
经过一周的实测,系统表现如下:
| 指标 | 数值 | 说明 |
|---|---|---|
| 流量检测误差 | ±3% | 1-30L/min范围内 |
| 响应时间 | <2s | 从异常到关阀 |
| 电磁阀寿命 | >10万次 | 每天开关20次计算 |
| WiFi丢包率 | <1% | 信号强度>70%时 |
| 系统功耗 | <5W | 待机时约2W |
5. 常见问题与解决方案
5.1 硬件相关问题
Q1:流量计读数不稳定怎么办?
- 检查安装方向是否正确
- 增加RC滤波电路(100Ω+0.1μF)
- 软件端采用中值滤波算法
Q2:电磁阀无法关闭?
- 检查继电器触点是否烧蚀
- 测量线圈电阻(正常约80Ω)
- 确认电源功率足够(启动电流约0.5A)
5.2 软件相关问题
Q1:WiFi频繁断开连接?
- 增加心跳包机制(每30秒发送AT指令)
- 设置硬件看门狗
- 优化天线位置(远离金属管道)
Q2:数据统计不准确?
- 检查RTC时钟是否正常
- 增加数据校验机制
- 关键变量使用volatile修饰
5.3 系统优化建议
- 增加电池备份,断电时保存关键数据
- 开发手机APP实时查看用水情况
- 加入机器学习算法,更精准识别用水模式
- 电磁阀改为电动球阀,降低水锤效应
6. 项目总结与展望
这个宿舍智能水表系统经过三个月的开发和测试,已经在我们宿舍楼稳定运行了半年,成功预防了5次忘关水龙头事件,月均节水约3吨。系统硬件成本约180元,安装简单,适合推广到学生宿舍、公寓等场景。
在实际部署中,有几点经验值得分享:
- 电磁阀要定期手动开关几次,防止结垢卡死
- 冬季要注意管道保温,防止冻裂
- WiFi信号强度对系统稳定性影响很大,必要时可改用4G模块
- 数据统计功能要预留足够的存储空间
未来如果增加水质监测、漏水检测等功能,系统的实用价值会更高。不过现有版本已经很好地解决了宿舍用水管理的主要痛点,是一个性价比很高的物联网应用实例。