基于STM32的农业大棚温湿度采集控制系统的设计

news2024/11/26 15:24:25

目录

1、设计要求

2、系统功能

3、演示视频和实物

4、系统设计框图

5、软件设计流程图

6、原理图

7、主程序

8、总结


 🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是智能教室。

设备的详细功能见网盘中的文章《8、基于STM32的大棚温湿度》:

链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132

提取码:5132

 农业大棚是设施农业的重要组成部分,大棚测控系统是实现大棚自动化、科学化的基本保证。通过对监测数据的分析,结合作物生长规律,控制环境条件,使作物达到优质、高产、高效的栽培目的。计算机应用技术的发展,也使得用计算机控制的方面也涉及到各个领域,其中在大棚内用单片机控制温度、湿度是应用于实践的主要方面之一。

1、设计要求

本设计选用STM32F103C8T6芯片为核心,通过DHT11检测模块、光敏传感器、土壤湿度传感器输出模块、按键模块和显示模块等,完成一种大棚温湿度监控系统的设计。通过编写相应的程序实现按键控制温湿度的设定,DHT11温湿度传感器检测温湿度的变化并在OLED模块显示测量温湿度数据和设置参数值,最后通过STM32单片机控制风扇和发热片输出实现温湿度的调节。

3、演示视频和实物

D27-基于STM32的大棚温湿度监控系统设计

4、系统设计框图

5、软件设计流程图

大棚温湿度监测系统设计的主程序主要是对相关硬件环境初始化,只有在系统硬件环境初始化成功后,系统才能够正常的工作。初始化过程涵盖了多个方面主要包括外部中断初始化、采集模块初始化、输入模块初始化、输出模块初始化和显示模块初始化,程序完成初始化后,单片机采集到原始ADC数据后,将原始ADC数据经过比例运算得到当前的真实值;然后将当前真实值显示在OLED屏幕上;显示完成后单片机会将当前真实值与设置的阈值进行比较,如果超出了当前设置的阈值,单片机将控制执行对应的输出设备。

6、原理图

 

7、主程序

 下面这个主程序,主要是设计的逻辑控制。

#include "stm32f10x.h" // 有问题和需求的,可以联系VX:lwfw123456789
#include <stdio.h>
#include <string.h>
#include "sys.h"
#include "delay.h"
#include "OLED.h"
#include "Key.h"
#include "OLED.h"
#include "Serial.h"
#include "led.h"
#include "Buzzer.h"
#include "MyRTC.h"
#include "dht11.h"
#include "AD.h"

uint8_t KeyNum;        //存储按键值
uint8_t RxData;        //蓝牙接收到的数据
u8 temp, humi;
uint32_t bufe[5];
uint16_t AD0, AD1, AD2, AD3;       //存储ADC的值
u8 state1 = 1;          //设备开关
u8 state2 = 0;         //模式选择
u8 state3 = 0;         //阈值切换
u8 state4 = 0;         //阈值切换
u8 state5 = 0;         //阈值切换

u8 t = 0;              //温湿度读取值的间隔
short temperature;     //存储DS18B20的温度值
u8 flag1;              //清屏用到的标志,为了使OLED_Clear();执行一次
u8 flag2;              //menu1()中为了使显示的提示信息执行一次
u8 flag3;  
u8 flag4;  
u8 flag5;  
u8 flag6;  
u8 wenyu = 23, shiyu = 65, guangyu = 50, tuyu = 50;


void ctrlue()
{
	if(state1==0&&state3 == 0 )	
	{
	  if(bufe[1]>shiyu)  //湿度大于设定阈值开风扇
		 {		      
			 LED4=0;
		 }else
		 {
			 LED4=1;
		 }
		 if(bufe[0]<wenyu )   //温度小于阈值开加热,关闭粉丝
		 {
			  LED3=1; 
		   LED4=0;
		 }else
		 {
			  LED3=0; 
		 	  LED4=1;
		 }    
	}    
}

void shoudong()
{
if(state1==0&&state3 == 1 )	
{
 if (KeyNum == 4)          //一键控制多媒体   PB10
    {
        delay_ms(20);
        if (KeyNum == 4)
        {
            state4++;
            if (state4 > 1)
            {
                state4 = 0;
            }
        }
    }
		
    if (state4 == 0)
    {
        LED3 = 1;           //开启指示灯      
    }
    if (state4 == 1)
    {
        LED3 = 0;            //关闭设备指示灯      
    }
		

		if (KeyNum == 5)          //一键控制多媒体   PB10
    {
        delay_ms(20);
        if (KeyNum == 5)
        {
            state5++;
            if (state5 > 1)
            {
                state5 = 0;
            }
        }
    }
    if (state5 == 0)
    {
        LED4 = 1;           //开启指示灯      
    }
    if (state5 == 1)
    {
        LED4 = 0;            //关闭设备指示灯
    }
}
	
}

