基于STM32的智能鱼缸控制系统开发实践:从硬件选型到远程监控
2026/9/6 19:42:41 网站建设 项目流程

简介:这是一份基于STM32的智能鱼缸控制系统完整设计与实现资料,适合具备一定电子和编程基础、对嵌入式与物联网感兴趣的初学者、中级开发者及养鱼爱好者。系统以STM32F103C8T6为控制核心,集成温度、水位、光照、浊度和pH检测传感器,驱动水泵、加热棒、增氧泵、步进电机等执行器,并借助ESP8266-12F模块实现手机APP远程监控与控制,可有效降低传统养鱼管理难度并提升鱼儿存活率。压缩包内共1个PDF文档,大小10.32MB,内容覆盖系统总体方案、传感器选型与电路设计、主控最小系统、各功能模块软硬件流程、实物焊接调试、常见问题排查及后续优化建议;目录层级清晰,从需求分析到软硬件实现均有详细说明,还包含材料清单、原理图与程序源码的文字描述,很适合作为课程设计或毕业设计的参考范例。该资源已有203人学习,可作为快速上手STM32综合项目并理解物联网架构的实用参考。 我养鱼养了差不多五年。从30cm小缸一路折腾到60cm草缸,中间死过不少鱼,也总结出一条铁律:观赏鱼出问题的原因里,水温波动、喂食不规律、水质恶化占了八成以上。后来工作忙,经常要出差,每次出门都提心吊胆——加热棒会不会失控把鱼煮熟?自动喂食器卡了没有?水里的溶质浓度是不是又飙升了?于是萌生了一个想法:干脆自己动手做一套基于STM32的智能鱼缸控制系统,把这些“看不见的风险”变成可监测、可控制、可远程告警的明确信号。

这套系统我前前后后做了两版。第一版用Arduino,功能能跑通但稳定性一般;第二版换到STM32F103C8T6,重新梳理了硬件电路和软件架构,连续运行至今没出过大问题。这篇文章把第二版完整的设计思路、硬件选型、软件实现和调试过程里踩过的坑都整理出来。如果你正在准备类似的毕业设计,或者想给家里的鱼缸加一套智能控制,这篇文章应该能帮你少走很多弯路。

1. 需求拆解:一台鱼缸真正需要哪些“智能”

1.1 从养鱼痛点倒推功能需求

先说结论:智能鱼缸不是功能越多越好,而是每个功能都能解决一个真实痛点。我在规划前把自己养鱼遇到的场景列了一遍:

  • 水温:鱼是变温动物,短时间内温差超过3℃就可能生病。加热棒虽然有自带温控,但坏了根本不知道,夏天水温过高也没人发现。
  • 喂食:上班族早上赶时间容易忘,周末一不留神又喂太多;出差几天更是没人管。
  • 水质:水浑了换水,换完又浑,没有一个量化的参考数据。
  • 灯光:草缸需要每天定时开灯6到8小时,手动开关很难长期坚持。
  • 人在外地:以上问题叠加到一起,你只能干着急。

围绕这些痛点,第一版功能清单确定为:DS18B20实时采集水温并控制加热棒继电器实现自动恒温;浮球开关检测低水位,缺水时声光报警并强制关闭加热棒防止干烧;TDS传感器监测水中可溶性固体总量,作为换水时机的参考;舵机驱动储料仓实现每天定时定量喂食;MOS管控制水草灯按时开关;OLED本地显示实时状态;ESP8266连接Wi-Fi,实现远程查看数据和下发控制指令。

这个组合不多不少,每一个功能都有对应的使用场景。毕业设计答辩时老师问“为什么做这个功能”,你也能讲出背后的真实需求。

1.2 哪些功能建议砍掉

做项目最容易犯的毛病是堆功能。我规划时明确划掉了几项:

PH传感器首先被砍。工业级PH探头校准繁琐,买现成模块的电极寿命又短,淡水观赏鱼更需要的其实是规律换水,而不是盯着PH数字焦虑。自动换水也暂时不做,这需要电磁阀、双水位传感器、复杂的加水逻辑,漏水风险大,对第一版系统来说得不偿失。视频监控同理,ESP8266的带宽不够,要清晰画面不如直接买几十块钱的网络摄像头。

砍掉这三项之后,系统复杂度大幅下降,稳定性和可维护性反而上来了。这个取舍本身就代表一种设计能力——你是在做一套长期运行的家用设备,而不是在参加“谁集成模块多谁赢”的比赛。

2. 硬件选型与电路连接:搭一套少出问题的底子

