基于STM32单片机的智能自动浇花灌溉系统设计
摘要
随着生活节奏的加快和智能家居技术的不断发展,智能自动浇花灌溉系统逐渐受到人们的青睐。本文设计了一种基于STM32单片机的智能自动浇花灌溉系统,通过DHT11温湿度传感器采集当前环境湿度,LCD1602显示屏显示湿度信息及用户设置的湿度阈值,继电器控制浇水电机的启停,实现自动灌溉功能。同时,系统还具备按键设置湿度阈值及蜂鸣器提醒功能,提高了用户体验。本文详细介绍了系统的硬件设计、软件编程及功能实现过程。
1. 引言
在现代城市生活中,养花种草已成为许多人休闲放松的方式之一。然而,由于工作繁忙等原因,人们往往难以定期为植物浇水,导致植物因缺水而枯萎。为了解决这一问题,智能自动浇花灌溉系统应运而生。该系统能够实时监测环境湿度,根据用户设置的湿度阈值自动浇水,有效保障了植物的正常生长。
STM32单片机作为一款高性能、低功耗的微控制器,在智能家居领域有着广泛的应用。结合DHT11温湿度传感器、LCD1602显示屏、继电器、按键及电机等器件,可以构建一个功能全面、操作简便的智能自动浇花灌溉系统。本文将详细介绍该系统的硬件设计、软件编程及功能实现过程。
2. 系统总体设计
2.1 系统功能需求
- 温湿度采集:通过DHT11传感器实时采集当前环境湿度,并显示在LCD1602屏幕上。
- 湿度阈值设置:通过按键设置湿度报警阈值,每按一次按键,蜂鸣器发出一次提醒声,同时设置的阈值显示在LCD1602屏幕上。
- 自动灌溉:当检测到的湿度低于当前设置的湿度阈值时,继电器自动闭合,浇水电机启动工作,实现自动灌溉。
- 报警提醒:在湿度低于阈值且电机启动浇水时,蜂鸣器可持续发出报警声(可选功能,根据实际需求设计)。
2.2 系统架构
本系统主要由STM32单片机控制单元、DHT11温湿度传感器模块、LCD1602显示模块、继电器控制模块、按键输入模块、浇水电机模块及蜂鸣器报警模块组成。系统架构如图2-1所示。
<img src="%E5%9B%BE2-1%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%9B%BE.png" />
3. 硬件设计
3.1 STM32单片机控制单元
STM32单片机作为系统的核心控制器,负责接收传感器数据、处理数据、控制显示屏显示、继电器开关及电机启停。本系统选用STM32F103C8T6型号单片机,其具有高性能、低功耗、丰富的外设资源等优点,满足系统设计需求。
3.2 DHT11温湿度传感器模块
DHT11是一款含有数字信号输出的温湿度复合传感器,具有响应快、抗干扰能力强、性价比高等特点。DHT11传感器通过单总线与STM32单片机通信,传输温湿度数据。在本系统中,主要利用其湿度采集功能。
3.3 LCD1602显示模块
LCD1602是一款16×2字符型液晶显示模块,能够显示两行字符,每行16个字符。通过并行接口与STM32单片机连接,用于显示当前湿度、设置的湿度阈值等信息。
3.4 继电器控制模块
继电器模块用于控制浇水电机的启停。当STM32单片机输出高电平时,继电器闭合,电机启动浇水;当输出低电平时,继电器断开,电机停止工作。
3.5 按键输入模块
按键输入模块用于设置湿度报警阈值。本系统采用4个独立按键,分别用于增加阈值、减少阈值、确认设置及返回主界面。按键通过GPIO口与STM32单片机连接。
3.6 浇水电机模块
浇水电机模块用于实现自动灌溉功能。当继电器闭合时,电机启动工作,通过水管向植物浇水。
3.7 蜂鸣器报警模块
蜂鸣器模块用于设置阈值时的提醒及报警功能。在按键设置阈值时,每按一次按键,蜂鸣器发出一次提醒声;当湿度低于阈值且电机启动浇水时(可选功能),蜂鸣器可持续发出报警声。
4. 软件设计
4.1 主程序设计
主程序流程如图4-1所示。系统上电后,首先进行初始化操作,包括STM32单片机、DHT11传感器、LCD1602显示屏、按键及继电器等外设的初始化。然后,进入主循环,不断采集当前湿度数据,并显示在LCD1602屏幕上。同时,检测按键输入,设置湿度阈值。当检测到湿度低于阈值时,控制继电器闭合,启动浇水电机进行灌溉。
<img src="%E5%9B%BE4-1%E4%B8%BB%E7%A8%8B%E5%BA%8F%E6%B5%81%E7%A8%8B%E5%9B%BE.png" />
4.2 DHT11传感器数据采集
DHT11传感器数据采集流程与4.2节相同,此处不再赘述。
4.3 LCD1602显示模块控制
LCD1602显示模块控制流程与4.4节类似,但显示内容有所不同。在本系统中,LCD1602主要用于显示当前湿度、设置的湿度阈值及系统状态等信息。
4.4 按键输入模块控制
按键输入模块控制流程如图4-2所示。系统不断检测按键状态,当检测到按键按下时,执行相应的操作。增加阈值按键用于逐步增加湿度阈值;减少阈值按键用于逐步减少湿度阈值;确认设置按键用于保存当前设置的阈值并返回主界面;返回主界面按键用于退出设置界面,返回系统主界面。
<img src="%E5%9B%BE4-2%E6%8C%89%E9%94%AE%E8%BE%93%E5%85%A5%E6%A8%A1%E5%9D%97%E6%8E%A7%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE.png" />
4.5 继电器控制模块及浇水电机控制
继电器控制模块及浇水电机控制流程如图4-3所示。当系统检测到当前湿度低于设置的阈值时,控制继电器闭合,启动浇水电机进行灌溉。当湿度达到或超过阈值时,控制继电器断开,停止浇水电机工作。
<img src="%E5%9B%BE4-3%E7%BB%A7%E7%94%B5%E5%99%A8%E6%8E%A7%E5%88%B6%E6%A8%A1%E5%9D%97%E5%8F%8A%E6%B5%87%E6%B0%B4%E7%94%B5%E6%9C%BA%E6%8E%A7%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE.png" />
4.6 蜂鸣器报警模块控制
蜂鸣器报警模块控制流程如图4-4所示。在按键设置湿度阈值时,每按一次按键,蜂鸣器发出一次提醒声。当湿度低于阈值且电机启动浇水时(可选功能),蜂鸣器可持续发出报警声,提醒用户植物正在接受灌溉。
<img src="%E5%9B%BE4-4%E8%9C%82%E9%B8%A3%E5%99%A8%E6%8A%A5%E8%AD%A6%E6%A8%A1%E5%9D%97%E6%8E%A7%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE.png" />
5. 系统测试与优化
5.1 系统测试
在完成硬件连接和软件编程后,进行系统测试。测试内容包括:DHT11传感器数据采集准确性、LCD1602显示屏显示正确性、按键设置阈值功能、继电器控制电机启停功能及蜂鸣器报警功能等。通过实际测试,验证了系统设计的正确性和稳定性。
5.2 系统优化
针对测试过程中发现的问题,进行系统优化。例如,优化DHT11传感器数据采集算法,提高数据采集准确性;优化LCD1602显示屏显示内容,使其更加直观易懂;增加按键去抖处理,避免误操作;优化继电器控制逻辑,减少电机启停时的冲击等。
6. 结论与展望
本文设计了一种基于STM32单片机的智能自动浇花灌溉系统,通过DHT11传感器采集当前环境湿度,LCD1602显示屏显示湿度信息及用户设置的湿度阈值,继电器控制浇水电机的启停,实现自动灌溉功能。同时,系统还具备按键设置湿度阈值及蜂鸣器提醒功能,提高了用户体验。通过实际测试和优化,验证了系统设计的正确性和稳定性。
未来,可以进一步优化系统性能,如增加网络通信功能,实现远程监控和控制;或采用更先进的传感器和算法,提高环境湿度监测的准确性和精度;还可以增加土壤湿度监测功能,实现更加精准的灌溉控制。此外,还可以考虑将系统与智能家居系统相结合,实现更加智能化的家庭植物养护。
7. 参考文献
程序部分展示,有中文注释,新手容易看懂uint8_t lcd_dat1[20];//液晶第一行uint8_t lcd_dat2[20];//液晶第二行uint16_t temp_dat;//温度变量uint16_t hum_dat;//湿度变量uint16_t set_hum_dat=50;//设置湿度变量uint8_t setnum;//设置变量
/**********函数申明****************************************/
void KEY_IO_Init(void);//按键初始化void EXTIx_Init(void);//外部中断void Relay_IO_Init(void); //控制继电器引脚io初始化void EXTI0_IRQHandler(void);void EXTI1_IRQHandler(void);void EXTI2_IRQHandler(void);/***************************************** main函数*****************************************/int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断向量分组 2 //按键和继电器引脚初始化 KEY_IO_Init(); Relay_IO_Init(); EXTIx_Init();//外部中断初始化 LCD_init(); //LCD1602初始化 LCD_clr();//LCD清屏幕 DHT11_Init();//温湿度传感器初始化 while(1) { //传感器数据采集 if(DHT11_ReadData())//温湿度采集 { temp_dat=DHT11_GetTem(); temp_dat=temp_dat/256; delay_ms(10); hum_dat=DHT11_GetHum(); hum_dat=hum_dat/256; }
//液晶显示:T温度 H湿度, sprintf(lcd_dat1,"T:%d C H:%d \n",temp_dat,hum_dat);//转换温度,湿度 LCD_prints(0,0,lcd_dat1);//液晶显示第一行 if(setnum==0) { sprintf(lcd_dat2," SET:%d \n",set_hum_dat);///转换设置设置湿度 LCD_prints(0,1,lcd_dat2);//液晶显示第二行 } if(setnum == 1) { sprintf(lcd_dat2," SET:%d *\n",set_hum_dat);///转换设置湿度 LCD_prints(0,1,lcd_dat2);//液晶显示第二行 }
if(hum_dat<set_hum_dat)//比较湿度 控制浇水电机 Relay1=1; else Relay1=0; } }
void KEY_IO_Init(void)//按键初始化{ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; //按键输入端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); } void EXTIx_Init(void)//外部中断{ NVIC_InitTypeDef NVIC_InitStructure; //NVIC寄存器结构体变量 EXTI_InitTypeDef EXTI_InitStructure; //外部中断相关寄存器结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能IO复用功能时钟 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0); // GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1); // GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource2); // //配置外部中断4相关寄存器 EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1|EXTI_Line2; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStructure); //中断通道使能 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能外部中断通道0 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //中断通道使能 NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//使能外部中断通道1 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //中断通道使能 NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能外部中断通道2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void EXTI0_IRQHandler(void)//进入设置{ setnum++; buzzer=1;delay_ms(50);buzzer=0;delay_ms(50); if(setnum > 1)//按下次数超过1次,退出设置 { setnum=0; }
EXTI_ClearITPendingBit(EXTI_Line4);//清除中断挂起标志位}void EXTI1_IRQHandler(void)//设置加{buzzer=1;delay_ms(50);buzzer=0;delay_ms(50); if(setnum == 1) { if(set_hum_dat<100) set_hum_dat++; } EXTI_ClearITPendingBit(EXTI_Line4);//清除中断挂起标志位}