void menu0()       //显示题目
{
	 if (flag3 == 0) 
            {
                OLED_ShowString(1, 1, "XX/XX");        //第一行显示时间
                OLED_ShowString(1, 12, "XX:XX");
                flag3 = 1;
            }
   
    //    OLED_ShowNum(1, 6, MyRTC_Time[0], 4);    //年
    OLED_ShowNum(1, 1, MyRTC_Time[1], 2);   //月
    OLED_ShowNum(1, 4, MyRTC_Time[2], 2);   //日
    OLED_ShowNum(1, 12, MyRTC_Time[3], 2);    //时
    OLED_ShowNum(1, 15, MyRTC_Time[4], 2);    //分
//      OLED_ShowNum(2, 12, MyRTC_Time[5], 2);   //秒
    OLED_ShowChinese(3, 3, 73);    //显示题目
    OLED_ShowChinese(3, 4, 74);
    OLED_ShowChinese(3, 5, 75);
    OLED_ShowChinese(3, 6, 76);

    OLED_ShowChinese(4, 1, 77);    //显示题目
    OLED_ShowChinese(4, 2, 78);
    OLED_ShowChinese(4, 3, 79);
    OLED_ShowChinese(4, 4, 80);
    OLED_ShowChinese(4, 5, 81);
    OLED_ShowChinese(4, 6, 84);
    OLED_ShowChinese(4, 7, 85);

}

void menu1()          //核心页面,用来显示传感器参数和逻辑判断
{
	if (flag4 == 0) 
            {
                OLED_ShowString(1, 1, "XX/XX");        //第一行显示时间
                OLED_ShowString(1, 12, "XX:XX");
                flag4 = 1;
            }
//    OLED_ShowNum(1, 6, MyRTC_Time[0], 4);    //年
    OLED_ShowNum(1, 1, MyRTC_Time[1], 2);   //月
    OLED_ShowNum(1, 4, MyRTC_Time[2], 2);   //日
    OLED_ShowNum(1, 12, MyRTC_Time[3], 2);    //时
    OLED_ShowNum(1, 15, MyRTC_Time[4], 2);    //分
//      OLED_ShowNum(2, 12, MyRTC_Time[5], 2);   //秒
    if (flag2 == 0)      //里面的代码执行一次
    {
        flag2 = 1;

        OLED_ShowChinese(2, 1, 2); //温湿度
        OLED_ShowChinese(2, 2, 4);
        OLED_ShowString(2, 5, ":");
        OLED_ShowChinese(2, 5, 3);
        OLED_ShowChinese(2, 6, 4);
        OLED_ShowString(2, 13, ":");

        OLED_ShowChinese(3, 1, 51); //土壤湿度
        OLED_ShowChinese(3, 2, 52);
        OLED_ShowChinese(3, 3, 37);
        OLED_ShowChinese(3, 4, 38);
        OLED_ShowString(3, 9, ":");


        OLED_ShowChinese(4, 1, 16); //光照强度
        OLED_ShowChinese(4, 2, 17);
        OLED_ShowChinese(4, 3, 37);
        OLED_ShowChinese(4, 4, 38);
        OLED_ShowString(4, 9, ":");
    }

//******************************传感器数据采集****************************************************//
    if (t % 10 == 0)
    {
        DHT11_Read_Data(&temp, &humi);  //读取温湿度并显示在OLED上
        bufe[0] = temp;
        bufe[1] = humi;
        OLED_ShowNum(2, 6, bufe[0], 2);
        OLED_ShowString(2, 8, "%");
        OLED_ShowNum(2, 14, bufe[1], 2);
        OLED_ShowString(2, 16, "%");
    }
    t++;

    AD0 = AD_GetValue(ADC_Channel_0);    //土壤湿度传感器
    if (AD0 > 4000)AD0 = 4000;
    bufe[2] = (u8)(AD0 / 40);
    OLED_ShowNum(3, 10, bufe[2], 2);
    OLED_ShowString(3, 12, "%");

    AD1 = AD_GetValue(ADC_Channel_1);    //光照强度传感器
    if (AD1 > 4000)AD1 = 4000;
    bufe[3] = (u8)(100-AD1 / 40);
    OLED_ShowNum(4, 10, bufe[3], 2);
    OLED_ShowString(4, 12, "%");



//******************************设备开关****************************************************//
    if (KeyNum == 1)          //一键控制多媒体   PB10
    {
			 state4=0;state5=0;
        delay_ms(20);
        if (KeyNum == 1)
        {
            state1++;
            if (state1 > 1)
            {
                state1 = 0;
            }
        }
    }
    if (state1 == 0)
    {
        LED2 = 0;           //开启指示灯 
      
    }
    if (state1 == 1)
    {
        LED2 = 1;            //关闭设备指示灯	
		  
        Buzzer_OFF();		
        LED3 = 1;
			  LED4 = 1;					
    }
//**************************************模式切换*****************************************************//
    if (KeyNum == 3 & state1 == 0) //一键控制自动或者手动   PB11
    {
			 flag6 = 0; flag5 = 0;state4=0;state5=0;
        delay_ms(20);
        if (KeyNum == 3)
        {
            state3++;
            if (state3 > 1)
            {
                state3 = 0;
            }
        }
    }
    if (state3 == 0 )
    {
        ctrlue();   // 开
        OLED_ShowChinese(4, 8, 30);
			 if (flag5 == 0) 
            {
                LED3 = 1;
			  LED4 = 1;
                flag5 = 1;
            }

    }
    if (state3 == 1 )
    {
        shoudong();   // 开
        OLED_ShowChinese(4, 8, 29);
			 if (flag6 == 0) //目的就是使OLED_Clear();执行一次
            {
               LED3 = 1;
			  LED4 = 1;
                flag6 = 1;
            }
    }
}

	
	