2.1 传感器与执行器选型对照

硬件选型的原则只有三个字:易获取、便宜、资料多。这决定了后期调试效率。下面是我逐个对比后定下来的方案。

器件我选的型号备选方案选择理由
MCUSTM32F103C8T6STM32F401、GD3272MHz主频、64KB Flash、20KB SRAM,资料全网最多
温度传感器DS18B20防水探头NTC 10K+ADC单总线协议,接线只需3根,教学和实用价值兼具
水位检测塑料浮球开关电极式探头结构简单,不受水垢和离子浓度影响
水质参考TDS模块不测只能测溶质总量,但作为换水提示完全够用
执行开关继电器模块MOS管加热棒220V必须继电器隔离;LED灯带用MOS管
喂食执行MG90S舵机28BYJ步进电机舵机自带位置反馈,控制出料角度更直接
显示0.96寸OLED SSD1306LCD1602I2C接口只占两根线,显示内容丰富
通信ESP8266-01sHC-05蓝牙Wi-Fi可以远程控制,可玩性高得多

关于MCU多说一句:F103C8T6虽然老,但性能和接口数量对这个项目绰绰有余。市面上的核心板只要十几块钱,自带最小系统和USB转串口,非常适合第一版原型验证。真要做到成品批量,再换F103RCT6这种更大封装的型号也不迟。

2.2 电源与驱动的几个关键点

整套系统的供电分配是新手最容易翻车的地方。我的方案是外部12V/2A开关电源统一供电,后级分三路:12V直接给水泵和LED灯带;12V经AMS1117-3.3降压给STM32、DS18B20、OLED;加热棒独立走220V回路,由继电器控制,与低压部分完全隔离。

实际测试发现,ESP8266-01s连接Wi-Fi时的瞬时电流可以达到300mA,AMS1117在12V转3.3V的大压差下发热很明显,瞬间掉压会导致MCU复位。后来我把ESP8266从3.3V主回路拆出去,单独用一块AMS1117从5V电源降压供电,掉线问题基本消失。

继电器控制加热棒是整套系统里唯一涉及强电的部分,必须做严格隔离。我买的继电器模块自带光耦,控制信号和220V部分在物理上分离。水泵是直流电机,属于感性负载,需要在电机两端并联一个1N4007二极管来吸收反向电动势,否则每次启停都会产生尖峰干扰MCU。

水位浮球接线要特别注意常开和常闭触点。我第一次就接反了,低水位成了高水位,折腾了很久才发现。正确做法是:浮球下沉时接通的触点用来做低水位报警,上浮时接通的触点留给高水位提示。接线前用万用表量一下浮球不同位置的导通状态,比接到板上再猜省时间得多。

2.3 总体连接结构一句话说清

STM32F103C8T6的PA0接TDS模拟输出,PB1接DS18B20数据脚,PB10/PB11接OLED的I2C,PA2/PA3接ESP8266串口,PA4至PA7分别控制继电器和MOS通断,PA8输出舵机PWM,PB12接浮球开关输入,PB13接蜂鸣器。

建议第一版直接用核心板加杜邦线搭建,不要急着画PCB。等所有功能验证完毕、逻辑确认无误,再画一块集成板把飞线问题一次性解决。我就是先洞洞板飞线跑通,确认整体方案后才打板,省去了反复改板的麻烦。

3. 软件架构:裸机任务调度、状态机与通信协议

3.1 工程搭建与代码目录规划

软件部分我用STM32CubeMX生成HAL库工程,配置要点:时钟切换到外部8MHz晶振;保留SWD调试口;USART1连接ESP8266,波特率115200;USART2接调试日志;I2C1接OLED;TIM2的CH1输出50Hz PWM控制舵机;ADC1的IN0采集TDS电压;若干GPIO控制继电器、MOS管、浮球输入和蜂鸣器。

代码目录我习惯分成四块:BSP放板级驱动,APP放应用逻辑,COMM放通信协议,SYSTEM放延时和任务调度。这个分层看起来简单,但调试时能帮你快速定位问题。比如水温不对,先去查BSP里的DS18B20读取函数,而不是在几百行的逻辑代码里找线索。

3.2 主循环时间片调度:不追RTOS也够用

这套系统要同时处理温度控制、喂食定时、按键扫描、OLED刷新、ESP8266收发,任务数量虽然不少但都不重,没必要引入FreeRTOS。我用一个1ms软件定时器作为时基,维护了一个简单的任务表。

