【STM32项目】植物养护设计
✌️✌️大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是基于《基于STM32的智能植物养护系统设计》。
目录
1、系统功能
2.1、硬件清单
2.2、功能介绍
2.3、控制模式
2、演示视频和实物
3、系统设计框图
4、软件设计流程图
5、原理图
6、主程序
7、总结
1、系统功能
2.1、硬件清单
STM32核心控制板 + OLED显示屏 + 光敏传感器 + 蜂鸣器 + 风扇 + 补光灯(LED) + 水泵(继电器控制) + 舵机(遮阳棚) + 温度传感器 + 土壤湿度传感器 + 二氧化碳传感器 + 蓝牙模块 + 4个按键 + 后备电池
2.2、功能介绍
(1)蓝牙模块:用于无线通信,通过手机APP连接(原文中通过“数字意识”APP),实现远程控制风扇、水泵、补光灯等设备,并在OLED显示屏上同步显示控制状态(如开关状态)。
(2)光敏传感器:检测环境光照强度,数据用于自动控制补光灯和遮阳棚(舵机)。
(3)温度传感器:检测环境温度,数据用于自动控制风扇(当温度过高时)。
(4)土壤湿度传感器:检测土壤湿度,数据用于自动控制水泵(当湿度过低时启动灌溉)。
(5)二氧化碳传感器:检测空气中二氧化碳浓度,数据用于触发蜂鸣器报警(当浓度过高时)。
(6)OLED显示屏:实时显示系统信息,包括时间、传感器数据(温度、土壤湿度、光照强度、二氧化碳浓度)及工作模式(手动、蓝牙、自动),并支持菜单导航。
(7)4个按键模块:在不同模式下提供控制功能:
第一个按键为确认键(在手动模式下控制风扇,在自动模式下用于阈值切换);
第二个按键为菜单/模式切换键(用于切换手动、蓝牙、自动模式);
第三个按键功能上下文相关(在手动模式下控制水泵,在自动模式下用于阈值加减操作);
第四个按键为返回键(退出菜单或返回上级界面)。
(8)蜂鸣器:用于声音报警,当二氧化碳浓度超过设定阈值时自动触发。
(9)风扇:在自动模式下,当温度超过阈值时启动以降温;手动或蓝牙模式下可通过按键或APP直接控制。
(10)补光灯(LED):在自动模式下,当光照强度低于设定阈值时开启以补光;手动或蓝牙模式下可通过按键或APP直接控制。
(11)水泵(继电器控制):用于植物灌溉,在自动模式下,当土壤湿度低于设定阈值时自动启动;手动或蓝牙模式下可通过按键或APP直接控制(继电器打开时绿灯亮起)。
(12)舵机(遮阳棚):控制遮阳棚(可安装纸片模拟),在自动模式下,当光照强度超过设定阈值时自动开启以遮阳;手动或蓝牙模式下可通过APP控制。
(13)STM32核心控制板(STM32F103C8T6):作为系统主控制器,处理所有传感器数据、执行控制逻辑(如阈值比较),并协调外设(如显示屏、按键、执行器)。
(14)后备电池:用于为系统时钟供电,确保上电后时间数据保持准确。
2.3、控制模式
系统支持三种工作模式,通过第二个按键(菜单/模式切换键)进行切换:
(1)蓝牙模式(远程控制):上电后可通过蓝牙模块连接手机APP(原文中APP名称为“数字意识”),实现远程控制风扇、水泵、补光灯、遮阳棚(舵机)等设备,并实时查看OLED显示屏上的传感器数据(温度、土壤湿度、光照强度、二氧化碳浓度)。
(2)手动模式:通过按键直接控制外设:
第一个按键控制风扇开关;
第三个按键控制水泵开关(继电器状态在OLED显示);
第三个按键控制补光灯开关;
第四个按键用于返回上级菜单。
(操作时无需长按,原文未提及延迟处理)。
(3)自动模式:系统根据传感器检测值与设定阈值的比较自动执行动作,支持通过按键调整阈值(第一个按键切换阈值类型,第二个按键增加阈值,第三个按键减少阈值):
温度 > 阈值时启动风扇(例如,温度 > 30°C);
二氧化碳浓度 > 阈值时触发蜂鸣器报警(例如,二氧化碳 > 500 ppm,正常空气为350 ppm);
土壤湿度 < 阈值时启动水泵(例如,土壤湿度 < 39%);
光照强度 < 阈值时开启补光灯(例如,光照强度 < 59 lux);
光照强度 > 阈值时开启舵机(遮阳棚)(例如,光照强度 > 59 lux)。
2、演示视频和实物
基于STM32的植物养护系统设计(加入了菜单)
3、系统设计框图
4、软件设计流程图
5、原理图
6、主程序
#include "sys.h" //头文件
/***********************************************************************************************
同学好!我们是5132单片机设计,定制单片机设计,实物和说明书均可定制,欢迎大家咨询。VX:lwfw123456789
其他项目演示视频和说明请大家移步哔哩哔哩、CSDN和公众号等。
淘宝:5132单片机设计
哔哩哔哩:5132单片机设计
CSDN: 5132单片机设计
公众号: 5132单片机设计
抖音 : 5132单片机设计
小红书: 5132单片机设计
咸鱼: 5132单片机设计
************************************************************************************************/
#include "main.h"
int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级delay_init(); //延时函数初始化LED_Init(); //初始化与LED连接的硬件接口Buzzer_Init(); //下面为外设初始化OLED_Init();Key_Init();AD_Init();Serial_Init(); //串口1初始化MyRTC_Init();Servo_Init(); //舵机初始化,并设置舵机初始角度USART2_Config();while (1){TimeRead();if (YiJiMenu) menu();if (t % 10 == 0) //读取传感器信息{sensor.Guang = AD_GetValue(ADC_Channel_4); //光敏传感器 PA4if (sensor.Guang > 4000)sensor.Guang = 4000;sensor.Guang = (u8)(100 - (sensor.Guang / 40));sensor.Tu_Humi = AD_GetValue(ADC_Channel_5); //土壤传感器 PA5if (sensor.Tu_Humi > 4000)sensor.Tu_Humi = 4000;sensor.Tu_Humi = (u8)(100 - (sensor.Tu_Humi / 40));temperature = DS18B20_Get_Temp();CO2GetData(&co2);}t++;KeyNum = Key_GetNum(); //按键扫描if (KeyNum == 1) //确认键{qingping = 0;delay_ms(20);if (KeyNum == 1){YiJiMenu = 0;}}if (KeyNum == 4) //返回键{qingping = 0;delay_ms(20);if (KeyNum == 4){YiJiMenu = 1;}}if (YiJiMenu == 0){switch (state){case 0:{if (qingping == 0){OLED_Clear();qingping = 1;}zhidong();ChuanGan();}break;case 1:{if (qingping == 0){OLED_Clear();qingping = 1;}shoudong();}break;case 2:{if (qingping == 0){OLED_Clear();qingping = 1;}LanYa();}break;}}}
}void menu() //菜单
{if (qingping == 0){OLED_Clear();qingping = 1;}if (KeyNum == 2){delay_ms(20);if (KeyNum == 2){state++;if (state > Mode - 1){state = 0;}}}switch (state){case 0:{OLED_ShowString(2, 1, ">>");OLED_ShowString(2, 15, "<<");OLED_ShowString(3, 1, " ");OLED_ShowString(3, 15, " ");OLED_ShowString(4, 1, " ");OLED_ShowString(4, 15, " ");OLED_ShowChinese(2, 3, 51);OLED_ShowChinese(2, 4, 52);OLED_ShowChinese(2, 5, 8);OLED_ShowChinese(2, 6, 9);OLED_ShowChinese(3, 3, 18);OLED_ShowChinese(3, 4, 52);OLED_ShowChinese(3, 5, 8);OLED_ShowChinese(3, 6, 9);OLED_ShowChinese(4, 3, 69);OLED_ShowChinese(4, 4, 70);OLED_ShowChinese(4, 5, 8);OLED_ShowChinese(4, 6, 9);}break;case 1:{OLED_ShowString(2, 1, " ");OLED_ShowString(2, 15, " ");OLED_ShowString(3, 1, ">>");OLED_ShowString(3, 15, "<<");OLED_ShowString(4, 1, " ");OLED_ShowString(4, 15, " ");OLED_ShowChinese(2, 3, 51);OLED_ShowChinese(2, 4, 52);OLED_ShowChinese(2, 5, 8);OLED_ShowChinese(2, 6, 9);OLED_ShowChinese(3, 3, 18);OLED_ShowChinese(3, 4, 52);OLED_ShowChinese(3, 5, 8);OLED_ShowChinese(3, 6, 9);OLED_ShowChinese(4, 3, 69);OLED_ShowChinese(4, 4, 70);OLED_ShowChinese(4, 5, 8);OLED_ShowChinese(4, 6, 9);}break;case 2:{OLED_ShowString(2, 1, " ");OLED_ShowString(3, 1, " ");OLED_ShowString(2, 15, " ");OLED_ShowString(3, 15, " ");OLED_ShowString(4, 1, ">>");OLED_ShowString(4, 15, "<<");OLED_ShowChinese(2, 3, 51);OLED_ShowChinese(2, 4, 52);OLED_ShowChinese(2, 5, 8);OLED_ShowChinese(2, 6, 9);OLED_ShowChinese(3, 3, 18);OLED_ShowChinese(3, 4, 52);OLED_ShowChinese(3, 5, 8);OLED_ShowChinese(3, 6, 9);OLED_ShowChinese(4, 3, 69);OLED_ShowChinese(4, 4, 70);OLED_ShowChinese(4, 5, 8);OLED_ShowChinese(4, 6, 9);}break;case 3:{OLED_ShowString(2, 1, " ");OLED_ShowString(3, 1, " ");OLED_ShowString(2, 15, " ");OLED_ShowString(3, 15, " ");OLED_ShowString(4, 1, ">>");OLED_ShowString(4, 15, "<<");OLED_ShowChinese(2, 3, 18);OLED_ShowChinese(2, 4, 52);OLED_ShowChinese(2, 5, 8);OLED_ShowChinese(2, 6, 9);OLED_ShowChinese(3, 3, 57);OLED_ShowChinese(3, 4, 58);OLED_ShowChinese(3, 5, 8);OLED_ShowChinese(3, 6, 9);OLED_ShowChinese(4, 3, 61);OLED_ShowChinese(4, 4, 62);OLED_ShowChinese(4, 5, 8);OLED_ShowChinese(4, 6, 9);}break;}
}void shoudong()
{OLED_ShowString(2, 1, "FengShan:");OLED_ShowString(3, 1, "Shui Ben:");OLED_ShowString(4, 1, "LED:");if (KeyNum == 1) //按键{delay_ms(20);if (KeyNum == 1){state2++;if (state2 > 1){state2 = 0;}}}if (state2 == 0){FengShan_ON();OLED_ShowString(2, 10, "ON ");}if (state2 == 1){FengShan_OFF();OLED_ShowString(2, 10, "OFF");}if (KeyNum == 2) //按键{delay_ms(20);if (KeyNum == 2){state2_1++;if (state2_1 > 1){state2_1 = 0;}}}if (state2_1 == 1){ShuiBen_ON();OLED_ShowString(3, 10, "ON ");}if (state2_1 == 0){ShuiBen_OFF();OLED_ShowString(3, 10, "OFF");}if (KeyNum == 3) //按键{delay_ms(20);if (KeyNum == 3){state2_2++;if (state2_2 > 1){state2_2 = 0;}}}if (state2_2 == 1){LED_ON();OLED_ShowString(4, 10, "ON ");}if (state2_2 == 0){LED_OFF();OLED_ShowString(4, 10, "OFF");}}
void zhidong()
{if (sensor.Tu_Humi < sensor.Tu_Humi_Yu){ShuiBen_ON();}else{ShuiBen_OFF();}if (temperature > temperature_Yu){FengShan_ON();}else{FengShan_OFF();}if (sensor.Guang < sensor.Guang_Yu){LED_ON();Servo_SetAngle(0);//外设操作}else{LED_OFF(); Servo_SetAngle(90);//外设操作}if (co2< 500){Buzzer_OFF();}else{Buzzer_ON();}if (KeyNum == 1) //自动模式下PB0按键控制阈值切换{delay_ms(20);if (KeyNum == 1){state3++;if (state3 > 2){state3 = 0;}}}if (state3 == 1){if (KeyNum == 2)temperature_Yu += 10; //光照强度上限加if (KeyNum == 3)temperature_Yu -= 10; //光照强度上限减}if (state3 == 2){if (KeyNum == 2)sensor.Tu_Humi_Yu++;if (KeyNum == 3)sensor.Tu_Humi_Yu--;}if (state3 == 0){if (KeyNum == 2)sensor.Guang_Yu++;if (KeyNum == 3)sensor.Guang_Yu--;}
}void LanYa()
{OLED_ShowString(2, 1, "FengShan:");OLED_ShowString(3, 1, "Shui Ben:");OLED_ShowString(4, 1, "LED:");if (Serial_GetRxFlag() == 1){RxData = Serial_GetRxData(); //蓝牙接收switch (RxData){case 1:state2++;if (state2 > 1){state2 = 0;}break;case 2:state2_1++;if (state2_1 > 1){state2_1 = 0;}break;case 3:state2_2++;if (state2_2 > 1){state2_2 = 0;}break;default:break;}}if (state2 == 0){FengShan_ON();OLED_ShowString(2, 10, "ON ");}if (state2 == 1){FengShan_OFF();OLED_ShowString(2, 10, "OFF");}if (state2_1 == 1){ShuiBen_ON();OLED_ShowString(3, 10, "ON ");}if (state2_1 == 0){ShuiBen_OFF();OLED_ShowString(3, 10, "OFF");}if (state2_2 == 1){LED_ON();OLED_ShowString(4, 10, "ON ");}if (state2_2 == 0){LED_OFF();OLED_ShowString(4, 10, "OFF");}
}void ChuanGan()
{OLED_ShowChinese(3, 1, 63);OLED_ShowChinese(3, 2, 65);OLED_ShowString(3, 5, ":");OLED_ShowNum(3, 6, sensor.Tu_Humi, 2);OLED_ShowString(3, 8, "%");OLED_ShowChinese(2, 1, 26);OLED_ShowChinese(2, 2, 28);OLED_ShowString(2, 5, ":");if (temperature < 0){OLED_ShowString(2, 6, "-"); //显示负号temperature = -temperature; //转为正数}else OLED_ShowString(2, 6, "+"); //去掉负号OLED_ShowNum(2, 7, temperature / 10, 2);OLED_ShowString(2, 9, ".");OLED_ShowNum(2, 10, temperature % 10, 1);OLED_ShowNum(2, 12, co2, 4);OLED_ShowChinese(3, 5, 4);OLED_ShowChinese(3, 6, 6);OLED_ShowString(3, 13, ":");OLED_ShowNum(3, 14, sensor.Guang, 2);OLED_ShowChinese(4, 1, 67);OLED_ShowChinese(4, 2, 68);OLED_ShowString(4, 5, ":");OLED_ShowNum(4, 6, temperature_Yu / 10, 2);OLED_ShowNum(4, 9, sensor.Tu_Humi_Yu, 2);OLED_ShowNum(4, 12, sensor.Guang_Yu, 2);
}void TimeRead()
{MyRTC_ReadTime();OLED_ShowNum(1, 2, MyRTC_Time[1], 2); //时OLED_ShowString(1, 4, "/");OLED_ShowNum(1, 5, MyRTC_Time[2], 2); //分OLED_ShowNum(1, 8, MyRTC_Time[3], 2); //时OLED_ShowString(1, 10, ":");OLED_ShowNum(1, 11, MyRTC_Time[4], 2); //分OLED_ShowString(1, 13, ":");OLED_ShowNum(1, 14, MyRTC_Time[5], 2); //秒
}
7、总结
本文设计了一款基于STM32的智能火灾报警系统,采用STM32F103C8T6作为主控芯片,集成温湿度、烟雾、火焰等传感器,实现环境监测与火灾预警功能。系统具备自动、手动、远程三种控制模式:自动模式下通过传感器数据触发喷水灭火、排风等联动操作;手动模式支持按键直接控制设备;远程模式通过ESP8266连接阿里云平台实现手机APP远程监控。系统还包含OLED显示、声光报警、后备电源等功能模块,通过模块化程序设计实现了火灾检测、报警和联动控制的完整解决方案。该设计具有实用性强、响应快速、操作灵活等特点。