【STM32项目】基于 STM32L475 的智慧农业大棚环境检测与自动控制系统前言本项目是《嵌入式系统与接口技术课程设计》的期末大作业使用正点原子潘多拉IoT开发板以STM32L475VET6为核心控制器设计并实现了一套智慧农业大棚环境检测系统。系统接入DHT11温湿度传感器、光敏传感器、酒精传感器、PIR人体红外传感器和超声波传感器可对温湿度、光照强度、模拟气体浓度、人员状态和水位距离进行检测。在数据采集的基础上系统还实现了自动补光、人员状态指示、水位异常判断、蜂鸣器报警、LCD分页显示和串口数据输出等功能形成了完整的传感器采集 → 数据处理 → 阈值判断 → 执行器控制 → 状态显示 → 异常报警项目综合使用了GPIO、ADC、单总线通信、超声波时序测量、串口通信、LCD显示、按键输入、继电器控制和蜂鸣器报警等嵌入式接口技术。一、项目功能介绍本系统主要实现以下功能使用 DHT11 采集环境温度和湿度使用酒精传感器模拟检测空气异常气体浓度使用光敏传感器检测当前环境光照强度当光照强度低于 35% 时自动控制继电器开启补光使用 PIR 人体红外传感器模拟人员进入和离开使用红灯和绿灯显示当前人员状态使用超声波模块测量距离模拟水箱水位当水位距离小于 3 cm 或大于 25 cm 时判断水位异常使用 KEY0 切换 LCD 显示页面使用KEY1开启或关闭蜂鸣器报警使用蜂鸣器对气体异常和水位异常进行周期报警使用USART1向串口调试助手输出完整运行数据。系统最终实现了环境数据采集、自动控制、人机交互和异常报警等功能。二、系统总体方案系统整体可以划分为三个层次1. 传感器采集层负责采集农业大棚中的各类环境信息包括DHT11温度和湿度酒精传感器模拟空气异常气体浓度光敏传感器光照强度PIR 人体红外传感器人员触发状态超声波传感器水箱液面距离。2. STM32主控处理层STM32L475VET6 主要负责读取传感器数据对 ADC 数据进行换算根据设定阈值判断异常管理人员进入和离开状态控制继电器、LED 和蜂鸣器管理 LCD 显示页面周期输出串口数据。3. 显示与执行层输出设备包括LCD显示屏继电器模块红色和绿色LED蜂鸣器串口调试助手。系统整体运行流程如下系统初始化 ↓ 按键扫描 ↓ 传感器数据采集 ↓ 数据换算与状态判断 ↓ 继电器、LED和蜂鸣器控制 ↓ LCD页面显示 ↓ 串口数据输出 ↓ 返回主循环农业大棚系统技术路线图三、硬件组成本项目使用的主要硬件如下。硬件模块主要作用STM32L475VET6 开发板系统主控制器DHT11检测温度和湿度酒精传感器模拟检测异常气体浓度光敏传感器检测光照强度PIR人体红外传感器检测人员触发信号超声波传感器测量距离并模拟水位继电器模块模拟控制大棚补光灯LCD显示屏分页显示系统数据蜂鸣器异常报警KEY0、KEY1页面切换和报警控制红色、绿色 LED显示人员状态USB 下载线程序下载与供电需要说明的是酒精传感器在本项目中主要用于模拟空气异常气体浓度检测并不是专业的农业气体检测设备。同样超声波模块通过检测目标面的距离来模拟水箱水位状态。四、软件开发环境本项目的软件开发环境如下STM32CubeMXKeil MDK-ARMSTM32 HAL 库串口调试助手ST-Link 或开发板板载下载器。其中STM32CubeMX 负责芯片型号、时钟、GPIO、ADC 和 USART 等外设配置Keil 负责代码编写、工程编译和程序下载HAL 库负责外设驱动串口调试助手负责观察系统运行数据。五、引脚分配本项目的主要引脚分配如下功能模块STM32引脚功能说明DHT11PB8单总线温湿度读取PIR人体红外PB9GPIO输入检测超声波TrigPB10发送触发脉冲超声波EchoPB11接收回波信号酒精传感器PC4ADC模拟量采集光敏传感器PA4ADC模拟量采集继电器PD12控制补光灯蜂鸣器PB2异常报警KEY0PD10LCD页面切换KEY1PD9报警使能控制红绿LEDPE7、PE8人员状态指示USART1 TX/RXPA9、PA10串口数据输出以上引脚需要在 STM32CubeMX 中完成对应配置。六、系统软件结构为了便于调试和维护程序采用模块化设计。主要模块包括main.c ├── 按键扫描模块 ├── ADC采集模块 ├── DHT11温湿度模块 ├── PIR人体检测模块 ├── 超声波测距模块 ├── 继电器控制模块 ├── LED状态指示模块 ├── 蜂鸣器报警模块 ├── LCD显示模块 └── 串口输出模块主函数主要负责初始化各个外设调用不同传感器模块完成阈值判断控制执行器状态更新LCD页面输出串口数据。主循环调用关系可以简化为while(1){Key_Direct_Scan();GH_ADC_Update();pir_statePIR_GetState();PIR_Event_Process();if(light_percentLIGHT_LOW_THRESHOLD){Relay_On();}else{Relay_Off();}DHT11_ReadData(dht_temp,dht_humi);Ultrasonic_ReadDistance(water_distance);Alarm_Check();Buzzer_Task();LCD_Display_Update();}实际程序中不同模块并不是每次循环都同时执行。例如DHT11每 2 秒更新一次超声波每 1 秒测距一次ADC和按键按照更短周期更新LCD根据当前页面周期刷新。程序可以使用HAL_GetTick()实现不同任务的周期调度避免所有任务同时运行造成阻塞。七、核心功能实现7.1 DHT11 温湿度采集DHT11采用单总线通信方式通过一个数据引脚完成温度和湿度数据传输。本项目将 DHT11 数据引脚连接到 PB8。采集完成后将温度和湿度分别保存到变量中uint8_tdht_temp0;uint8_tdht_humi0;DHT11_ReadData(dht_temp,dht_humi);为了避免读取过于频繁导致数据不稳定程序设置 DHT11 每 2 秒读取一次。示例周期调度逻辑如下if(HAL_GetTick()-dht_last_tick2000){dht_last_tickHAL_GetTick();DHT11_ReadData(dht_temp,dht_humi);}读取完成后温湿度数据同时显示在 LCD 和串口调试助手中。7.2 ADC 模拟量采集酒精传感器和光敏传感器均输出模拟电压因此需要使用 STM32 的 ADC 外设进行采集。本项目中酒精传感器连接PC4光敏传感器连接PA4。ADC 读取到的原始数据范围通常为0 4095为了方便LCD显示和阈值判断程序将ADC原始值换算为百分比gas_percentgas_adc_value*100/4095;light_percentlight_adc_value*100/4095;转换完成后gas_percent表示模拟气体浓度百分比light_percent表示光照强度百分比。相比直接显示ADC原始值百分比形式更加直观。7.3 气体异常判断系统设定气体浓度大于 75% 时判断为空气异常。对应代码如下#defineGAS_ALARM_THRESHOLD75gas_alarm(gas_percentGAS_ALARM_THRESHOLD);当gas_percent大于 75 时gas_alarm1;否则gas_alarm0;该状态会参与蜂鸣器报警判断。需要注意的是酒精传感器在本项目中主要用于验证ADC 采集百分比换算阈值判断报警联动。7.4 光照检测与自动补光光敏传感器用于检测当前环境光照强度。系统设定光照强度低于 35% 时自动开启继电器。对应代码如下#defineLIGHT_LOW_THRESHOLD35if(light_percentLIGHT_LOW_THRESHOLD){Relay_On();}else{Relay_Off();}当用手遮挡光敏传感器时光照百分比会下降。如果光照低于 35%继电器吸合LCD 显示Lamp Status: ON模拟补光灯开启。当光照恢复到 35% 以上继电器断开LCD 显示Lamp Status: OFF模拟补光灯关闭。该功能实现了光照采集 → 阈值判断 → 继电器控制这是系统中的一个典型闭环控制功能。7.5 PIR 人员状态检测PIR 人体红外传感器可以检测人体经过时产生的触发信号。如果直接将 PIR 高电平理解为“有人”可能会受到传感器高电平保持时间的影响。例如人体经过后 PIR 可能持续输出一段时间高电平。如果程序每次循环都进行状态切换就会导致人员状态不断变化。因此本项目采用PIR 每触发一次人员状态切换一次。核心代码如下if((last_pir_statePIR_SAFE)(pir_statePIR_DETECTED)){pir_trigger_count;if(people_statePEOPLE_OUT){people_statePEOPLE_IN;}else{people_statePEOPLE_OUT;}People_LED_Update(people_state);}last_pir_statepir_state;这里判断的是PIR信号从Safe → Detect的变化瞬间也就是信号上升沿。只有在上升沿到来时程序才切换一次人员状态。这样可以避免一次PIR高电平持续期间产生多次误切换。7.6 红绿灯人员状态指示人员状态通过红灯和绿灯进行显示。系统规则如下人员状态红灯绿灯People Outside亮灭People Inside灭亮示例代码voidPeople_LED_Update(uint8_tpeople_state){if(people_statePEOPLE_IN){Red_LED_Off();Green_LED_On();}else{Green_LED_Off();Red_LED_On();}}系统上电后默认为无人状态People Outside此时红灯点亮。PIR 第一次触发后People Inside绿灯点亮。PIR 再次触发后状态重新变为People Outside7.7 超声波测距超声波模块使用 Trig 和 Echo 两个信号引脚。本项目中Trig 连接 PB10Echo 连接 PB11。测距过程如下Trig 输出一个短高电平脉冲超声波模块发射声波Echo引脚输出高电平测量Echo高电平持续时间根据时间换算距离。发送触发脉冲HAL_GPIO_WritePin(TRIG_PORT,TRIG_PIN,GPIO_PIN_SET);DWT_Delay_us(20);HAL_GPIO_WritePin(TRIG_PORT,TRIG_PIN,GPIO_PIN_RESET);距离换算公式为距离(cm) ≈ Echo高电平时间(us) ÷ 58代码如下*distance_cm(uint16_t)((echo_time_us29)/58);在整数运算中先加29再除以58可以实现近似四舍五入。7.8 水位异常判断本项目使用超声波距离模拟水箱水位。如果超声波模块安装在水箱顶部那么距离越小表示水位越高距离越大表示水位越低。系统设定距离小于 3 cm水位过高 距离大于 25 cm水位过低判断代码如下if((water_distance3)||(water_distance25)){water_alarm1;}else{water_alarm0;}两种情况都会触发水位异常标志。在实际测试时需要保持超声波模块方向固定并尽量使用平整目标面以提高测距稳定性。7.9 KEY0 页面切换KEY0 用于切换 LCD 显示页面。系统设计了四个页面页面编号页面名称显示内容0Environment温度、湿度、气体浓度1Light Control光照、继电器、水位2People Status人员状态、红绿灯、触发次数3Warning Monitor报警使能、蜂鸣器、报警原因按键检测代码如下if((key0_last_levelGPIO_PIN_SET)(key0_nowGPIO_PIN_RESET)){lcd_page(lcd_page1)%4;lcd_force_update1;}其中lcd_page(lcd_page1)%4;可以使页面编号在以下范围内循环0 → 1 → 2 → 3 → 0相比将所有数据显示在同一个页面多页面显示更加清晰也更适合项目演示。7.10 KEY1 报警使能KEY1 用于控制蜂鸣器报警功能。按一次 KEY1Warning Enable再次按下Warning Disable对应代码如下if((key1_last_levelGPIO_PIN_SET)(key1_nowGPIO_PIN_RESET)){buzzer_warning_enable!buzzer_warning_enable;if(buzzer_warning_enable0){Buzzer_Stop();}}使用报警使能开关后即使传感器检测到异常也可以手动关闭蜂鸣器。但是 LCD 仍然保留异常原因便于查看当前故障状态。7.11 蜂鸣器报警逻辑蜂鸣器报警由两个条件共同控制KEY1已经开启报警气体或水位出现异常。首先合并报警条件alarm_condition(gas_alarm||water_alarm);然后判断是否允许报警if((buzzer_warning_enable0)||(alarm_condition0)){Buzzer_Stop();return;}只有报警使能且存在异常时蜂鸣器才开始工作。为了避免蜂鸣器一直长鸣系统采用周期短响方式if((HAL_GetTick()-buzzer_last_period_tick)BUZZER_PERIOD_TIME){buzzer_last_period_tickHAL_GetTick();Buzzer_Start_Beep();}使用HAL_GetTick()进行周期控制相比直接使用长时间HAL_Delay()不会长时间阻塞主循环。7.12 LCD 分页显示系统使用 LCD 显示不同模块的数据。Environment 页面主要显示Temperature Humidity Air LevelLight Control 页面主要显示Light Level Lamp Status WaterPeople Status 页面主要显示People Inside / Outside Red Light / Green Light PIR CountWarning Monitor 页面主要显示Warning Enable / Disable Buzzer Active / Silent ReasonLCD 分页显示可以提高信息层次避免过多内容集中在同一页面。7.13 串口数据输出USART1 用于向串口调试助手输出系统运行数据。串口配置如下参数配置波特率115200数据位8 位校验位None停止位1 位串口输出内容包括Temperature Humidity Air Level Light Level Lamp Status Water People PIR Sensor Warning Alarm ADC Status LCD Page示例输出 GreenHouse Data Temperature : 30 Humidity : 62% Air Level : 85% Light Level : 100% Lamp Status : OFF Water : 15cm People : Outside PIR Sensor : Safe Warning : Enable Alarm : GasNormal | WaterNormal LCD Page : 0 串口数据可以用于判断传感器是否正常采集LCD 显示是否正确报警条件是否成立继电器状态是否正确当前页面编号是否正确。八、系统运行步骤8.1 检查硬件连接按照引脚分配表完成接线重点检查电源是否正确GND 是否共地信号线是否接反ADC 模块输出是否连接到正确引脚超声波 Trig 和 Echo 是否接反继电器模块供电是否正常。8.2 配置STM32CubeMX在 STM32CubeMX 中完成选择 STM32L475VET6配置系统时钟配置 GPIO 输入和输出配置 ADC 通道配置 USART1配置调试接口生成Keil工程。8.3 编译并下载程序使用 Keil 打开工程后点击编译确认无错误连接开发板点击Download将程序下载到 STM32L475。8.4 测试 LCD 页面系统上电后默认显示 Environment 页面。按下 KEY0页面依次切换Environment ↓ Light Control ↓ People Status ↓ Warning Monitor8.5 测试光照联动使用手遮挡光敏传感器。当光照低于 35% 时Lamp Status: ON继电器吸合。移开遮挡物后Lamp Status: OFF继电器断开。8.6 测试人员状态在 PIR 传感器前移动。第一次触发People Inside Green Light ON第二次触发People Outside Red Light ON8.7 测试水位报警改变超声波传感器与目标物之间的距离。当距离小于 3 cm或者大于 25 cm系统判断为水位异常。按下KEY1开启报警后蜂鸣器开始周期短响。8.8 观察串口数据打开串口调试助手并设置115200 8 None 1连接后可以观察系统周期输出的各项数据和状态。九、系统运行效果经过测试系统实现了以下功能DHT11 温湿度采集正常气体浓度 ADC 采集正常光照低于 35% 时继电器能够自动开启PIR 每触发一次可切换一次人员状态红灯和绿灯能够同步显示人员状态超声波距离能够用于模拟水位水位异常时能够触发报警KEY0可以切换四个LCD页面KEY1可以控制报警使能串口能够周期输出系统状态。典型测试数据如下。测试场景关键数据或状态系统响应环境数据采集Temperature30℃Humidity62%LCD和串口正常显示模拟气体异常Air Level85%气体异常标志置位正常光照Light Level100%继电器关闭人员外出People Outside红灯亮人员进入People Inside绿灯亮水位异常Water Error蜂鸣器报警报警关闭Warning Disable蜂鸣器停止项目测试结果表明各传感器、执行器、LCD页面和按键功能基本能够按照预期逻辑运行。十、调试过程中遇到的问题10.1 多个模块引脚冲突问题现象将多个独立实验整合到同一个项目后部分传感器、LCD、串口和按键使用了相同引脚。原因分析不同例程通常按照自己的默认引脚配置直接组合时容易产生资源冲突。解决方法重新规划引脚资源统一在STM32CubeMX中配置PB8 → DHT11 PB9 → PIR PB10 → Trig PB11 → Echo PC4 → 酒精传感器 PA4 → 光敏传感器 PD12 → 继电器同时检查这些引脚是否与LCD和串口资源冲突。10.2 LCD显示内容过多问题现象如果将所有传感器数据放在同一页面显示内容拥挤不便于观察。解决方法将LCD划分为四个页面并使用KEY0切换。这样不仅提高了界面可读性也便于现场逐项展示功能。10.3 PIR触发一次却多次切换问题现象人体经过PIR后人员状态在进入和离开之间快速切换多次。原因分析PIR检测到人体后高电平会持续一段时间。如果程序直接判断if(pir_statePIR_DETECTED){people_state!people_state;}那么在高电平持续期间主循环会重复执行状态翻转。解决方法检测PIR的上升沿Safe → Detect只有在状态变化瞬间执行一次切换。10.4 蜂鸣器一直鸣响问题现象异常状态持续时蜂鸣器一直响影响调试和演示。解决方法增加KEY1报警使能开关。只有满足以下两个条件时才报警Warning Enable 存在气体异常或水位异常同时使用HAL_GetTick()实现周期短响。10.5 超声波测距不稳定问题现象测距数据偶尔跳变或者出现错误值。可能原因目标面不平整传感器角度倾斜接线松动Echo信号测量超时目标距离超过有效范围供电不稳定。解决方法固定传感器方向使用平整目标面检查Trig和Echo接线增加超时判断对连续多次测量结果进行平均或中值滤波在串口中输出原始回波时间和错误状态。十一、项目总结本项目完成了一套基于STM32L475VET6的智慧农业大棚环境检测与自动控制系统。系统综合使用了GPIO输入输出ADC模拟量采集DHT11单总线通信超声波时序测量串口通信LCD显示按键输入继电器控制LED状态指示蜂鸣器报警。项目不仅实现了多个传感器的数据采集还进一步实现了光照不足自动补光人员进出状态切换水位异常判断气体异常判断多页面数据显示报警使能控制周期蜂鸣器报警。最终形成了完整的嵌入式系统运行流程数据采集 ↓ 数据处理 ↓ 阈值判断 ↓ 执行器控制 ↓ 状态显示 ↓ 异常报警通过本项目可以进一步理解STM32多外设协同工作、模块化程序设计和非阻塞周期任务调度的基本方法。十二、后续优化方向目前系统仍然存在一定的优化空间。1. 替换专业农业传感器可以将酒精传感器替换为CO₂传感器氨气传感器甲烷传感器空气质量传感器。这样能够提高项目与农业场景的匹配程度。2. 增加土壤湿度检测增加土壤湿度传感器后可以检测土壤含水量。当土壤湿度过低时自动控制水泵进行灌溉。3. 增加自动灌溉增加水泵电磁阀MOS管或继电器驱动模块。可以实现土壤湿度检测 ↓ 湿度低于阈值 ↓ 开启水泵 ↓ 湿度恢复 ↓ 关闭水泵4. 增加无线通信可以加入ESP8266ESP32LoRa蓝牙4G通信模块。将采集数据上传到网页、手机或云平台。5. 增加远程监控后续可以接入MQTT服务器阿里云物联网平台OneNET自建Flask服务器WebSocket网页。实现远程查看温湿度、光照、水位和报警状态。6. 未来优化LCD界面可以增加图标进度条折线图不同颜色的报警提示中文显示触摸操作。使系统更加接近实际农业监控终端。文章说明本文项目来源于《嵌入式系统与接口技术课程设计》期末大作业主要用于学习STM32多传感器采集、状态判断、执行器控制和人机交互。项目中的酒精传感器和超声波模块主要用于模拟异常气体和水箱水位场景当前系统更侧重于嵌入式接口技术和控制逻辑验证并未直接达到实际农业生产环境的部署标准。