typedef struct { uint32_t period; // 执行周期,单位ms uint32_t lastRun; // 上次执行时间 void (*func)(void); // 任务函数 } TaskItem; TaskItem tasks[] = { {10, 0, KeyScan}, {100, 0, UpdateDisplay}, {500, 0, CheckWaterLevel}, {1000, 0, ReadTemperature}, {2000, 0, CheckHeater}, {60000, 0, FeedTask}, };

主循环里就是遍历任务表,判断当前时间减上次运行时间是否大于等于周期,满足则执行。这是裸机版的定时任务机制,代码量少,逻辑直观,也不会因为某个任务阻塞影响全局。

要注意DS18B20一次温度转换需要750ms(12位分辨率),如果直接放在1000ms任务里调用阻塞式读取,会把整个调度拖死。我的做法是把读温度流程改成状态机:发起转换、等待完成、读取数据三步拆开,由1000ms任务定期驱动。这样既不阻塞主循环,温度值也稳定。

3.3 温度滞回控制与喂食状态机

加热棒控制的坑在于继电器不能频繁通断。如果写成“低于25℃开,高于25℃关”,温度在目标值附近抖动时会反复吸合,继电器寿命迅速缩水,火花干扰也会影响其他模块。滞回控制能解决这个问题:目标25℃,回差0.5℃,那么低于24.5℃开启加热,高于25.5℃关闭加热。

if (temp <= target - 0.5f) heaterOn(); else if (temp >= target + 0.5f) heaterOff();

中间区间保持上一次状态不动。滞回的本质是把“要不要动作”的判断范围拉大,避免在临界点反复横跳。这个思路不仅适用于加热棒,风扇散热、水泵启停这些开关控制都能复用。

喂食模块我设计成一个小状态机。正常处于IDLE;定时时间一到进入ROTATE,舵机从初始角度转到出料角度,保持1秒后回到初始角度;随后进入LOCK,5分钟内不响应任何喂食指令,防止手动误触连续投喂。状态机全部用switch-case实现,状态迁移只依赖时间和角度条件,逻辑非常直观。

3.4 与ESP8266的通信协议

ESP8266在我的方案里定位是“透传网关”。它连上路由器后,定期向上位服务器上报数据,收到下行指令则通过串口转发给STM32。STM32这边只需要维护一套轻量协议就够了。

协议帧格式定义为:

帧头(0xAA 0x55) + 长度(1字节) + 命令字(1字节) + 数据区(N字节) + 累加和校验(1字节) + 帧尾(0x0D 0x0A)

上行命令字0x01表示上报状态,数据区固定为温度、水位、TDS、加热状态、喂食状态共5字节;下行命令字0x11表示控制加热,数据区为开关。STM32串口按帧解析,校验通过才执行,执行后回发ACK。这段自定义协议不复杂,但在答辩时能清楚展示你对通信格式、校验机制的理解,算是一个不错的亮点。

4. 调试实录:五个最值得记录的坑与排查过程

4.1 DS18B20读回85℃,不是传感器坏了

第一版上电后OLED一直显示85℃,我第一反应是探头坏了,换了一只新的还是一样。随后量VCC和GND,电压正常,拿逻辑分析仪抓单总线波形,发现芯片根本没有完成ROM指令握手。

排查后发现是上拉电阻和线长的问题。DS18B20数据线虽然开发板上有内建上拉,但接了一根30cm的延长线后总线电容偏大,信号上升沿太慢,单片机总是复位识别失败。解决办法是在数据线和3.3V之间外接一个4.7kΩ上拉电阻,把探头延长线缩短到20cm内,问题立刻消失。DS18B20的单总线协议对线长和上拉非常敏感,这是我每次做项目都会重新踩一遍的坑,这次特意记录了下来。

4.2 继电器一吸合,MCU立刻重启

第一版调试时出现一个恐怖现象:温度低于下限,继电器吸合,OLED闪一下熄灭,串口日志显示MCU复位。

用示波器观察3.3V电源轨,发现继电器吸合瞬间出现接近1V的跌落尖峰。12V电源被继电器线圈的瞬态冲击拖垮,殃及后面的稳压器。我做了三处修改:12V输入端加470uF电解电容和0.1uF陶瓷电容吸收瞬态;继电器控制信号与MCU之间用光耦隔离,控制线远离传感器线;水泵电机两端并联续流二极管。三管齐下后,无论怎么切换负载,MCU供电都稳定如初。

4.3 ESP8266掉线,根源在3.3V供电能力

ESP8266连上Wi-Fi后运行几分钟到几小时不等,串口和TCP数据就会丢失,有时直接重启。我一开始怀疑是路由器信号问题,但换位置后没改善。后来用万用表盯住模块3.3V供电端,发现在重启瞬间电压掉到2.6V以下。

原因就是AMS1117-3.3在大压差场景下带不动ESP8266的脉冲电流。解决方式前面提过:改成5V独立电源给ESP8266供电,CH_PD使能脚接3.3V拉高,串口信号串联1kΩ电阻限流。改完后连续跑了72小时没掉过线,属于成本极低但回报极高的一个改动。

4.4 舵机抖动,喂食量忽多忽少

MG90S每次启动时抖两下,出料角度不稳定。排查发现两个叠加原因:舵机供电取自控制板的3.3V,而MG90S堵转电流能到700mA以上,3.3V供电力矩不足,位置反馈自然发散;另外PWM参数不对,MG90S要求50Hz周期也就是20ms,脉宽0.5ms到2.5ms对应0°到180°。把舵机供电改成5V独立回路,用TIM2按20ms周期输出正确占空比后,抖动消失,出料角度每次都准。

4.5 断电后喂食时间全乱

家里一次临时停电半小时,RTC时间归零,恢复供电后喂食任务在00:00立刻执行了一次,鱼被投喂了两遍。STM32内部RTC依赖VBAT备份电池,我第一版没接,断电即丢。

解决有两个方案:初级方案是STM32上电后主动向ESP8266请求一次网络时间,校准RTC;更可靠的方案是外接DS3231高精度时钟模块,也就几块钱,断电后时间照样准。对鱼缸这种需要长期运行的设备,强烈建议直接上DS3231。

5. 实测数据、成本清单与后续还能做什么

5.1 连续运行30天的关键数据

系统搭好后我在60cm淡水草缸上连续运行了30天,记录了几个关键指标。

指标实测数据说明
温度控制精度目标25.0℃,实测24.6~25.4℃滞回控制效果稳定
水位报警响应浮球触发后500ms内蜂鸣器响带软件滤波防误报
喂食准确性30天共投喂90次,每天准点时间基准来自DS3231
除加热棒外整机功耗水泵、灯带、控制电路约0.2度/天单片机整体功耗较低
远程控制延迟MQTT指令1秒内到达ESP8266家庭Wi-Fi环境下

从数据看,这套方案对中小型鱼缸完全够用。温度波动范围比普通加热棒自带温控更小,原因在于加热棒内置温控精度通常只有±1.5℃左右,而DS18B20配合滞回算法能把波动压得更窄。

5.2 整机成本逐项拆解

按量产一版集成PCB的实际花费,不算人工,参考价格如下:

器件规格参考价格
STM32F103C8T6最小系统板蓝板带USB转串口12元
DS18B20防水探头3线1米5元
0.96寸OLED SSD1306I2C 4针9元
TDS水质检测模块探头加调理电路12元
塑料浮球开关常开型2元
MG90S舵机金属齿轮9g9元
ESP8266-01s带转接板10元
4路继电器模块带光耦隔离6元
AMS1117-3.3模块两个2元
12V/2A电源适配器品牌电源15元
PCB打样10x10cm五片25元
接线端子、排针、线材杂项20元

合计大约127元,加上加热棒、水泵和LED灯带这三样鱼缸已有或另购的配置,整机能控制在200元出头。对比市面上成品智能鱼缸设备动辄五六百的价格,这个成本很有竞争力,而且所有控制逻辑都在自己手里,想改哪里改哪里。

5.3 我认为值得继续做的三个扩展

这套系统做完以后,我梳理了三个后续方向。

第一,把TDS数据接进云端,在手机上画趋势曲线。TDS值不能直接代表水质好坏,但趋势很有参考价值。如果换水后一周内TDS持续爬升,说明过滤系统负荷偏大,该洗滤筒了。

第二,加水泵转速闭环。用驱动芯片通过PID把水流控制在设定值,对草缸的CO2溶解率和过滤效果会有明显改善。

第三,把喂食器升级成双仓结构,一个仓放颗粒饲料,一个仓放液肥,通过按键或远程分别控制。

最后再分享一个我养成的习惯:整个调试过程最不值得省的就是串口日志。日志从第一版就一直保留,每次出异常,翻日志比重新测电路快得多。这个项目做到现在,已经不只是给鱼缸用,更是一个练手的好平台。动手做起来,你会发现很多东西比你想象的复杂,但也比你想象的值得。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询