void menu2()       //阈值控制
{
    OLED_ShowChinese(1, 3, 86);
    OLED_ShowChinese(1, 4, 87);
    OLED_ShowChinese(1, 5, 88);
    OLED_ShowChinese(1, 6, 89);

    OLED_ShowChinese(2, 1, 2); //温湿度
    OLED_ShowChinese(2, 2, 4);
    OLED_ShowString(2, 5, ":");
    OLED_ShowChinese(2, 5, 3);
    OLED_ShowChinese(2, 6, 4);
    OLED_ShowString(2, 13, ":");


    OLED_ShowChinese(3, 1, 51); //土壤湿度
    OLED_ShowChinese(3, 2, 52);
    OLED_ShowChinese(3, 3, 37);
    OLED_ShowChinese(3, 4, 38);
    OLED_ShowString(3, 9, ":");


    OLED_ShowChinese(4, 1, 16); //光照强度
    OLED_ShowChinese(4, 2, 17);
    OLED_ShowChinese(4, 3, 37);
    OLED_ShowChinese(4, 4, 38);
    OLED_ShowString(4, 9, ":");

    if (KeyNum == 3)          //
    {
        delay_ms(20);
        if (KeyNum == 3)
        {
            state3++;
            if (state3 > 4)
            {
                state3 = 0;
            }
        }
    }
    if (state3 == 0)
    {
        if (KeyNum == 4)   wenyu++;
        if (KeyNum == 5)  wenyu--;
    }
    OLED_ShowNum(2, 6, wenyu, 2);
    if (state3 == 1)
    {
        if (KeyNum == 4)   shiyu++;
        if (KeyNum == 5)  shiyu--;
    }
    OLED_ShowNum(2, 14, shiyu, 2);
    if (state3 == 2)
    {
        if (KeyNum == 4)   tuyu++;
        if (KeyNum == 5)  tuyu--;
    }
    OLED_ShowNum(3, 10, tuyu, 2);
    if (state3 == 3)
    {
        if (KeyNum == 4)   guangyu++;
        if (KeyNum == 5)  guangyu--;
    }
    OLED_ShowNum(4, 10, guangyu, 2);
}
int main(void)     //主函数
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   // 设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    delay_init();      //延时函数初始化
    SystemInit();

    Key_Init();      //按键初始化
    LED_Init();
    OLED_Init();
    Buzzer_Init();
    Serial_Init();   //串口1初始化
    MyRTC_Init();
    DHT11_Init();
    AD_Init();



    while (1)
    {
        MyRTC_ReadTime();    //读取时间(每一个页面都有时间显示)


        KeyNum = Key_GetNum();               //按键检查

//*********************页面切换*****************************************************

        if (KeyNum == 2)    //页面切换PB1
        {
            flag1 = 0;
					   flag3 = 0;
					 flag4 = 0;
            delay_ms(20);
            if (KeyNum == 2)
            {
                state2++;

                if (state2 > 2)    //3个页面
                {
                    state2 = 0;
                }
            }
        }
        if (state2 == 0)           //初始页面   显示题目“智能大棚温湿度采集“
        {
            if (flag1 == 0) //目的就是使OLED_Clear();执行一次
            {
                OLED_Clear();
                flag1 = 1;
            }
            menu0();
        }
        else if (state2 == 1)      //第一页面
        {
            if (flag1 == 0)
            {
                OLED_Clear();
                flag1 = 1;
            }
            menu1();
        }
        else if (state2 == 2)        //等二页面    阈值控制
        {
            flag2 = 0;
            if (flag1 == 0)
            {
                OLED_Clear();
                flag1 = 1;
                flag2 = 1;
            }
            menu2();
        }
    }
}

