1. 项目背景与需求分析
养鱼看似简单,实则是个技术活。水温高了鱼会缺氧,浊度大了影响观赏性,溶解氧不足更是直接威胁鱼类生存。传统养鱼需要频繁手动检测水质,不仅麻烦还容易出错。我记得刚开始养鱼时,就因为没及时换水,一缸孔雀鱼全军覆没,心疼了好久。
这个项目就是要解决这些痛点——用STM32做主控,搭配多种传感器,实现对鱼缸水质的24小时无人值守监测。温度、浊度、溶解氧这三个核心参数一旦异常,系统会自动触发增氧或换水装置。你还可以通过手机APP远程查看数据,接收报警信息,真正实现智能养鱼。
特别适合嵌入式入门者作为毕业设计选题:硬件成本控制在200元内,软件逻辑清晰,既能展示嵌入式系统设计能力,又具备实际应用价值。我当年做类似项目时,最大的成就感不是通过了答辩,而是半年后鱼缸里的红绿灯鱼居然开始繁殖了——这说明水质稳定真的至关重要。
2. 系统架构设计
2.1 整体方案设计
先看核心架构(表2-1)。系统采用分层设计,底层传感器采集数据,中间STM32处理决策,上层执行器动作反馈。这种设计最大的好处是模块化——哪个传感器坏了就换哪个,不影响整体运行。
表2-1 系统架构分层说明
| 层级 | 组成模块 | 功能说明 | 通信方式 |
|---|---|---|---|
| 感知层 | 温度/浊度/溶解氧传感器 | 实时采集水质参数 | 模拟量/I2C/单总线 |
| 控制层 | STM32F103C8T6 | 数据处理与决策 | - |
| 执行层 | 水泵/电磁阀/增氧机 | 执行调控动作 | GPIO控制继电器 |
| 交互层 | OLED屏+蓝牙模块 | 本地显示与远程通信 | I2C+UART |
我最初尝试过用Arduino开发,发现处理多路传感器数据时容易卡顿,后来换到STM32就顺畅多了。72MHz主频完全够用,DMA功能还能实现ADC采集时不占用CPU资源。
2.2 传感器选型要点
传感器选型是项目成败的关键。温度检测用DS18B20防水款最省心,直接扔进鱼缸就行,单总线协议只需要一根数据线。记得买不锈钢外壳的,我贪便宜买过环氧树脂封装的,被乌龟咬破就短路了。
溶解氧传感器建议用荧光法的,虽然比极谱式的贵几十元,但不用频繁校准。极谱式的每隔两周就得校准一次,麻烦得很。浊度传感器选TS-300B就行,输出模拟电压信号,注意安装时要避开直接光照,否则读数会漂。
水位检测可以用简单的电阻式探针,但容易氧化。更好的方案是超声波传感器,虽然贵点但非接触测量更可靠。我曾经用电阻式探针养海水鱼,三个月后探针全被腐蚀了。
3. 硬件设计实战
3.1 核心电路设计
主控采用STM32F103C8T6最小系统板,价格不到20元。为什么选这个型号?除了性价比高,更重要的是资料丰富。当你凌晨三点调试遇到问题时,网上能搜到上百个相关案例。
电源设计要特别注意:整个系统需要5V供电,但STM32需要3.3V。建议用AMS1117-3.3稳压芯片,最大提供800mA电流,足够带动所有外设。记得在电源入口加个自恢复保险丝,我有次水泵短路导致整个系统烧毁,就是少了这个保护。
传感器接口设计要预留冗余。我习惯多引出一组I2C和ADC接口,后期想加PH传感器或TDS检测仪时直接插上就能用。PCB布局时把模拟和数字部分分开,模拟信号走线尽量短,否则ADC读数会跳变。
3.2 抗干扰设计
鱼缸环境电磁干扰很强,水泵和增氧机都是干扰源。硬件设计时要注意:
- 所有IO口串联100Ω电阻
- 模拟信号线并行走地线
- 关键芯片电源引脚加0.1μF去耦电容
软件上采用数字滤波算法。比如溶解氧传感器读数波动大,可以用滑动平均滤波:
#define FILTER_DEPTH 10
uint16_t oxygen_filter(uint16_t new_value) {
static uint16_t filter_buf[FILTER_DEPTH] = {0};
static uint8_t filter_index = 0;
static uint32_t filter_sum = 0;
filter_sum -= filter_buf[filter_index];
filter_buf[filter_index] = new_value;
filter_sum += new_value;
filter_index = (filter_index + 1) % FILTER_DEPTH;
return (uint16_t)(filter_sum / FILTER_DEPTH);
}
这样处理后的数据就很平稳了,避免系统因瞬时波动误动作。
4. 软件实现详解
4.1 主程序逻辑设计
程序采用状态机模式(图4-1),这是嵌入式系统最可靠的架构。上电后先初始化各外设,然后进入主循环持续检测水质。当某个参数超标时,立即跳转到对应处理状态。
正常监测状态下,系统每5秒采集一次数据,OLED屏实时显示数值。我发现很多人喜欢用1秒的采集间隔,其实完全没必要——水质变化没那么快,频繁采集反而浪费功耗。
异常处理状态分为三级响应:溶解氧低于5mg/L启动增氧泵,浊度超标启动过滤泵,水位过低则打开电磁阀补水。每个动作执行后都会重新检测参数,直到恢复正常值。
typedef enum {
STATE_NORMAL = 0,
STATE_OXYGEN_LOW,
STATE_TURBIDITY_HIGH,
STATE_WATER_LOW
} SystemState;
void main_loop() {
while(1) {
switch(current_state) {
case STATE_NORMAL:
monitor_parameters();
break;
case STATE_OXYGEN_LOW:
run_oxygen_pump();
break;
// 其他状态处理
}
delay_ms(100);
}
}
4.2 传感器驱动开发
DS18B20温度传感器的驱动最麻烦,时序要求严格。写驱动程序时要注意:
float read_temperature() {
if(ds18b20_init() != 0) return -1;
ds18b20_write_byte(0xCC); // 跳过ROM
ds18b20_write_byte(0x44); // 启动转换
delay_ms(750); // 等待转换完成
ds18b20_init();
ds18b20_write_byte(0xCC);
ds18b20_write_byte(0xBE); // 读取寄存器
uint8_t temp_l = ds18b20_read_byte();
uint8_t temp_h = ds18b20_read_byte();
int16_t temp_raw = (temp_h << 8) | temp_l;
return temp_raw * 0.0625; // 转换为摄氏度
}
浊度传感器就简单多了,直接读取ADC值:
uint16_t read_turbidity() {
uint16_t adc_value = adc_read(ADC_CHANNEL_3);
// 将ADC值转换为NTU浊度单位
return (uint16_t)(adc_value * 0.1234);
}
溶解氧传感器需要温度补偿,计算公式稍微复杂些:
float read_oxygen(float temperature) {
uint16_t adc_value = adc_read(ADC_CHANNEL_1);
float voltage = adc_value * 3.3 / 4096.0;
// 温度补偿公式,不同传感器系数不同
float oxygen = voltage * 10.0 + (temperature - 25) * 0.2;
return oxygen > 0 ? oxygen : 0;
}
5. 手机APP远程监控
5.1 蓝牙通信实现
用HC-06蓝牙模块实现手机连接,成本才10元左右。STM32通过串口发送数据:
void bluetooth_send_data(float temp, float oxygen, uint16_t turbidity) {
char buffer[64];
sprintf(buffer, "T:%.1f,O:%.1f,TU:%d\n", temp, oxygen, turbidity);
uart_send_string(USART2, buffer);
}
手机端可以用MIT App Inventor快速开发APP,拖拽组件就能做出监控界面(图5-1)。显示实时数据曲线,设置报警阈值,收到异常报警时推送通知。
数据包格式设计很重要,我建议用JSON格式虽然STM32处理起来麻烦点,但手机端解析方便。最简单的格式是:
{"t":25.6,"o":6.8,"tu":12}
5.2 低功耗优化
系统要长期运行,功耗必须优化。我的经验是:
- 采集间隔从1秒增加到5秒,功耗降低60%
- OLED屏设置15秒后自动关闭
- 蓝牙模块只在发送数据时使能
这样改造后,整个系统待机功耗不到0.5W,相当于普通鱼缸灯的十分之一。
6. 调试与优化经验
6.1 常见问题解决
传感器读数不准是最常见的问题。溶解氧传感器需要预热30分钟才能稳定,很多人刚上电就校准当然不准。校准方法很简单:把探头完全晾干时调节零点,放入饱和氧溶液中调节满量程。
电磁阀控制要加续流二极管,否则继电器通断时产生的感应电动势会损坏IO口。我就烧过一块STM32,后来在每个继电器线圈两端都反向并联了1N4007二极管。
电源干扰表现为ADC读数跳动。解决方法是在传感器电源端加π型滤波电路:10μF电解电容并联0.1μF瓷片电容,再串个10Ω电阻。
6.2 系统稳定性提升
要保证系统长期稳定运行,必须加入看门狗。STM32有硬件看门狗,初始化后每隔一段时间喂狗:
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_256); // 40kHz/256=156Hz
IWDG_SetReload(0xFFF); // 约26秒
IWDG_ReloadCounter();
IWDG_Enable();
在主循环中定期喂狗:
while(1) {
// 业务逻辑
IWDG_ReloadCounter();
delay_ms(100);
}
这样即使程序跑飞,26秒后也会自动复位。我还增加了数据异常判断:如果连续多次读数突变过大,就自动重启相关传感器。
7. 效果展示与改进方向
实际测试中,系统成功将鱼缸溶解氧维持在5mg/L以上,浊度控制在10NTU以内。当投入过量鱼食模拟污染时,系统在2分钟内启动过滤泵,10分钟后水质恢复正常。
成本核算:STM32核心板20元,传感器总计80元,执行器40元,其他零件30元,总成本170元。相比市售的智能鱼缸动辄上千元,这个方案极具性价比。
可以改进的地方还有很多:增加PH传感器监测酸碱度,加入TDS检测仪监测矿物质含量,甚至可以通过图像识别检测鱼类活动状态。我还想过加入自动喂食功能,但担心机械结构不可靠反而饿死了鱼。
最实用的改进是增加SD卡存储,记录长时间的水质变化趋势。这样就能分析出什么时候水质容易变差,提前采取预防措施。养鱼高手告诉我,看水质曲线比看实时数据更有用。
6461



被折叠的 条评论
为什么被折叠?



