基于STM32的鱼缸水质监测系统DIY设计与实现 📅 发布时间:2026/9/11 10:46:40 👁 浏览次数: 养鱼的朋友应该都经历过这种时刻:鱼缸里的水看着还挺透亮,鱼却突然没精神了,紧接着就开始生病、趴缸,等你反应过来,水质早就出问题了。传统养殖靠经验,看水色、闻味道、观察鱼的活动状态,但这些都是事后指标——等你肉眼能看出来不对劲,水质参数往往已经偏离了很久。所以我一直想给鱼缸配一套能实时盯着水质的设备,但又不想买市面上那种动辄上千的成品监测仪,干脆自己用STM32搭了一套。这个项目做下来,整套系统能实时监测鱼缸的水温、pH值、TDS(溶解性固体总量)、浊度和水位,数据在OLED屏上直接显示,超限会自动报警,还可以通过串口把数据送到上位机或者ESP8266做远程查看。整体成本控制在一百多块钱,比成品设备便宜一大截,而且全部代码和电路都是自己可控的,想加什么功能随时改。这篇就把整个设计思路、硬件选型、传感器信号处理、标定流程和实测踩坑记录下来,给准备做类似项目的朋友一个完整参考。1. 养鱼先养水:监测指标选定与传感器选型思路1.1 这些指标为什么值得测开始动手之前,我花了很长时间纠结到底要测哪些参数。鱼缸水质相关的指标其实很多:温度、pH、氨氮、亚硝酸盐、硝酸盐、溶解氧、硬度、TDS、浊度……如果全部堆上去,系统复杂度会成倍上升,而且很多传感器不是贵就是维护麻烦。最终我选定了五个参数:水温、pH值、TDS、浊度、水位。水温是所有热带鱼养殖的基础参数,直接影响鱼的新陈代谢和免疫力。大多数观赏鱼的适宜温度区间在22到28摄氏度,温度波动超过2度鱼就容易应激。pH值影响鱼的渗透压调节和水体中有毒物质的存在形态,比如氨在碱性条件下毒性会显著增强。TDS反映水中溶解性固体的总量,可以间接判断水质是否有积累污染的趋势,比如喂食过量、排泄物分解都会让TDS缓慢上升。浊度则是直观的水体清澈程度指标,虽然不直接等于水质好坏,但浊度突变往往预示着藻类爆发或者微生物异常。水位参数其实经常被忽略,但对于有蒸发、有过滤系统的鱼缸来说,水位下降会影响水泵的扬程和氧气交换,加一个水位监测能防止干烧和溢流。这里面我特意没有上氨氮和亚硝酸盐传感器,不是因为它们不重要——恰恰相反,它们才是养鱼水质安全的核心。但这两个参数的电化学传感器价格都在几百到上千元,而且电极寿命短、需要频繁校准,对于DIY项目来说性价比太低。我的方案是用TDS和pH作为间接指标:pH突变和TDS持续上升都是水质恶化的前兆,在这两个参数出现异常时提前干预,可以规避大部分氨氮超标的风险。1.2 六类传感器选型对比与理由选型的原则很简单:优先选输出信号简单、接口成熟的传感器,避免自己处理复杂的模拟前端电路,否则调试成本会失控。下面是最终选用的元器件列表:监测参数传感器方案输出信号接口方式水温DS18B20防水探头数字信号(单总线)1-WirepH值pH玻璃电极信号调理模块模拟电压(0~3V)ADCTDSTDS探针调理模块模拟电压(0~2.3V)ADC浊度红外光电对管传感器模拟电压(0~4.5V)ADC水位HC-SR04超声波模块电平时间(脉宽)GPIO定时器输入捕获水温选DS18B20是最没悬念的,因为它直接输出数字信号,精度正负0.5摄氏度,抗干扰能力强,不需要ADC,一根线就能挂多个探头。pH传感器用的是实验室级别的玻璃电极加信号调理板,模块会输出与pH值线性对应的电压,虽然玻璃电极需要定期校准和维护,但在可接受范围内。TDS传感器的原理是测量水体电导率,探针相当于两个铂电极,通过测溶液电阻来推算离子浓度,输出也是模拟电压。浊度传感器我用的是红外光电对管方案,NPN三极管输出,一方面测透光率,浊度越高输出电压越低。水位最后选了HC-SR04超声波,因为非接触式测量不受水体腐蚀影响,比电极式水位传感器耐用得多。这里要提醒一下,市面上几十块钱的TDS模块和几百块钱的实验室TDS笔,差别主要在电极材质和温补算法上。DIY项目用几十块的模块完全够用,但需要有心理预期:它的绝对精度不会特别高,作为趋势监测和相对变化监测完全没问题。pH传感器反而建议买稍微好一点的,因为玻璃电极的质量直接决定读数的稳定性和寿命,便宜的电极漂移非常严重,可能两天就要重新校准一次。2. 硬件电路搭建:STM32最小系统之外的几个关键设计2.1 电源拓扑:为什么单独给传感器供电很多第一次做STM32项目的人容易犯一个错误:把所有模块全部用单片机的3.3V或者USB的5V供电,结果水泵一启动,屏幕上ADC读数就开始跳,还以为是传感器坏了。其实问题出在电源噪声上。鱼缸里有水泵、气泵这些感性负载,启动瞬间的电流冲击会拉低电源电压,而且电机的换向火花会产生宽频噪声,通过电源线传导到模拟电路里。我这次的电源拓扑分了三级:220V市电 → 12V开关电源 → 5V降压模块(MP1584) → 3.3V LDO(AMS1117) ↓ 传感器供电(5V/3.3V分开走线)主控STM32F103C8T6用3.3V供电,OLED、蜂鸣器、继电器这些数字外设走5V,而pH、TDS、浊度这三个模拟传感器的电源地线单独走一条路径,最后在电源入口处单点汇合。模拟地和数字地在PCB上或者面包板上要保持分离,只在主控的地引脚附近单点连接,避免数字电路的开关噪声通过地回路耦合到模拟信号里。另外一个容易被忽略的细节是ADC的参考电压。STM32F103的ADC使用VDDA作为参考电压,如果VDDA直接用AMS1117的输出而不做滤波,那么3.3V上的纹波会直接叠加到ADC读数里。我实测过,不滤波的VDDA在电机启动瞬间会有接近50mV的跌落,对应到ADC的12位读数就是将近70个LSB的跳变,这在pH测量中相当于0.1以上的偏差。所以VDDA走线一定要单独出来,加一个10uF和100nF的电容组合滤波,如果是追求极致精度,可以用专门的基准电压芯片搭参考源。2.2 模拟信号链路:从BNC接头到ADC引脚pH传感器是整个系统里模拟链路最脆弱的环节。玻璃电极的内阻非常高,通常在100MΩ到1000MΩ级别,它输出的电压信号极其微弱,必须有高输入阻抗的缓冲放大器才能读取。市面上买的pH信号调理板自带了运算放大电路,输出阻抗很低,可以直接接ADC,这块不用自己搭。但要注意信号传输线的问题——电极出来的BNC线到调理板之间必须用屏蔽线,否则周围任何电磁干扰都会耦合进这个高阻信号里。pH信号调理板输出范围一般是0到3V(有的板子是0到5V),对应pH 0到14的线性关系。这里要特别留意调理板的供电电压:有些模块是用5V供电的,输出范围会到4V以上,直接接STM32的ADC(最大3.3V)会超出量程,轻则削顶失真,重则烧坏引脚。我用的模块带了一个电压比较电路,通过模块上的电位器可以把输出中线调整到合适的电压,然后用一个电阻分压把最大输出电压限制在3.3V以内。最稳妥的办法是看一下模块手册,如果没有手册,就用万用表实测输出的最大电压,再用分压电阻衰减。TDS和浊度传感器的输出就友好很多。TDS模块输出0到2.3V,正好在ADC量程内;浊度传感器输出0到4.5V,但实际使用时浊度越高电压越低,正常鱼缸水体的输出电压在3到4V之间,超过3.3V的部分会在ADC端截断。所以浊度传感器也需要做分压处理,我用了两个10k电阻分压,把4.5V映射到2.25V,避免超出量程。2.3 外设连接与引脚分配表引脚分配看起来简单,但排布不合理会给自己挖坑。比如把PWM输出和ADC输入放在相邻引脚,高频PWM的噪声就可能串扰到模拟信号上。我最终的引脚分配如下:外设引脚说明DS18B20PA0单总线,需4.7k上拉电阻pH模块PA1ADC1_IN1,模拟输入TDS模块PA2ADC1_IN2,模拟输入浊度模块PA3ADC1_IN3,模拟输入HC-SR04 TrigPA4GPIO输出HC-SR04 EchoPA5GPIO输入,定时器输入捕获OLED SCLPB6I2C1时钟OLED SDAPB7I2C1数据蜂鸣器PB0低电平触发水泵控制PB1继电器驱动每个模拟输入引脚我都在靠近芯片的位置加了一个100nF的滤波电容,配合软件滤波双保险。DS18B20的4.7k上拉电阻是必须的,没有它单总线通信会时好时坏,这个坑我刚开时就踩过,表现为温度读数偶尔跳出一个离谱的负值。3. 从电压到水质数值:ADC采集、滤波与转换的完整链路3.1 多通道ADC的DMA采集设计STM32F103的ADC有16个通道,但同一个时刻只能采一路。如果顺序采样,每次切换通道需要一小段稳定时间,而且如果CPU在采集过程中去处理别的任务,就会产生采样间隙,导致数据不连续。最省心的方案是ADC加DMA配合使用:配置好ADC为连续扫描模式,使能DMA循环传输,让硬件自动完成三路模拟信号的轮流采集,CPU完全不用干预,采好的数据直接落在内存数组里。我用的配置是ADC1的三个通道(PA1、PA2、PA3),扫描模式,12位分辨率,采样时间尽量拉长到55.5个ADC时钟周期。采样时间不够长也是新手常踩的坑——ADC采样电容需要时间充到和输入信号相同的电压,如果采样时间太短,高阻抗的输入信号来不及给采样电容充电,测量结果会偏低。对于阻抗较高的传感器信号,拉长采样时间能明显改善读数准确性。DMA的循环模式下,每通道每次转换完成后会自动存到数组的对应位置。我定义了一个长度为3的uint16_t数组,三个通道的数据循环更新。主循环里读取这个数组时,理论上不需要加锁,因为即使读取到一半DMA更新了数据,最多也就是当前这一帧有一路数据是上一轮的,对滤波算法几乎无影响。3.2 滤波策略:为什么单纯滑动平均不够ADC原始数据在鱼缸这种电磁环境并不好的场景下,噪声水平相当可观。我第一版代码用了最简单的滑动平均滤波,窗口取20次,跑起来发现一个问题:当水泵开启时,瞬时噪声会导致个别采样值偏离真实值非常多,滑动平均虽然能平滑大部分噪声,但对这种离群野值却无能为力——一个特别大的跳变会把均值带偏很多,要窗口滑动完一轮才能消除影响。所以我最后采用的是中位值滤波滑动平均的二级方案:先对连续采样的7个值取中位数,把野值剔除掉,然后再对中位数结果做15次的滑动平均。实测效果比单纯滑动平均好很多,水泵启停瞬间的ADC读数波动从正负70个LSB降低到了正负5个LSB以内。具体实现代码如下:#define FILTER_BUFFER_SIZE 15 uint16_t mid_filter(uint16_t *buf, uint8_t len) { uint16_t temp[7]; for(uint8_t i 0; i len; i) temp[i] buf[i]; // 简单冒泡排序取中值,数据量小无所谓效率 for(uint8_t i 0; i len - 1; i) { for(uint8_t j 0; j len - 1 - i; j) { if(temp[j] temp[j1]) { uint16_t t temp[j]; temp[j] temp[j1]; temp[j1] t; } } } return temp[len / 2]; } uint16_t slide_mean_filter(uint16_t new_value) { static uint16_t buffer[FILTER_BUFFER_SIZE]; static uint8_t index 0; static uint32_t sum 0; if(index FILTER_BUFFER_SIZE) index 0; sum - buffer[index]; buffer[index] new_value; sum buffer[index]; index; return (uint16_t)(sum / FILTER_BUFFER_SIZE); }3.3 把原始值换算成pH、TDS、浊度的公式来源ADC读到的只是0到4095的数字量,要变成有意义的物理量需要经过两步换算:先把数字量还原成电压,再把电压映射成目标参数。电压还原公式很简单:V ADC_Value / 4095 * 3.3pH的电压映射关系取决于pH传感器模块的设计。大多数pH模块的输出电压与pH值成线性反比关系:pH V_offset / 每pH电压变化量不同模块的斜率和截距差异很大,这就是为什么要做标定(下一章详细讲)。以我用的模块为例,它的特性是输出电压越高,pH值越低,大约每变化1个pH对应59.16mV(能斯特方程在25摄氏度下的理论值),但实际模块因为参考电位不同,会有自己的基准偏移。pH传感器的标定本质上就是确定两个参数:每pH对应的电压变化量(slope)和零电压对应的pH值(offset)。TDS的换算稍微绕一点。TDS模块输出的电压与溶液电导率相关,而TDS值和电导率又有一个经验换算系数,通常取0.5到0.7之间(1uS/cm电导率约等于0.5~0.7ppm TDS)。市面上常见的TDS模块厂商会在内置电路里做一部分近似处理,输出一个与TDS值近似线性的电压。实际计算时我用两点标定法确定电压到TDS的线性关系,公式为:TDS (V - V0) * K其中V0和K通过标定溶液确定。完全没有标定条件的情况下,也可以参考模块资料里给的典型公式,比如某常见模块的对应关系是TDS 66.7 * V,但这个值只做粗参考,误差可能超过30%。浊度传感器的换算我采用的是查表法加线性插值。不同水体的浊度-电压关系一致性较差,很难用一个固定公式覆盖所有情况。我先把传感器放入清水中测出基准电压Vclean,然后配几组不同浊度的标准液,记录对应的电压值,建立一张简单的映射表。运行时通过线性插值算出当前浊度值(NTU)。这个方法不是特别精确,但对鱼缸监测场景足够了——我更关心的是浊度的相对趋势,而不是绝对精度。4. 代码架构:模块化任务调度与显示报警逻辑4.1 系统状态机与任务调度整个固件我没有用操作系统,而是采用了一个简单的前后台结构:定时器产生1ms时基,主循环里通过时间片轮询执行不同任务。这个结构对付数据采集、显示、报警这种低速系统绰绰有余,而且代码逻辑清晰,方便调试。系统核心是一个简单的状态机:状态: INIT → MEASURE → PROCESS → DISPLAY → ALARM_CHECK → (回到MEASURE)每个状态的执行频率不同。传感器采集任务每200ms执行一次,这是为了给滤波算法提供足够的采样点;数据处理任务每500ms执行一次,把原始值转换为物理量;OLED显示任务每1秒刷新一次,因为OLED频繁刷新会导致闪烁和寿命衰减;报警检查任务每500ms执行一次,一旦参数越限就触发蜂鸣器。这种分频调度的好处是各任务相互独立,增加新功能时不需要改动调度框架,只需要在状态机里插入新的状态。比如后期想加ESP8266数据上传,只需要添加一个UART_SEND状态,每5秒执行一次即可。4.2 数据显示与越限报警的实现OLED用的是一块0.96寸SSD1306驱动的I2C屏幕,128x64分辨率。显示界面分两页,第一页轮播显示温度和pH值,第二页显示TDS、浊度和水位。数字字号用的是8x16的大号字体,方便站在鱼缸前远距离看清数值。报警逻辑一开始做的是单纯的门限比较——任何一个参数超过上/下限就立刻触发蜂鸣器。实际用起来发现一个问题:传感器读数偶尔会有短时跳变,比如pH值在标定后刚放入鱼缸时,会因为电极周围局部水体和整体不均匀产生一个短暂的异常读数,触发误报警。后来我在报警逻辑里加了一个持续时间确认机制:只有当参数连续越限超过10秒才真正触发报警,避免单帧数据异常打扰正常使用。报警之后还会联动一个继电器去控制水泵或加热棒。我没做全自动闭环控制,主要是安全考虑——pH值异常时自动加酸碱调节剂这种操作风险太大,一旦执行机构故障或者加药过量会直接毁掉一缸鱼。所以我的系统只做监测报警,执行部分保留为手动操作,这也是我在设计上刻意保守的一点。4.3 调试技巧:常见开发环境问题编译和烧录阶段,很多人会卡在开发环境上。如果遇到error: no stm32 target found!的报错,通常不是代码问题,而是ST-LINK和芯片之间的连接问题:一是ST-LINK的SWDIO、SWCLK、GND、3.3V四根线有没有接对,不能带电插拔调试器,容易导致调试器固件锁死;二是芯片若有读保护(Secure Area)或者调试接口被禁用过,需要先用ST-LINK Utility执行整片擦除。还有一个不太容易想到的原因——如果板子上ST-LINK没供电,芯片完全没上电,自然找不到目标。STM32延时函数卡死的问题也值得提一句。很多人用HAL_Delay卡死,原因多半是在中断回调函数里调用了HAL_Delay。HAL_Delay依赖SysTick中断,而定时器中断里调用它会形成嵌套等待,系统就卡死了。解决办法是中断回调里只用标志位,把耗时操作放到主循环处理。如果是标准库的delay_init没配置好时钟树,延时也会异常,务必要先确认系统主频的配置是否正确。5. 标定才是精度的灵魂:pH和TDS校准实操5.1 pH两点标定完整流程pH传感器是这套系统里对精度要求最高、也最需要人工维护的传感器。电极会随着使用缓慢老化,参考电位会发生漂移,如果没有定期校准,读数误差会在几周内从0.1漂移到0.5甚至更大。所以pH传感器的标定不是做一次就完事的,而是要形成习惯性维护流程。两标定法需要两种标准缓冲液,通常用pH 6.86和pH 4.00(或者pH 9.18,看养鱼的酸碱环境选择)。流程如下:把电极用去离子水(或者纯净水)冲洗干净,用滤纸轻轻吸干水珠,注意不要擦拭电极玻璃泡,避免摩擦产生静电影响电位。电极浸入pH 6.86标准液,等待读数稳定(一般需要1到3分钟),记录此时传感器输出的电压值V1。换pH 4.00标准液,同样等待稳定,记录电压V2。根据两点确定线性关系:slope (V1 - V2) / (6.86 - 4.00) offset 6.86 - V1 / slope pH offset V / slope把计算出的slope和offset写进固件的配置参数里。这里我做了个小小的软件优化:把标定参数存储在STM32内部Flash的一个专用扇区,标定时通过串口命令在线更新参数,不用每次重新编译烧录。标定过程中最容易犯的错误是电极还没稳定就开始读数。pH玻璃电极在液体中建立平衡需要时间,尤其是在两种不同pH的溶液之间切换时,电极表面需要置换掉残留液膜。判断稳定的标准是电压读数在一分钟内变化不超过1mV,用串口把实时电压打出来观察最直观。5.2 TDS标定的简易替代方案TDS传感器的标定没有pH那么复杂的理论,甚至很多时候不用特意标定。多数家用TDS模块的出厂参数已经做了基本的线性补偿,直接按厂商公式算出来的结果虽然在绝对精度上有误差,但趋势监测绰绰有余。如果你想要更准的数据,最实用的标定方法不是去买标准溶液,而是用一瓶怡宝或农夫山泉的纯净水做参考。找一根实验室级的TDS笔或者电导率仪,测一下你要用来标定的水的真实TDS值,然后把这个水和你的传感器放在同一个容器里,调节模块上的电位器使输出值接近参考值。这样标定出来的系统在200ppm以下的低TDS区间误差可以控制在10%以内,对淡水观赏鱼缸来说足够了。这里要特别说一个很多人的误区:TDS不能直接和水质好坏划等号。TDS高不一定代表水质差,有些矿物含量高的水体TDS天然就高;TDS低的也不一定就是好水,比如纯水TDS接近0但缺乏缓冲能力,pH容易剧烈波动。所以TDS更适合作为趋势指标——如果你看到TDS在几天内从200缓慢爬升到400,说明水体中的溶解物质在持续积累,该考虑换水或者加强过滤了。5.3 标定后误差对比实测标定完成后我做了一组对比测试,拿系统读数和实验室仪器读数做对照:参数系统读数参考仪器误差水温25.3°C25.4°C-0.1°CpH7.127.050.07TDS342 ppm355 ppm-13 ppm浊度1.2 NTU参考系趋势一致整体误差在接受范围内。pH的0.07误差在鱼缸养殖场景下完全够用,水温误差几乎可以忽略,TDS的13ppm偏差也符合经济型传感器的定位。浊度因为没有专业浊度仪做校准,这里只做了趋势验证,在喂食前后水体浊度确实出现了对应变化,说明传感器对水质变化是敏感的。6. 连续运行实测与踩坑记录:一周之后我发现的问题6.1 一周连续监测的数据变化系统做好后我在自己家的金鱼缸上跑了整整一周,每两小时记录一次数据,下面是一周里几个有代表性的时间点:时间水温(°C)pHTDS(ppm)浊度(NTU)事件周一 08:0024.87.352680.8正常周一 20:0026.17.122961.5喂食后2小时周三 22:0025.66.983522.1未换水第3天周五 12:0025.96.854082.8明显恶化趋势周五 20:0025.47.023151.0换水1/3后周日 10:0025.17.282890.9恢复正常这个数据非常直观地展示了鱼缸水质的变化规律:喂食后两小时,pH和TDS会发生明显波动;一周不换水,TDS会从268缓慢爬升到408,同时浊度也在上升;换水1/3后各项指标迅速恢复。这套系统最大的价值就在这里——它让我在水质肉眼可见变差之前就看到了趋势,周五中午的数据已经提醒我该换水了,而不是等到周末鱼状态不好才反应过来。6.2 五个容易翻车的细节连续运行一周暴露了不少问题,这里挑五个最有代表性的记录一下,给后面做类似项目的朋友提个醒。第一个坑:浊度传感器被藻类污染。跑了两天之后,浊度传感器的光学窗口上开始附着微藻,导致输出电压缓慢下降,浊度读数虚高。这个问题在鱼缸这种富营养水体里几乎无法避免。解决方案是把传感器探头垂直放置,让窗口不容易积累沉淀物,然后每隔一周拆下来用软布擦拭光学窗口。另外,传感器不要离灯光太近,光照会干扰光电对管的测量,导致读数异常波动。第二个坑:水质参数的空间不均匀性。一开始把所有探头都捆扎在鱼缸的同一个角落,结果发现测出来的数据波动很大。原因很简单:鱼缸里的水并不是均匀的,靠近加热棒的水温高,靠近出水口的水流快、溶解氧高,鱼粪沉底的地方污染物浓度高。后来我把传感器分散安装,温度探头放在远离加热棒的缸体中部,pH和TDS探头放在水循环比较充分的区域,水位传感器放在缸壁最高处,数据就稳定多了。第三个坑:pH电极的存储不当。有两天pH读数突然变得异常迟钝,从7.0跳到6.5又跳回来。排查了半天才发现是电极头没泡在溶液里,空气暴露导致玻璃电极表面干燥,测量性能大幅下降。pH玻璃电极必须始终保持湿润,不用的时候要浸泡在电极保护液(一般用3M KCl溶液)里。如果发现电极已经干了,先泡在保护液里24小时以上让它恢复,不能直接放进鱼缸测量,否则读数会一直漂移不定。第四个坑:泵的干扰仍然存在。虽然做了电源分离和滤波,但水泵启动瞬间TDS读数还是会有短暂的跳变。原因后来找到了:水泵是感性负载,它产生的干扰不仅通过电源传导,还通过水体本身传导——电流在水里的分布会瞬间改变TDS探针两端的微电压,相当于水里的电磁场直接干扰了测量。这个没办法完全消除,只能通过软件规避:在报警逻辑里设置了10秒的越限确认,而且采样时检测到水泵开机的信号就跳过这一轮测量,等稳定后再采。第五个坑:OLED屏幕的刷新闪烁。I2C接口的OLED在主循环里频繁逐字节刷新时,会有明显的闪烁感。究其原因是SSD1306的显存更新需要时间,而MCU在传输数据时无法同时完成其他任务。优化方案是使用SSD1306的页地址模式,只更新变化的数据区域而不是全屏重绘,同时在显示任务里加入1秒的间隔。这样屏幕非常稳定,而且主循环的负载也降下来了。7. 扩展方向与最终心得这套系统跑通之后,我还预留了几个扩展接口。串口1接了一个ESP8266模块,可以直接把数据推送到MQTT服务器,用手机远程查看鱼缸状态;继电器输出除了控制水泵,还可以扩展为自动补水装置——当水位低于设定值时,自动打开电磁阀补水。如果想进一步升级,可以把氨氮传感器和溶解氧传感器接进来,但前提是你要能接受这些传感器的维护成本和标定周期。做这个项目的过程中我最大的感受是:硬件本身不难,难的是让你的测量值靠谱。STM32的ADC配置、DMA传输、滤波算法,这些东西一遍就能跑通;真正花了我最多时间的是回头理解传感器本身的物理特性——pH电极为什么要保湿、TDS为什么受水温影响、浊度为什么会被藻类污染。只有把这些底层原理吃透了,你在系统的每个环节做的决定才不会是无根之木。如果让我给后来者一个建议,那就是:第一版系统不要贪多求全,先把温度、pH、TDS这三个基础参数做好,跑一段时间积累真实数据,再逐步加功能。因为你会发现,实际运行中遇到的问题永远比设计时预想的多得多,先让系统稳定可靠地转起来,再去追求功能丰富,才是做嵌入式项目的正道。