8、总结

基于STM32的温湿度监控系统是将STM32单片机作为主控制器的,外接OLED显示模块、DHT11数字温湿度传感器、按键电路和输出模块,共同构成了大棚温湿度监控系统的硬件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1941295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

451.根据字符出现频率排序(中等)

451.根据字符出现频率排序&#xff08;中等&#xff09; 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;451.根据字符出现频率排序&#xff08;中等&#xff09; 2.详细题解 题目&#xff1a; 347. 前 K 个高频元素&#xff08;中等&am…

2月科研——arcgis计算植被差异

ArcGIS中&#xff0c;设置高于或低于某个值的像元为 -9999&#xff0c;然后将这些地方设为空——目的&#xff1a;去除异常值和黑色背景值 Con(("T_std ano7.tif" > 2) | ("T_std ano7.tif" < - 2), - 9999,"T_std ano7.tif") SetNull(&…

数学基础【俗说矩阵】:初等矩阵和矩阵的初等行变化关系推导

初等矩阵和矩阵的初等行变换 初等矩阵 矩阵的初等行变换 对单位阵E进行一次初等行变化得到的阵叫做初等阵。 这里只能进行一次初等行变换。 置换阵 给矩阵【左乘】一个【置换阵】&#xff0c;相当与对该矩阵进行了一次【置换阵】对应的【置换】初等行变换&#xff1b; 数…

爬取百度图片,想爬谁就爬谁

前言 既然是做爬虫&#xff0c;那么肯定就会有一些小心思&#xff0c;比如去获取一些自己喜欢的资料等。 去百度图片去抓取图片吧 打开百度图片网站&#xff0c;点击搜索xxx&#xff0c;打开后&#xff0c;滚动滚动条&#xff0c;发现滚动条越来越小&#xff0c;说明图片加载…

Wordpress文章分享到微信朋友圈不带图像问题的解决

目录 一、插件选择 二、插件安装 三、获取微信公众号管理信息 1、登录微信公众平台 2、配置“JS接口安全域名” 3、至安全中心设置“IP白名单” 4、获得“开发者ID(AppID)” 5、获得“开发者密码(AppSecret)” 四、配置插件 五、验证 WordPress装配好后&#xff0c;可…

10.11和10.8那个大(各种ai的回答)

问题&#xff1a;10.11和10.8两个数哪个大 腾讯混元 ✔️ chatGPT ❎ 通义千问 ❎ 文心一言 ✔️ 智谱清言 ❎ 讯飞星火 ✔️ C知道 ❎ 豆包 ✔️

matlab 声音信号希尔伯特黄变换

1、内容简介 略 91-可以交流、咨询、答疑 2、内容说明 略 Hilbert-Huang变换&#xff08;HHT&#xff09;是一种基于经验的数据分析方法 方法。它的扩展基础是自适应的&#xff0c;因此它可以从非线性和非平稳过程中产生具有物理意义的数据表示。这个 适应性的优势是有代价…

代码随想录第二天 | 数组 | 双指针法、滑动窗口、螺旋数组

来源 代码随想录数组第二天 有序数组的平方 数组其实是有序的&#xff0c; 只不过负数平方之后可能成为最大数了。 那么数组平方的最大值就在数组的两端&#xff0c;不是最左边就是最右边&#xff0c;不可能是中间。 此时可以考虑双指针法了&#xff0c;i指向起始位置&…

matlab永磁同步电机反馈试验装置的设计和永磁同步电机仿真

