1. 项目概述:STM32水质监测系统全栈开发实录
去年帮本地水产养殖场部署了一套水质监测系统,从电路设计到嵌入式开发全流程走了一遍。这个项目用STM32F103C8T6作为主控,搭配TDS、PH、浊度等多传感器模块,实现了水体关键指标的实时采集与无线传输。整套系统包含硬件设计(原理图+PCB)、Proteus仿真验证、嵌入式程序开发三个核心部分,最终成本控制在200元以内,比市面同类设备便宜60%以上。
这套方案特别适合中小型水产养殖、家庭鱼缸监控、实验室水质分析等场景。如果你正打算自己动手做一套低成本水质监测设备,这篇文章会带你完整走通从电路设计到代码烧录的全流程,所有设计文件都已开源。
2. 硬件设计详解
2.1 核心传感器选型
水质监测的准确性首先取决于传感器性能。经过实测对比,最终选定了这三个关键模块:
| 传感器类型 | 型号 | 测量范围 | 精度 | 接口方式 |
|---|---|---|---|---|
| PH值 | PH-4502C | 0-14PH | ±0.1PH | 模拟电压 |
| TDS | TDS Meter V1.0 | 0-1000ppm | ±10% | 数字信号 |
| 浊度 | TS-300B | 0-1000NTU | ±5% | 模拟电压 |
实操心得:PH传感器需要定期校准(建议每周一次),校准液要选用4.01、6.86、9.18三种标准缓冲液。TDS探头使用时要注意避免气泡附着,否则读数会严重失真。
2.2 主控电路设计
采用STM32F103C8T6最小系统板作为核心,其硬件设计要点包括:
-
电源部分:通过AMS1117-3.3将输入电压(5V-12V)转换为3.3V,需注意:
- 输入电容:10μF钽电容(耐压16V)
- 输出电容:22μF MLCC+0.1μF去耦电容
- 在Vin脚并联1N4007防反接二极管
-
传感器接口电路:
c复制// PH传感器接口示例 void PH_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; HAL_ADC_Init(&hadc1); sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); } -
PCB布局关键点:
- 模拟信号走线远离数字线路
- 传感器供电采用独立LDO(如HT7350)
- 所有接口添加TVS二极管防护
3. 软件系统实现
3.1 数据采集处理算法
传感器原始数据需要经过多重处理才能得到准确值:
-
PH值计算公式:
c复制float Get_PH_Value(float adc_voltage) { // 温度补偿系数(需根据实际校准调整) const float k = 0.0185; float ph_value = 7.0 + ((2.5 - adc_voltage) / k); return ph_value; } -
滑动滤波算法实现:
c复制#define FILTER_LEN 10 float moving_filter(float new_val) { static float buffer[FILTER_LEN] = {0}; static uint8_t index = 0; float sum = 0; buffer[index++] = new_val; if(index >= FILTER_LEN) index = 0; for(int i=0; i<FILTER_LEN; i++) sum += buffer[i]; return sum/FILTER_LEN; }
3.2 无线传输模块
选用ESP8266-01S实现WiFi数据传输,关键配置步骤:
-
AT指令初始化流程:
code复制AT+RST AT+CWMODE=1 AT+CWJAP="SSID","password" AT+CIPSTART="TCP","192.168.1.100",8080 AT+CIPSEND=48 -
数据包协议设计:
json复制{ "device_id": "WQ001", "timestamp": 1634567890, "ph": 7.2, "tds": 350, "turbidity": 12.5, "temp": 25.3 }
4. 系统集成与调试
4.1 Proteus仿真验证
在硬件制作前,先用Proteus进行功能验证:
-
仿真模型配置:
- STM32F103C8T6:设置晶振8MHz
- 虚拟终端:波特率115200
- ADC参考电压:3.3V
-
常见仿真问题解决:
- 如果ADC读数异常,检查"Analog Options"中的采样频率
- WiFi模块连接超时需调整仿真时钟速度
4.2 实际环境测试数据
在鱼缸环境中的实测数据对比:
| 时间点 | PH值 | TDS(ppm) | 浊度(NTU) | 温度(℃) |
|---|---|---|---|---|
| 08:00 | 7.1 | 320 | 15 | 24.5 |
| 12:00 | 7.3 | 335 | 18 | 26.1 |
| 16:00 | 7.0 | 310 | 20 | 25.8 |
避坑指南:当多个传感器同时工作时,建议采用分时供电策略(用MOS管控制电源),避免相互干扰导致读数跳变。
5. 项目优化方向
在实际部署中总结了几个改进点:
-
低功耗优化:
- 将采集间隔从1秒改为30秒
- 启用STM32的STOP模式
- 改用NB-IoT传输方案
-
校准流程自动化:
c复制void Auto_Calibrate_PH(void) { printf("放入PH4.01标准液后按任意键..."); getchar(); float ph4 = Read_ADC_Avg(100); printf("放入PH9.18标准液后按任意键..."); getchar(); float ph9 = Read_ADC_Avg(100); Save_Calibration_Param(ph4, ph9); } -
外壳设计建议:
- 使用IP68防水盒
- 传感器探头朝下安装
- 预留太阳能板接口
这个项目最让我意外的是TDS传感器的温度影响——水温每变化1℃,读数会有约2%的偏差。后来在代码里添加了温度补偿算法,精度才达到实用要求。所有设计文件和源码都已打包,包括Altium Designer工程、Keil MDK项目和完整的API文档。
