1. 项目概述与核心功能
这个基于STM32的水位检测自动控制系统,是我在折腾了三个鱼缸之后设计出来的终极解决方案。作为一个养鱼爱好者,每次手动换水、调节水温都让我头疼不已。市面上的商业产品要么功能单一,要么价格离谱,于是决定自己动手打造一个全能型控制系统。
系统核心功能包括:
- 实时水位监测(超声波模块HC-SR04)
- 水温检测(DS18B20数字温度传感器)
- 自动水泵控制(继电器模块)
- 云端数据同步(ESP8266+阿里云IoT平台)
- 手机端远程监控(自研Android APP)
整套系统以STM32F103C8T6作为主控,采用FreeRTOS实现多任务调度,确保传感器数据采集、设备控制和网络通信能够并行处理。实测下来,水位检测精度可达±0.5cm,温度检测精度±0.2℃,完全满足观赏鱼养殖的需求。
2. 硬件设计与关键组件选型
2.1 主控芯片选择
选用STM32F103C8T6(蓝桥杯开发板同款)主要基于以下考量:
- 性价比突出:20元左右的价位提供Cortex-M3内核,72MHz主频
- 丰富外设:具备12位ADC、多个定时器、USART等必要接口
- 开发生态完善:HAL库成熟,社区支持好
注意:购买时认准"正品丝印",市场上存在打磨翻新片。我曾在某宝买到假货导致PWM输出异常。
2.2 水位检测方案对比
测试了三种水位检测方案后最终选定超声波模块:
| 方案类型 | 精度 | 成本 | 安装复杂度 | 抗干扰性 |
|---|---|---|---|---|
| 浮球开关 | ±2cm | 5元 | 低 | 中 |
| 压力传感器 | ±0.2cm | 80元 | 高 | 高 |
| 超声波模块 | ±0.5cm | 15元 | 中 | 中 |
HC-SR04超声波模块的驱动电路设计要点:
- VCC接5V(实测3.3V驱动距离会缩短)
- 触发信号(Trig)需>10us的高脉冲
- 回波信号(Echo)通过定时器输入捕获测量
- 添加10uF电容滤波防止电源干扰
2.3 温度传感器选型
DS18B20的优势在于:
- 单总线接口节省IO资源
- 数字输出免去ADC采样
- 防水封装可直接浸入水中
- ±0.5℃精度满足需求
硬件连接注意事项:
- 信号线需接4.7K上拉电阻
- 导线长度超过3米需改用屏蔽线
- 避免与水泵电源线平行走线
3. 软件架构与核心算法实现
3.1 FreeRTOS任务划分
系统采用多任务架构提高实时性:
c复制void StartDefaultTask(void const * argument) {
// 创建各任务
xTaskCreate(WaterLevel_Task, "Level", 128, NULL, 3, NULL);
xTaskCreate(Temperature_Task, "Temp", 128, NULL, 2, NULL);
xTaskCreate(CloudComm_Task, "Cloud", 256, NULL, 1, NULL);
xTaskCreate(PumpCtrl_Task, "Pump", 128, NULL, 4, NULL);
vTaskStartScheduler();
}
任务优先级设置原则:
- 水泵控制(最高)
- 水位检测
- 温度检测
- 云端通信(最低)
3.2 水位计算与温度补偿
超声波测距原始公式:
code复制距离(cm) = 高电平时间(us) × 声速(m/s) / 2 × 10000
加入温度补偿后的改进算法:
c复制float Get_CompensatedDistance(uint32_t echo_time, float temp) {
float sound_speed = 331.4f + 0.6f * temp; // 声速温度补偿
return (echo_time * sound_speed) / 20000.0f;
}
实测数据对比:
| 水温(℃) | 无补偿误差(cm) | 补偿后误差(cm) |
|---|---|---|
| 15 | +2.1 | +0.3 |
| 25 | +0.8 | +0.1 |
| 35 | -1.7 | -0.2 |
3.3 水泵控制逻辑优化
为防止频繁启停,采用状态机设计:
c复制typedef enum {
PUMP_OFF,
PUMP_ON,
COOLDOWN // 冷却状态
} PumpState;
void Pump_Control(float level, float temp) {
static PumpState state = PUMP_OFF;
static uint32_t last_switch = 0;
switch(state) {
case PUMP_OFF:
if(level < LOW_LEVEL && temp < 35.0f
&& HAL_GetTick() - last_switch > 30000) {
Relay_On();
state = PUMP_ON;
last_switch = HAL_GetTick();
}
break;
case PUMP_ON:
if(level > HIGH_LEVEL || temp >= 40.0f) {
Relay_Off();
state = COOLDOWN;
last_switch = HAL_GetTick();
}
break;
case COOLDOWN:
if(HAL_GetTick() - last_switch > 60000) {
state = PUMP_OFF;
}
break;
}
}
4. 云端通信与手机APP开发
4.1 阿里云IoT平台配置
关键配置步骤:
- 创建产品:选择"自定义品类"-"数据格式"选Alink JSON
- 添加设备:获取三元组(ProductKey、DeviceName、DeviceSecret)
- 定义物模型:
- 水位属性(water_level, float, cm)
- 水温属性(water_temp, float, ℃)
- 水泵状态(pump_status, bool)
三元组转换示例:
code复制username = DeviceName&ProductKey
password = 用DeviceSecret计算的签名
4.2 ESP8266通信实现
AT指令配置流程:
c复制void ESP8266_Connect() {
SendAT("AT+CWMODE=3", "OK", 1000);
SendAT("AT+CWJAP=\"SSID\",\"PASSWORD\"", "OK", 5000);
// MQTT配置
SendAT("AT+MQTTUSERCFG=0,1,\"clientID\",\""
"deviceName&productKey\",\""
"计算得到的password\"", "OK", 2000);
SendAT("AT+MQTTCONN=0,\"iot-xxx.mqtt.aliyuncs.com\",1883,1)",
"OK", 5000);
}
踩坑记录:阿里云要求clientId格式为"securemode=3,signmethod=hmacsha1,timestamp=xxx"
4.3 Android APP开发要点
核心功能实现:
- 使用MQTT客户端库(Paho Android Service)
- 数据可视化(MPAndroidChart)
- 控制指令下发(JSON格式)
关键代码片段:
java复制// 订阅主题
client.subscribe("/sys/productKey/deviceName/thing/event/property/post", 1);
// 处理消息回调
public void messageArrived(String topic, MqttMessage message) {
JSONObject json = new JSONObject(message.toString());
float level = json.getJSONObject("items")
.getJSONObject("water_level")
.getFloat("value");
// 更新UI...
}
5. 系统调试与性能优化
5.1 常见问题排查指南
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 水位数据跳变 | 超声波模块受干扰 | 1. 加装金属屏蔽罩 2. 软件中值滤波 |
| DS18B20无响应 | 时序不准确 | 1. 检查GPIO配置为高速模式 2. 用逻辑分析仪调试波形 |
| ESP8266连接失败 | 三元组错误 | 1. 使用阿里云官方工具生成 2. 检查密码签名算法 |
| 水泵频繁启停 | 水位波动大 | 1. 增加状态保持时间 2. 安装缓冲水箱 |
5.2 电源设计经验
实测发现的问题及改进:
-
初始设计:7805线性稳压
- 问题:水泵启动时电压跌落导致MCU复位
- 改进:换用DC-DC降压模块(MP2307)
-
继电器隔离:
- 原方案:光耦+三极管驱动
- 优化:改用现成继电器模块(带续流二极管)
-
布线技巧:
- 传感器信号线与电源线垂直走线
- 数字地与模拟地单点连接
- 每个IC电源引脚添加0.1uF去耦电容
5.3 系统功耗优化
通过以下措施将待机功耗从120mA降至35mA:
- 调整FreeRTOS时钟节拍从1kHz降至100Hz
- ESP8266采用深度睡眠模式(每5分钟唤醒)
- 关闭未用外设(ADC、TIM等)时钟
- 水泵控制改用MOSFET替代继电器
实测数据:
| 模式 | 电流消耗 | 持续时间占比 |
|---|---|---|
| 正常运行 | 85mA | 15% |
| 轻量运行 | 45mA | 70% |
| 深度睡眠 | 8mA | 15% |
这套系统已经稳定运行半年多,成功帮我养活了包括龙鱼、锦鲤在内的多种观赏鱼。最让我自豪的是去年出差两周,全靠手机APP远程监控和自动换水,回家时鱼儿们状态比我在家时还好!