1、内容简介 略 85-可以交流、咨询、答疑 2、内容说明 略 摘要&#xff1a;得益于电力电子器件及控制技术的高速发展&#xff0c;使得电机的应用越来越方便及精确&#xff0c;适应了实际应用对电机性能及质量提出的更高要求和标准。同时电机测试技术也因为电力电子技术的发…

c++ primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作

c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作 c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作 文章目录 c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作16.3.3 对矢量可执行的其他操作…

Idea中git如何进行回退操作

当你的代码已经提交并且推送到远程仓库了如何进行回退 1.首先找到你需要回退到的提交记录 假设你要回退到当前大营销模板位置&#xff0c;右键当前分支然后选中rest 点击后&#xff0c;若需要保留之前提交记录到本地则可以选择max或者soft 选择后进行回退操作&#xff0c;最后将…

全代码 | 随机森林在回归分析中的经典应用

公众号后台记录了发表过文章的各项阅读指标包括&#xff1a;内容标题&#xff0c;总阅读人数&#xff0c;总阅读次数&#xff0c;总分享人数&#xff0c;总分享次数&#xff0c;阅读后关注人数&#xff0c;送达阅读率&#xff0c;分享产生阅读次数&#xff0c;首次分享率&#…

《低代码指南》——Oracle APEX : AI在低代码开发中的创新应用

在低代码开发领域,我们正在目睹人工智能(AI)集成所带来的显著进展。Oracle公司最新推出的APEX 24.1版本,便是这一趋势的明显体现,其集成的AI功能旨在极大提高开发者的生产力,同时简化应用程序的创建过程。 Contents 将变革性的AI整合到低代码平台 将AI技术引入低代码平台…

UniMERNet - 数学公式识别转LaTeX

文章目录 一、关于 UniMERNet演示视频 二、快速入门1、克隆repo并下载模型2、安装3、运行UniMERNet 四、评估1、下载UniMER-Test数据集2、运行评估代码3、与SOTA方法的性能比较&#xff08;BLEU&#xff09;4、不同方法的可视化结果 五、UniMER数据集1、导言2、数据集下载 六、…

【Linux 13】文件系统

文章目录 &#x1f308; 一、前言&#x1f308; 二、文件操作的系统接口⭐ 1. 打开文件 open⭐ 2. 关闭文件 close⭐ 3. 写入文件 write⭐ 4. 读取文件 read &#x1f308; 三、文件描述符⭐ 1. 文件描述符介绍⭐ 2. 提前被分配的文件描述符 0 1 2⭐ 3. 文件描述符的分配规则 &…

【Qt】Qt的坐标转换(mapToGlobal)

1、QPoint QWidget::mapToGlobal(const QPoint &pos) const 将小部件坐标转换为全局坐标。mapToGlobal(QPoint(0,0))可以得到小部件左上角像素的全局坐标。2、QPoint QWidget::mapToParent(const QPoint &pos) const 将小部件坐标转换为父部件坐标。如果小部件没有父部…

Linux内存的概念及管理

1、内存概念 内存是指计算机中所安装的随机存取内存的容量&#xff0c;储存是指计算机内硬盘的容量。硬盘应当是计算机的“外存”。内存应当是在主板上的一些存储器&#xff0c;用来保存CPU运算使用过程中的中间数据和计算结果&#xff0c;当不用这些数据时&#xff0c;它们被保…

鸿蒙仓颉语言【Redis仓颉语言客户端】

特性 支持RESP2和RESP3协议接口设计兼容jedis接口语义丰富的管理命令支持支持单连接多线程模式支持发布订阅模式支持哨兵模式和集群模式完备的单元测试覆盖架构简洁&#xff0c;易于扩展 开发计划 2024.3.22 完成支持单机模式的RESP2和RESP3协议的客户端&#xff0c;提供Bet…

实际生活中网段不通的典型分析及处理方案

关于端口&#xff1a; 应用层&#xff1a; FTP TELNET SMTP DNS TFTP SNMP 端口号&#xff1a; 21 23 25 53 69 161 传输层&#xff1a; TCP UDP&#xff08;DNS两个都占…

7月21日,贪心练习

大家好呀&#xff0c;今天带来一些贪心算法的应用解题、 一&#xff0c;柠檬水找零 . - 力扣&#xff08;LeetCode&#xff09; 解析&#xff1a; 本题的贪心体现在对于20美元的处理上&#xff0c;我们总是优先把功能较少的10元作为找零&#xff0c;这样可以让5元用处更大 …