ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

STM32F103水质检测系统:PH/TDS/温度三参数可部署方案

2026/9/21 3:03:51 拓冰建站 浏览量
STM32F103水质检测系统:PH/TDS/温度三参数可部署方案 1. 这不是个“玩具项目”而是一套能真正在鱼缸、水培箱、小型养殖池里跑起来的水质监测系统我做STM32项目快十二年了从最早用JTAG烧录器在实验室焊板子到现在带团队做工业级传感器节点见过太多“开源项目”——代码能编译仿真波形漂亮原理图看着规整但一接真实探头就掉线一连串口就乱码一上电就复位。这次这个“STM32水质检测系统”我把它从嘉立创打样、探头校准、现场泡水72小时实测全走了一遍不是Demo是能当工具用的完整闭环方案。核心关键词就三个STM32、水质检测、可部署。它不讲虚的“物联网云平台对接”不堆砌“AI水质预测模型”而是聚焦在——怎么让F103C8T6这颗成本不到8块钱的芯片稳稳读出PH、TDS、温度三路模拟信号抗住水汽冷凝干扰把数据存进内部Flash不丢还能用串口吐给手机APP或上位机。适合两类人一是电子/自动化专业学生做毕设原理图和代码直接抄作业Keil5工程里连main.c都给你分好模块二是小型水产养殖户或家庭水培爱好者想自己搭个低成本监控不用买动辄上千的商用仪表。整个系统没用任何加密芯片、没上RTOS、没接WiFi模组就是最朴素的裸机架构硬件滤波软件滑动平均断电保护存储但恰恰是这种“土办法”在潮湿、温差大、供电不稳的真实环境里活得最久。下面所有内容都是我在鱼塘边蹲着调参、在实验室用盐水反复泡探头、在嘉立创改到第三版PCB后总结出来的硬经验。2. 系统整体设计与思路拆解为什么放弃“高大上”选择“扛造”2.1 选型逻辑F103C8T6不是妥协而是精准匹配很多人看到“水质检测”第一反应是上F4系列甚至H7觉得要算FFT、跑浮点运算。但实际测过就知道PH探头输出是毫伏级直流信号0-14pH对应-414mV~414mVTDS传感器本质是交流激励的电导率换算频率固定在1kHz温度用NTC或DS18B20都是单点采样。这些全是低速、低精度、强抗干扰需求的场景。F103C8T6的ADC12位±1LSB INL、定时器支持PWM输出驱动TDS激励源、GPIO推挽/开漏可配完全够用。关键优势在于成本压到极致单片机晶振复位电路BOM总成本控制在12元内批量1k开发链路成熟Keil5ST-Link V2调试零门槛学生用笔记本就能撸外设资源刚好3个ADC通道PH/TDS/Temp、1个USART调试数据输出、1个TIMTDS方波发生、1个I2C可扩展OLED屏。我试过F407ADC采样率提上去了但噪声反而更大——因为高频数字电路干扰模拟前端最后还得加更厚的屏蔽罩成本翻倍。F103的“慢”反而是稳定性的保障。2.2 信号链设计不靠算法补硬件缺陷先从源头掐死干扰水质检测最大的坑不是代码写错是信号被污染。PH电极在水中会形成原电池输出阻抗高达10^9ΩTDS传感器两极间有微弱电流温度NTC受潮后阻值漂移。所以整个信号链设计原则就一条模拟部分越简单越好数字部分越鲁棒越好。PH通道采用两级运放调理。第一级用TI的OPA333零漂移、超低输入偏置电流200fA做电压跟随隔离高阻抗第二级用LM358做2倍增益放大把-414mV~414mV映射到0~3.3V。中间加100nF陶瓷电容滤高频10kΩ可调电阻校准零点。这里坚决不用仪表放大器——虽然AD620性能好但失调电压温漂大水温变化时零点飘得厉害。TDS通道不用现成模块自己用STM32的TIM1_CH1输出1kHz方波占空比50%经MOSFETAO3400驱动探头再用运放TL072做跨阻放大把微安级电流转成电压。好处是频率精准可控避免商用模块谐振失真激励幅度可调适配不同电导率范围且省掉外部晶振。温度通道NTC10KB3950精密10kΩ贴片电阻分压直接进ADC。不接DS18B20——单总线在潮湿环境易受干扰且转换时间长750ms影响采样周期。提示所有模拟地AGND和数字地DGND在单点电源入口处用0Ω电阻连接PCB铺铜时AGND区域单独分割绝不和DGND混铺。这是实测下来降低ADC噪声最有效的一招。2.3 存储与通信不追求“实时上云”先保证本地数据不丢很多开源项目把精力全花在ESP8266联网上结果探头数据还没读准WiFi就断了。本系统通信只做两件事本地存储用STM32内置Flash模拟EEPROM基于ST官方AN2594应用笔记划分2KB扇区存历史数据。每30分钟存一次PH/TDS/Temp/时间戳最多存1000条约21天。关键设计写入前先校验CRC16失败则重试3次3次都失败则标记该条数据无效跳过后续处理。串口输出USART1配置为115200bps8N1无流控。协议极简$DATA,PH:7.23,TDS:128,TEMP:25.6,TS:1678890123*AB\r\n末尾AB为校验和。上位机用Python写个5行脚本就能解析手机端用“串口调试助手”APP直连。放弃SD卡——潮湿环境下接触不良率太高放弃蓝牙——功耗大且配对不稳定放弃LoRa——小范围监测没必要。实测下来一根USB-TTL线连电脑比任何无线方案都可靠。3. 核心细节解析与实操要点从原理图到代码的每一处“坑”3.1 原理图关键设计嘉立创EDA开源文件已验证原理图不是“画出来就行”每个器件选型都有实测依据。以下是必须抠细节的5个位置PH电极接口用三芯航空插头带屏蔽层屏蔽层单端接地接AGND信号线用双绞线。PCB上PH_IN走线全程包地宽度0.2mm长度15mm。曾因走线过长导致50Hz工频干扰叠加后ADC读数跳±0.5pH。TDS激励源MOSFET AO3400的栅极串联100Ω电阻防振荡源极接GND漏极串100Ω限流电阻后接探头。实测发现不用限流电阻时探头极化严重TDS值随时间衰减。ADC参考电压不用VDDA3.3V改用REF30333.3V精密基准源输出经RC滤波10uF钽电容100Ω后供ADC。VDDA波动100mV时REF3033输出纹波仅0.5mV。复位电路采用STM32标准复位方案10kΩ上拉100nF电容TVS管SM712但增加一个细节RESET引脚旁并联10pF电容到GND抑制高频干扰引发的误复位。鱼塘边雷击后这套方案比纯RC复位故障率低90%。电源滤波AMS1117-3.3输入端用47uF电解100nF陶瓷输出端用22uF钽电容1uF陶瓷。特别注意钽电容正极必须朝向AMS1117输出端反接会爆炸我炸过两颗教训深刻。3.2 代码结构与关键函数实现Keil5工程已开源代码不是堆砌而是按功能分层。整个工程目录如下Src/ ├── main.c // 系统初始化、主循环 ├── adc.c // ADC采集含校准、滤波 ├── tds_driver.c // TDS激励与采样含相敏检波 ├── ph_calibrate.c // PH探头两点校准标定液pH4.01/pH6.86 ├── flash_emu.c // Flash模拟EEPROM擦写寿命管理 ├── usart1.c // 串口协议封装 └── utils.c // CRC16、字符串解析等工具函数最核心的三个函数ADC_GetValue()开启ADC连续扫描模式采样16次后取中值滑动平均窗口5。重点在校准每次上电执行ADC_Calibration()用内部参考电压Vrefint校准ADC增益误差。实测未校准时同一PH值读数偏差达±0.15pH。TDS_Read()TIM1输出1kHz方波→探头→运放输出→ADC采样。关键在相敏检波用另一个TIM2捕获ADC采样时刻只取方波正半周对应的ADC值剔除负半周噪声。否则TDS值波动±20ppm。FLASH_WriteData()写入前先检查目标扇区是否为空读0xFFFF若非空则执行FLASH_EraseSector()。擦写次数计数存在Flash最后一页每次擦写更新计数超10000次则报警Flash寿命理论值10000次实测8000次后出现坏块。注意所有ADC采样必须在__disable_irq()下进行否则中断打断采样序列导致数据错位。我在调试时发现串口接收中断偶尔会触发ADC中断嵌套最终在ADC初始化里关闭了所有NVIC中断优先级。3.3 仿真验证Proteus不是万能的但能筛掉80%硬件错误用Proteus做仿真不是为了“看起来像”而是提前暴露硬件设计缺陷。本系统仿真重点验证三件事PH信号链在Proteus里用DC电压源模拟PH电极-414mV~414mV接入OPA333LM358电路用虚拟示波器看输出是否线性。发现LM358在轨到轨输出时接近0V和3.3V会有100mV压降于是把放大倍数从2改为1.8留出余量。TDS激励用Proteus的“Signal Generator”替代TIM1输出1kHz方波接虚拟探头RLC网络模拟电导率验证跨阻放大输出幅值是否随电导率线性变化。Flash擦写Proteus不支持Flash仿真但可用内存模拟。在flash_emu.c里加宏定义#define SIMULATE_FLASH把Flash操作重定向到RAM数组验证擦写逻辑和CRC校验是否正确。实操心得Proteus仿真必须配合真实探头测试。我曾仿真完美但实测PH值漂移——原因是仿真没考虑电极响应时间实际需15秒稳定于是在代码里加了delay_ms(15000)等待。4. 实操过程与核心环节实现从焊接第一颗电阻到泡水72小时4.1 PCB打样与焊接嘉立创2层板的“生存指南”PCB用嘉立创2层板1.6mm厚FR4尺寸80×50mm。关键工艺要求阻焊层全板绿油但PH/TDS探头接口焊盘露铜方便焊接屏蔽线丝印所有测试点TP1-TP5标注清晰VCC/GND用粗字体过孔所有电源过孔用0.5mm直径数量≥6个降低热阻铺铜AGND区域铺满但避开PH信号走线3mmDGND区域用网格铺铜减少高频辐射。焊接顺序严格按先贴片电阻电容→再IC→最后插件接口。特别注意OPA333的8脚SOIC封装焊锡量必须精准多一滴就短路AMS1117的散热片必须紧贴PCB铜皮涂导热硅脂我用的是TG-8801导热系数1.2W/mKUSB-TTL芯片CH340G的晶振12MHz离芯片越近越好走线加地线包围。踩过的坑第一次打样没加TVS管雷雨天烧毁3块板。第二次在USB接口前端加SM712再没出过问题。4.2 探头校准没有标定液就别谈精度PH和TDS探头出厂有误差必须现场校准。工具清单PH标定液pH4.01邻苯二甲酸氢钾 pH6.86磷酸盐各100mlTDS标定液1413μS/cmKCl溶液温度计精度±0.1℃的数字温度计。PH校准步骤用pH6.86液浸泡电极10分钟读取稳定值如6.72在ph_calibrate.c里修改PH_CAL_686_OFFSET 6.86 - 6.72 0.14换pH4.01液读取值如3.95计算斜率PH_SLOPE (4.01-3.95)/(6.86-6.72) 0.428写入Flash保存参数。TDS校准用1413μS/cm液调节TDS_CAL_FACTOR使读数1413。注意校准必须在25℃恒温下进行温度偏差1℃TDS值偏差约2%。4.3 泡水实测72小时不间断记录的真相把装好探头的PCB放进20L水箱自来水食盐调TDS每天记录3次第1天TDS从120ppm升至135ppm探头极化PH从7.23降至7.18第2天TDS稳定在138ppmPH回升至7.21电极活化完成第3天所有数据波动±0.02pH、±2ppmFlash存储无丢帧。关键发现水面蒸发导致水位下降探头露出水面时TDS读数归零——于是在代码里加水位检测用浮球开关水位低时停采样并报警夜间温度下降2℃NTC读数滞后10分钟——改用滑动平均窗口从5扩大到20平滑响应。实测结论系统连续运行72小时无复位、无数据丢失、无探头漂移满足家庭水培日常监测需求。5. 常见问题与排查技巧实录那些手册里不会写的“血泪经验”5.1 典型问题速查表现象可能原因排查步骤解决方案PH读数始终为0PH电极未接通/运放供电异常用万用表测OPA333的V、V-、Vout电压检查PH接口焊点确认VDDA3.3VTDS值跳变剧烈激励方波失真/探头接触不良示波器测TIM1_CH1输出波形检查AO3400栅极电阻清洁探头铂金片串口无输出USART1引脚配置错误/电平不匹配用逻辑分析仪抓TXD波形确认PA9/PA10复用功能开启TXD接USB-TTL的RXDFlash存储失败扇区未擦除/写入地址越界在FLASH_WriteData()加调试打印用ST-Link Utility读Flash确认目标地址为0xFFFF温度读数偏低2℃NTC分压电阻精度不足用万用表测分压电阻实际阻值更换为1%精度贴片电阻5.2 独家避坑技巧ADC噪声杀手如果ADC读数毛刺多先关掉所有未用外设时钟RCC-APB2ENR/RCC-APB1ENR尤其关掉SPI/I2C时钟。实测关掉SPI后ADC噪声降低60%。探头“休眠”恢复长期不用的PH电极会干涸直接泡水效果差。正确做法先用3mol/L KCl溶液浸泡2小时再用蒸馏水冲洗最后标定。TDS探头“镀膜”处理新探头表面有氧化膜导致初始读数偏低。用细砂纸2000目轻轻打磨铂金片再用酒精棉擦拭可提升响应速度30%。Flash寿命预警在flash_emu.c里加函数FLASH_GetEraseCount()每100次擦写读取一次计数通过串口输出。当计数8000时建议备份数据并更换Flash扇区。潮湿环境防护PCB喷三防漆Conformal Coating时避开PH/TDS探头接口焊盘和NTC热敏电阻否则影响测量精度。我用的是HC-520丙烯酸树脂喷涂厚度15μm。5.3 性能边界实测数据在标准实验室环境25℃湿度60%下系统极限性能PH测量范围0.00~14.00pH精度±0.05pH25℃重复性±0.02pHTDS测量范围0~2000ppm精度±5ppm0~1000ppm段±10ppm1000~2000ppm段温度测量范围0~80℃精度±0.3℃NTC误差±0.1℃校准后功耗待机状态仅RTC运行23μA采样状态ADCTDS激励12mA存储寿命Flash擦写10000次后实测坏块率0.03%仍可读写。最后分享一个小技巧如果想延长电池供电时间把采样间隔从30分钟改为2小时配合低功耗模式STOP模式CR2032纽扣电池可支撑18个月。具体做法用RTC闹钟唤醒唤醒后执行采样完成后立即进入STOP模式。我在鱼塘边调试时老养殖户递给我一杯茶指着旁边上千元的商用仪表说“你这板子比我那台还准还便宜。”那一刻觉得所谓“开源”不是把代码扔网上就完事而是让每个拿到它的人都能在真实世界里解决问题。这套系统没有炫技的算法只有扎进泥土里的细节——PH电极怎么接、TDS探头怎么磨、Flash怎么擦全是手把手试出来的。如果你也打算动手记住先校准标定液再调代码参数先泡水24小时再谈精度指标。毕竟水质不会骗人水里的鱼更不会。