简介:基于51单片机Proteus仿真的农田自动灌溉系统设计包,面向单片机入门学习者、课程设计及电子竞赛备赛者。系统以51单片机为控制核心,搭配SHT10温湿度传感器完成环境采集,LCD12864实时显示数据,通过按键灵活设定湿度阈值,继电器控制电机模拟排水与灌溉,并设有蜂鸣器告警提示,涵盖湿度超标排水、湿度过低灌溉等典型逻辑。资源压缩包共24个文件,约225KB,包含8个C程序源文件与8个头文件、Proteus仿真原理图(.dsn及.pdsprj工程)、HEX烧录文件、2张效果图、工作区文件及说明文本;源码模块化划分清晰,按键扫描、LCD驱动、SHT10读取、蜂鸣器发声、24C02存储等功能独立成模块,便于按需定位和修改。Proteus工程可直观演示传感器采集、阈值判断、继电器联动与排灌动作,配合说明文档可快速上手。目前已有163人学习下载,适合作为完整工程参考或二次开发基础。
1. 农田灌溉的痛点,为什么先落在Proteus仿真上
农田自动灌溉系统听起来是个农业工程,但真正动手做的时候,你会发现它本质上是一道“传感器读值 → 阈值判断 → 执行器动作”的嵌入式控制题。用51单片机加Proteus仿真来做这套设计,最大的价值不在于省掉买硬件的钱,而在于把整个系统的逻辑先跑通:土壤湿度怎么采集、水泵怎么被继电器控制、阈值能不能现场调,这些在仿真环境里用一个下午就能反复验证,不用等元件、不用担心烧板子。这个标题背后是课程设计和毕业设计里最常被翻牌子的方案,也是嵌入式入门者能完整接触“输入-处理-输出”闭环的第一个项目。你不需要有真实的农田,也不需要懂农业,只需要会C语言、能照图连线、耐着性子看数据手册,就能把这个系统做到能演示、能答辩的程度。
2. 系统拆解与器件选型:为什么这套电路能成为主流方案
2.1 工作流程先立住:湿度采集、阈值比较、水泵控制三者怎么串起来
自动灌溉系统的逻辑链并不复杂。土壤湿度传感器实时感知土壤的干湿程度,把湿度转换成电压信号;这个电压信号通常是模拟量,单片机只能处理数字量,所以中间需要一个模数转换器(ADC)把电压变成数值;单片机拿到数值后,与设定好的阈值比较——湿度低于下限,说明土壤偏干,单片机拉高继电器控制引脚,水泵通电开始灌溉;湿度高于上限,说明土壤足够湿润,单片机让继电器断开,水泵停止。整个过程反复循环,就构成了一个最基本的闭环控制。
这套逻辑里最容易被忽视的是一个细节:阈值不能是写死的。不同作物、不同土质的适宜湿度范围差别很大,所以设计里一般会加按键,让用户能现场调上限和下限,并把实时湿度、当前状态显示在LCD1602屏幕上。这看起来只是多几个按键和一行显示,实际上把系统从“固定逻辑演示”提升到了“可交互的工程样机”的高度。
还有一个方向值得提一下:状态机。很多人写灌溉逻辑喜欢用一个大循环,if湿度低就开泵,else就关泵,这在Proteus仿真里能跑,但拿到真实环境会出问题——土壤湿度在阈值附近抖动时,继电器会频繁吸合断开,水泵电机扛不住这种冲击。我一般会在主循环里维护一个灌溉状态机,状态只有“待机”“灌溉”“保持”三个,切换条件加上滞回区间(比如下限30、上限60,中间是滞回带),这样系统行为稳定得多。这个思路在后面写代码时会展开。
2.2 器件选型的三个关键取舍
单片机主控:STC89C52是这类设计的事实标准,原因很现实——Keil里支持完善,Proteus元件库里直接搜得到,网上参考代码几乎都是基于它的,出了任何问题都有人踩过坑。不要在这个位置标新立异选一个冷门型号,答辩和排错都会被拖累。
湿度检测方案:常见的低成本方案有两种。一种是土壤湿度传感器模块,输出0~5V模拟电压,干土电压高、湿土电压低(也有反的,取决于模块内部比较器接法);另一种是电阻式探针配合分压电路,本质也是测电阻变化。在Proteus仿真里,最省事的做法是用一个可变电阻(电位器)模拟传感器——湿度的变化就体现为抽头电压的变化,你甚至不需要装一个真实的传感器模型。这个“用电位器当传感器”的技巧,是仿真和实物之间最重要的思维切换。
ADC芯片选型:51单片机没有内置ADC,所以必须外扩。ADC0808(或ADC0809)是这个场景最常见的选择,8路模拟输入、8位分辨率,Proteus元件库里可以直接放进来,和单片机的接口也简单,一根地址锁存线决定当前采哪一路。8位分辨率对土壤湿度控制来说完全够用——256个档位分辨干湿程度,不是做高精度仪器,没必要上12位甚至16位ADC,那只会让电路复杂度和代码量一起膨胀。
继电器与水泵:单片机IO口驱动能力有限,直接接继电器往往带不动,需要三级管或驱动器IC扩流。Proteus仿真里很多人会跳过这一步直接把继电器线圈接到单片机引脚上,结果发现继电器不动或工作异常,其实这就是忽略了驱动电路的问题。仿真图中一定要保留ULN2003或NPN三极管(如S8550)驱动级,这不仅是仿真能跑的问题,更是实物移植时不出烟的安全底线。
提示:这类设计中“传感器选型”在答辩时是高频问题。能用3句话说清“为什么选电阻式湿度传感器+ADC0808方案——成本低、接口简单、精度对灌溉足够”,比背参数表留的印象深得多。
3. 在Proteus里搭仿真图:从空白图纸到可跑通的灌溉样机
3.1 新建工程与元件清单表
打开Proteus(我用的是Proteus 8.x,和7.x的菜单布局略有差异,但元件搜索和连线逻辑一致),新建一个Design,默认会自动生成一张A4图纸。先别急着画线,把元件清单列出来、从库里面找齐,这是后面最省时间的一步。元件搜索用的是“P”键直接输入关键词,找不全的话就是关键词不对,比如ADC0808在库里的名字可能是“ADC0808”,LCD1602需要搜“LM016L”,这是Proteus里LCD1602的模型名称,搜LCD1602反而找不到。
常见的元件清单和搜索关键词可以参考下表:
| 元件 | Proteus搜索关键词 | 数量 | 作用说明 |
|---|---|---|---|
| STC89C52 | 89C52 | 1 | 主控,Keil中选AT89C52即可 |
| ADC0808 | ADC0808 | 1 | 8通道模数转换,采集湿度电压 |
| LCD1602 | LM016L | 1 | 显示实时湿度、阈值、工作状态 |
| 电位器 | POT-HG或POT | 2 | 一路模拟湿度传感器,一路调节对比度 |
| 继电器 | RELAY | 1 | 控制水泵通断 |
| 水泵电机 | MOTOR | 1 | 灌溉执行器,用直流电机模型代替 |
| NPN三极管 | NPN或2N2222 | 1 | 驱动继电器线圈 |
| 轻触按键 | BUTTON | 3~4 | 功能按键:上调/下调/模式切换 |
| 晶振 | CRYSTAL | 1 | 12MHz,产生时钟 |
| 电容电阻 | CAP、RES | 若干 | 复位电路、上拉、限流 |
| 蜂鸣器 | BUZZER | 1 | 湿度异常或按键提示音 |
3.2 电路连线:把六个功能块串成一张图
元件放好之后,连线是整个仿真图的核心环节。我把这个电路分成六个功能块来看,每块连对了,整体就一定通。
电源与复位电路:VCC接5V,GND接地。复位电路用经典的10uF电解电容加10K电阻,高电平复位——PSTYLE上电瞬间RESET引脚保持高电平,单片机复位,然后电容充电完毕,RESET回低,程序从头跑。按键手动复位是可选功能,仿真里一般不接,但实物建议保留。
时钟电路:18脚和19脚(XTAL1和XTAL2)接12MHz晶振,两个30pF电容分别到地。Proteus里晶振频率要双击元件修改,默认值未必是12MHz,这个参数忘记改的话,后面调试串口和定时器计算全都会偏,属于典型的低级翻车点。
传感器与ADC接口:电位器抽头接ADC0808的IN0通道(具体脚位看元件引脚标注)。ADC0808的VREF+接5V,VREF-接GND,ALE和START引脚并联后接单片机P3.5(也可以选其他IO,只要代码里对应),EOC接P3.4,OE接P3.6,CLOCK接一个低频脉冲源,否则ADC内部逐次逼近没有时序基准。
单片机与LCD1602:LCD的RS、RW、E分别接P2.0、P2.1、P2.2,数据线D0~D7接P0.0~P0.7。P0口做数据口时必须接上拉电阻排(通常是10K排阻到VCC),否则LCD显示乱码——这是51单片机特有的坑,P0口内部没有上拉,Proteus仿真里不接上拉也有问题,表现形式就是屏幕亮但字符乱跳。
继电器驱动回路:单片机P3.7经10K电阻接NPN三极管基极,三极管发射极接地,集电极接继电器线圈一端,线圈另一端接5V,继电器开关端串联水泵电机到VCC。注意继电器线圈要并联一个续流二极管,方向是负极接VCC、正极接集电极。Proteus仿真里续流二极管缺了可能照样跑,但实物会打火花——仿真跑通不等于实物能跑,这是两个维度的事。
3.3 仿真参数设置:双时钟源、电压参考与电位器标定
连线结束后,双击每个元件检查关键参数。晶振设12MHz。A压控振荡器即ADC0808的CLOCK引脚,要求频率范围是10kHz~1MHz左右,Proteus里最方便的方法是放一个“Clock”发生器,把频率设成100kHz,输出接ADC的CLOCK。如果你不想额外放时钟源,也可以用单片机ALE引脚输出的脉冲(ALE是晶振频率的1/6,12MHz下正好是2MHz),这个频率对ADC0808来说偏高,建议还是用独立时钟源。
电位器的拖动是仿真交互体验的灵魂。双击电位器后,会弹出一个滑动条,鼠标拖动就能改变抽头比例——把抽头电压拉到接近0V,等价于传感器检测到“很湿”;拉到接近5V,等价于“很干”。实际系统中,传感器电压和湿度成反比还是正比取决于模块型号,仿真里你只需要定义一个规则:电压高于下限阈值对应土壤缺水。然后在LCD上看到湿度数值和状态显示联动变化,整套逻辑就闭环了。
4. 写51单片机源代码:用C语言把状态机跑起来
4.1 Keil工程结构与头文件配置
代码用Keil C51写。新建工程时芯片型号选AT89C52,如果你手头是STC89C52也别纠结,两者在Proteus仿真层面寄存器完全兼容。代码文件建议拆成三个:main.c放主逻辑,lcd1602.c放驱动,adc0808.c放采集函数。这种拆法对项目本身不是硬需求,但提示你在课设文档里“系统采用模块化程序设计”这句话有实际代码支撑,也比全部堆在一个文件里好调试。
先给一个精简版的主程序框架,完整逻辑说清楚之后你再往里填:
#include <reg52.h> #include <string.h> /* ADC0808 引脚定义 */ sbit ADC_START = P3^5; sbit ADC_EOC = P3^4; sbit ADC_OE = P3^6; sbit ADC_ALE = P3^5; /* ALE与START短接 */ /* LCD1602 引脚定义 */ sbit LCD_RS = P2^0; sbit LCD_RW = P2^1; sbit LCD_E = P2^2; /* 继电器与蜂鸣器 */ sbit RELAY = P3^7; sbit BUZZER = P3^3; #define THRESHOLD_DRY 200 /* 湿度下限:高于此值认为缺水 */ #define THRESHOLD_WET 60 /* 湿度上限:低于此值认为湿度过高 */ #define SAMPLE_TIMES 8 /* 每次连续采样次数,取平均 */ void ADC0808_Init(void); unsigned int ADC0808_Read(unsigned char channel); void Relay_Control(unsigned char on);引脚定义有一个细节值得说明:ADC0808的START和ALE通常直接连在一起,都用P3.5控制,所以代码里ADC_START和ADC_ALE指向同一个引脚。这样写的好处是代码语义清晰,硬件连接也不用额外引线。RELAY和BUZZER的引脚位置按仿真图调整,只要保持一致就没什么问题。
4.2 主循环与灌溉状态机:为什么不能一个if搞定
主程序的结构是初始化、按键扫描、ADC采样、LCD刷新、状态机切换,循环往复。这里的核心设计是状态机,不是裸的if-else。我用两个阈值把湿度区间切成三段:湿度值小于WET,视为“过湿”;湿度值介于WET和DRY之间,视为“适宜”;湿度值大于DRY,视为“缺水”。状态机只有在“当前状态与目标状态不一致”时才动作,人为加一个滞回带,避免阀门在阈值边界抖动。
typedef enum { STATE_IDLE, /* 待机,湿度适宜 */ STATE_IRRIGATE, /* 灌溉中 */ STATE_HOLD /* 保持中,等待渗透完成 */ } IrrigState; volatile IrrigState current_state = STATE_IDLE; volatile unsigned int irrigation_timer = 0; /* 灌溉持续时间 */ void IrrigStateMachine(unsigned int humidity) { switch (current_state) { case STATE_IDLE: if (humidity > THRESHOLD_DRY) { current_state = STATE_IRRIGATE; Relay_Control(1); /* 启动水泵 */ } break; case STATE_IRRIGATE: if (humidity < THRESHOLD_WET) { current_state = STATE_HOLD; /* 湿度已达标 */ Relay_Control(0); irrigation_timer = 60000; /* 保持60秒,让水分渗透 */ } break; case STATE_HOLD: if (irrigation_timer > 0) { irrigation_timer--; } else { current_state = STATE_IDLE; /* 渗透期结束,回到待机 */ } break; default: current_state = STATE_IDLE; break; } }主循环里调用这个函数时,会先读AD值、做平均值滤波,然后传给状态机。HOLD状态设置了一个递减计时器,仿真里你会发现:即使湿度已经达标,系统也不会立刻重采,而是等一个“渗透期”,这非常贴近真实灌溉场景——水从土壤表面渗透到根部需要时间,刚浇完立刻采样,传感器可能还在露出水面的位置,数值虚高。
void main(void) { unsigned int humidity = 0; unsigned int avg = 0; ADC0808_Init(); LCD_Init(); LCD_ShowString(1, 1, "Auto-Irrigate Sys"); while (1) { /* 按键扫描被省略,正常实现时会在这里处理阈值加减 */ avg = 0; for (unsigned char i = 0; i < SAMPLE_TIMES; i++) { avg += ADC0808_Read(0); } avg /= SAMPLE_TIMES; humidity = avg; /* 8位ADC值直接作为湿度百分比 */ IrrigStateMachine(humidity); LCD_ShowValue(2, 1, humidity); /* 实时显示湿度值 */ delay_ms(100); /* 每100ms刷新一次,足够及时 */ } }这里的采样次数SAMPLE_TIMES取8次取平均,是一个务实的折中——92系列的单片机跑12MHz时,一次AD转换加读取不到几十微秒,8次采样带来的延迟几乎可以忽略,但对抑制电位器或真实传感器输出端的高频噪声有明显作用。如果你用的是STC15系列等1T单片机,这个参数可以再提到16次,几乎不占时间。
4.3 ADC0808驱动时序:读一次AD值要踩准四个信号
ADC0808的时序大概是这个路径:把通道地址锁存到芯片内部(ALE拉高再拉低),启动转换(START拉高再拉低),等待转换结束信号(EOC引脚从高变为低,表示转换完成,然后变回高),最后打开输出使能(OE拉高),从数据总线读出8位结果。下面这段代码是精简的时序实现,重点在于每次读完之后OE要及时拉低,否则数据总线一直处于被驱动状态,影响后续采样。
unsigned int ADC0808_Read(unsigned char channel) { unsigned char result = 0; unsigned int value = 0; /* 锁存通道地址 */ ADC_ALE = 0; P1 &= 0xF8; /* 低3位清零 */ P1 |= (channel & 0x07); /* 选择通道0~7,这里只用到0 */ ADC_ALE = 1; ADC_ALE = 0; /* 启动转换 */ ADC_START = 1; ADC_START = 0; /* 等待EOC变低,表示转换完成 */ while (ADC_EOC == 1); /* 输出使能,读取数据 */ ADC_OE = 1; result = P1; /* 数据输出复用在P1口,低8位有效 */ ADC_OE = 0; /* 将8位结果映射到0~255 */ value = result; return value; }这段代码有两个坑值得单独说。
第一,数据输出引脚是P1口,但通道选择也在P1口的低3位,这意味着读数据之前不能把P1口全写0,否则会改变通道地址。在上面的代码里,读数据用的是result = P1,不会向P1写入,所以没有这个问题,但如果你习惯先P1 = xx再读,就会把通道地址搞乱,读出来的值忽高忽低。
第二,while(ADC_EOC == 1)是死等,如果AD芯片没有时钟输入(CLOCK引脚悬空),这个循环就会一直在里面空转,现象是整个程序“卡死”在ADC函数里,主循环不再刷新LCD。后期A拉高了也不闪,板子看起来像是死了,其实是在空等。这个问题在硬件层面修比代码层面修更直接:给CLOCK引脚接一个外部时钟源,或者检查Proteus里的Clock器件是否设了正确频率。
4.4 LCD1602驱动与按键阈值调节
LCD1602驱动直接用标准的4线或8线驱动。Proteus里的LM016L模型对8线模式支持最稳定,我建议全程用8线驱动,不要为了省两根IO线去用4线模式,仿真模型对时序的要求比想象中的严,4线模式下经常出现“能初始化但显示乱码”的情况,排查起来非常浪费精力。
LCD初始化、写命令、写数据这几段函数在江科大的51单片机笔记里已经很成熟了,照着标准写法就行。按键部分,我建议加三个功能键:“+1”键上调湿度下限阈值,“-1”键下调,“模式键”切换显示页面——页面1显示实时湿度,页面2显示两个阈值的设定值。这个交互距离“可答辩”还有一步:LCD显示阈值的同时,最好把“当前是否处于灌溉状态”用一个图标标识出来,比如第2行末尾显示“IRRIGATE”或“STANDBY”,评审老师一眼就能看懂系统状态,比让他自己观察继电器指示灯更直观。
我需要特别指出一点:不要把阈值调节做得太复杂。有人会加上“长按加速”“短按微调”这种交互设计,在真实产品里这是合理的,但作为课程设计项目,按键去抖、短按长按识别会让代码量增加三四百行,并且Proteus仿真中对长按的判断极易误触发,去年我见过好几个同学在答辩演示时按键失灵,最后都是把长按逻辑删掉才稳定。一个按键一次加1,按住不放靠重复触发,就够了。
5. Proteus仿真排错实战:五个高频踩坑点与修复方案
5.1 继电器始终不动作,电机不转
现象:程序跑起来了,LCD显示湿度值也能变化,但不管湿度飙到多高,继电器就是没反应,电机纹丝不动。
原因:这类问题七成出在驱动电流不够。Proteus的继电器模型有最小吸合电流参数,如果你直接把继电器线圈接到51单片机的P3.7引脚,引脚输出高电平时的驱动能力很可能低于继电器的吸合电流,继电器处于半吸合状态,表现为“嗒嗒”乱响或者完全不动作。
解决:在继电器线圈和单片机引脚之间加一个NPN三极管放大,基极串1K~10K限流电阻,发射极接地,继电器线圈接在集电极和VCC之间。再给线圈并联一个续流二极管,方向是二极管的阳极接集电极,阴极接VCC,防止继电器断电瞬间的反向电动势损坏三极管。改完之后点运行,继电器吸合的声音会变得干脆利落。
5.2 ADC0808采集值恒为0或恒为255
现象:无论电位器怎么拖,LCD上显示的湿度值要么固定在0,要么固定在255,完全不受传感器影响。
原因:恒为0,常见的是ADC的OE引脚没有正确拉高,数据根本没输出到P1口,你读到的全是0;恒为255,常见的是ADC数据线的引脚定义和实际电路接错了,读到的是上拉电阻的高电平。还有一种隐蔽的情况:EOC引脚一直为低,转还没完成就假完成,时序错乱导致读到的数据是上一次的残留值。
解决:先用一个固定电压源直接接到IN0通道,比如用一个2.5V的直流源,如果读值稳定在约128附近,说明ADC链路是好的,问题在传感器电位器那一侧。接着检查EOC、OE、CLOCK三个引脚的波形——Proteus里可以直接右键触点放置电压探针,运行后用虚拟示波器看,EOC应该是一个短脉冲而不是恒电平。另外一个最容易忽略的点是ADC0808的START和ALE都要有从低到高再从高到低的跳变,不能只给恒高。
5.3 湿度值在阈值附近时,继电器疯狂抖动
现象:电位器缓慢拖动到阈值附近时,继电器开始快速吸合断开,电机一抽一抽地转,LCD上的状态显示在“灌溉”和“待机”之间高频切换。
原因:这就是典型的阈值抖动。8位ADC的精度下,湿度值在阈值边界附近会大幅跳变,比如这一帧读数是199,下一帧就跳到201,超过阈值就开泵,低于阈值就关泵,系统变成了一个没有滞回的振荡器,控制规律完全是坏的。
解决:用我在主循环里实现的滞回区间。阈值不再是一个点,而是一个区间:下限设为200,上限设为60,湿度值在60~200之间时,状态保持当前不变。只有在湿度值超过200时才启动灌溉,也只有在湿度值低于60时才停止灌溉。中间地带留给系统“思考”,实际效果非常明显,从仿真到实物都应该始终坚持这个写法。这也是答辩时老师最喜欢追问的细节,回答得出来就是加分项。
5.4 LCD1602显示乱码或者显示不出字符
现象:屏幕亮了,但显示的不是“Auto-Irrigate Sys”,而是一堆方块或者乱码,有的情况下第一行正常、第二行乱。
原因:90%的情况是P0口没有接上拉排阻,或者上拉电阻的阻值太大,比如用100K可能效果不好,10K是比较稳妥的常见取值。另外一个原因是E引脚(使能)的时序问题,LCD1602的数据锁存是在E引脚的下降沿完成的,如果你的E引脚脉冲宽度太窄,LCD芯片来不及采到数据线电平,就会用上一次的数据,显示自然错乱。
解决:确定P0口接了10K排阻到VCC后,在写数据函数体的E引脚操作后加一小段延时,参考实现是LCD_E=1; delay_us(5); LCD_E=0;。给E拉高后留出足够的建立时间给LCD内部逻辑去采信号,这个延时在仿真环境里可以改小到2~3微秒,但保留它会让代码在实物上也同样稳定。
5.5 Proteus和Keil联合调试时联不上
现象:在Proteus里点击运行,单片机没有任何反应,像是一块没烧录的板子。Proteus提示“Cannot open ‘...hex’”,或者干脆弹窗说加载程序失败。
原因:这是一个流程性错误而不是电路错误。Proteus要运行51单片机的程序,你必须先让Keil编译生成HEX文件,然后在Proteus里双击单片机芯片,在Program File选项里指向这个HEX文件的路径。很多人把C文件编译了就直接点Proteus运行,忽略了Proteus根本不认识.uvprojx工程文件。
解决:完全按“三步走”来操作。第一步,在Keil中确认Target选项里勾选“Create HEX File”(在Options for Target → Output选项卡),每次编译时才会生成.hex。第二步,把.hex文件路径里的中文名和空格全部去掉——Proteus对中文路径的支持非常糟糕,文件放在“D:\irrigation\code.hex”比放在“C:\Users\张三\桌面\灌溉系统代码.hex”可靠一百倍。第三步,在Proteus中双击单片机,指定HEX文件,再点左下角的运行按钮调试。
6. 从仿真到实物移植和进阶验证:别让设计停在“看起来能跑”
Proteus仿真只是第一步,真正的技术含量在“把这个仿真变成真实电路”的过程中。仿真里用的电位器,到了实物上要换成真实的土壤湿度传感器模块(一般是带探针的LM393电压比较器模块,输出数字量和模拟量两种信号,接模拟量输出即可)。传感器探针插入土壤后,第一次上电先要标定:把探针插在干燥的土壤里读取一个数值,再插在水里读取一个数值,这两个值就是你代码里湿度和干度的实际边界。千万不要照抄别人的阈值,不同土壤、不同模块的输出范围天差地别。
水泵驱动也要换思路。仿真里用直流电机模型代替水泵,实物上如果是220V交流水泵,继电器必须换成带隔离的交流接触器,控制板和强电之间要做好电气隔离,弱电控制回路和强电主回路要分板布局。这个不是可选项,是安全底线。即使是12V直流小水泵,也要在继电器输出端加一个保险丝,防止堵转烧电机。
验证方法方面,至少要做三件事。第一,模拟干土测试:不加水时系统应自动启动灌溉,LCD显示状态为“灌溉中”,继电器吸合,水泵运转。第二,模拟湿土测试:把传感器探头放入水中,湿度值应达到或超过上限阈值,水泵在规定时间内停止,系统进入“保持”状态。第三,阈值可调测试:用按键把下限阈值调到当前湿度之上或之下,看系统是否立即执行对应的开关动作。这三步走完,这个设计才是完整的,而不是一个“演示时碰运气”的仿真。
我个人的习惯性是,每次改完硬件或者换了一个传感器模块,都会先跑10分钟连续采样,把采到的值画成折线,看看传感器有没有周期性漂移。土壤湿度传感器本质是把两个电极插在土里测电阻,电极极化效应会导致测量值缓慢漂移,如果你发现湿度值一直平稳但突然跳变,大概率是电极和土壤之间接触出了问题——这个经验在答辩前最后一次调试时能救命。希望这个设计能让你真正理解嵌入式系统“输入-处理-输出”的闭环本质,也祝你一次点亮,希望帮到你。
本文还有配套的精品资源,点击获取