基于STM32的蔬菜大棚温湿度智能控制系统设计

2024-03-16 03:59

本文主要是介绍基于STM32的蔬菜大棚温湿度智能控制系统设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

随着人们对健康和可持续生活方式的关注不断增加,蔬菜大棚成为了现代农业中的重要组成部分。蔬菜大棚提供了一个受控的环境,使得农民能够在任何季节种植蔬菜,并根据需要进行调节。为了实现最佳的蔬菜生长和产量,对温度和湿度等环境条件的精确控制至关重要。

传统的蔬菜大棚管理通常依赖于人工监测和调节。这种方法存在一些问题,例如人工监测容易出现误差和延迟,而且对于大规模的蔬菜大棚来说,人工调节工作量巨大。所以开发一种基于智能控制系统的蔬菜大棚温湿度管理方案变得非常重要。

基于STM32微控制器的蔬菜大棚温湿度智能控制系统用于解决传统管理方法的问题,并提供一种自动化的解决方案。该系统利用STM32微控制器的强大计算和控制能力,结合温湿度传感器和执行器,实现对蔬菜大棚环境的精确监测和控制。

通过该系统,农民可以实时监测蔬菜大棚内的温度和湿度,并根据预设的目标范围自动调节。系统可以自动控制温室内的加热器、通风设备和加湿器等设备,以维持最适宜的生长环境条件。项目的目标是提高蔬菜大棚的生产效率和质量,降低能源消耗,并减少人力投入。通过智能控制系统的应用,农民能够实现更加可持续和高效的农业生产,为社会提供更多健康的蔬菜产品。

image-20230802152046578

二、系统设计流程

2.1 硬件选型

硬件选型是设计蔬菜大棚温湿度智能控制系统的重要环节。

【1】主控芯片:STM32F103ZET6 主控芯片使用STM32F103ZET6,它是一款高性能的ARM Cortex-M3内核微控制器,具有丰富的外设资源和强大的处理能力。该芯片可满足本项目对控制和数据处理的要求。

【2】温湿度传感器:DHT11 空气温湿度采集选用DHT11传感器,它采用数字信号输出,具有简单、低成本和较好的精度,适合大棚环境的温湿度监测。

【3】土壤湿度传感器:土壤湿度传感器 土壤湿度采集选用土壤湿度传感器,通过模拟-数字转换器(ADC)接口采集土壤湿度数据。该传感器能够准确测量土壤湿度,为农作物提供合适的灌溉水量。

【4】通风风机:5V小风扇+继电器 为了实现通风控制,选择5V小风扇作为通风装置,并通过继电器控制其开关状态。根据温度数据和设定阈值,通过STM32的GPIO口控制继电器的高低电平实现通风风扇的启停控制。

【5】照明灯:LED白色灯模块 为了提供适当的照明条件,选择LED白色灯模块作为照明装置。该模块使用STM32的GPIO口控制其开关状态,实现灯光的开启和关闭。

【6】灌溉系统:抽水电机+继电器 灌溉系统采用抽水电机作为水源,并通过继电器控制其开启和关闭。通过单片机控制继电器的高低电平来控制抽水电机的工作状态,实现灌溉系统的自动化操作。

【7】显示模块:LCD显示屏 为了方便用户观察当前的温湿度等数据,选用LCD显示屏进行数据的显示。通过STM32的数字接口与LCD显示屏进行通信,将采集到的数据实时显示在屏幕上。

2.2 软件设计思路

本项目的代码设计思路可以分为以下几个关键部分:

【1】初始化设置:首先,需要进行主控芯片的初始化设置,包括引脚配置、时钟设置等。同时,还需要对LCD显示屏进行初始化配置,以便后续显示数据。

【2】传感器数据采集:使用合适的库函数或代码,读取DHT11传感器和土壤湿度传感器的数据。通过适当的接口与主控芯片进行通信,获取温度、湿度和土壤湿度的数值。

【3】数据处理与判断:根据采集到的温湿度和土壤湿度数值,进行相应的数据处理和判断。判断当前温度是否超出设定范围,以及土壤湿度是否低于设定阈值等。

【4】控制执行器:根据数据处理和判断的结果,控制相应的执行器,如通风风扇、照明灯和灌溉系统。通过设置相应的引脚电平或触发继电器,实现执行器的开启或关闭。

【5】LCD显示:将采集到的温湿度和土壤湿度数值通过LCD显示屏进行显示,以便用户实时监测。

【6】用户交互:通过按键输入或其他方式,实现用户与系统的交互。设置土壤湿度阈值、调节温度范围等。

【7】循环运行:将上述步骤组织成一个循环运行的程序,确保系统能够持续采集数据、处理判断和控制执行器的操作。

三、代码实现

3.1 DHT11温湿度读取

读取DHT11传感器环境温湿度并通过串口打印出来。

#include "stm32f10x.h"
#include "stdio.h"// 定义DHT11数据引脚
#define DHT11_PIN   GPIO_Pin_0
#define DHT11_PORT  GPIOA// DHT11初始化函数
void DHT11_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置DHT11引脚为推挽输出GPIO_InitStructure.GPIO_Pin = DHT11_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}// 延时函数,单位为微秒
void Delay_us(uint32_t nCount)
{uint32_t i;for(i=0; i<nCount; i++);
}// 软件延时函数,单位为毫秒
void Delay_ms(uint32_t nCount)
{uint32_t i;for(i=0; i<nCount*1000; i++);
}// 从DHT11读取一位数据
uint8_t DHT11_ReadBit(void)
{uint8_t retries = 0;while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_RESET){if (retries++ > 100) return 0;Delay_us(1);}Delay_us(40);   // 延时40usif (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_SET)retries = 100;  // 超时标识elseretries = 0;while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_SET){if (retries++ > 100) return 0;Delay_us(1);}return 1;
}// 从DHT11读取一个字节数据
uint8_t DHT11_ReadByte(void)
{uint8_t i, temp = 0;for(i=0; i<8; i++){temp <<= 1;temp |= DHT11_ReadBit();}return temp;
}// 读取DHT11的温湿度值
uint8_t DHT11_ReadData(uint8_t* temperature, uint8_t* humidity)
{uint8_t data[5], checksum;// 主机将总线拉低至少18msGPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DHT11_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DHT11_PORT, &GPIO_InitStructure);GPIO_ResetBits(DHT11_PORT, DHT11_PIN);Delay_ms(20);GPIO_SetBits(DHT11_PORT, DHT11_PIN);Delay_us(30);// 设置为输入模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(DHT11_PORT, &GPIO_InitStructure);// 等待 DHT11 响应if (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_RESET){while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_RESET);while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_SET);// 读取5字节数据for(uint8_t i=0; i<5; i++)data[i] = DHT11_ReadByte();// 读取校验和checksum = DHT11_ReadByte();// 校验数据if((data[0] + data[1] + data[2] + data[3]) != checksum)return 0;*humidity = data[0];*temperature = data[2];return 1;}else{return 0;}
}// 初始化USART1
void USART1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 使能USART1和GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置USART1的引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  // TXGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  // RXGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置USART1USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);// 使能USART1USART_Cmd(USART1, ENABLE);
}// 发送字符到USART1
void USART1_SendChar(char ch)
{while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);USART_SendData(USART1, (uint8_t)ch);
}// 发送字符串到USART1
void USART1_SendString(const char* str)
{while(*str){USART1_SendChar(*str++);}
}int main(void)
{uint8_t temperature, humidity;// 初始化DHT11和USART1DHT11_Init();USART1_Init();while(1){if (DHT11_ReadData(&temperature, &humidity)){// 发送温湿度数据到串口char buffer[50];sprintf(buffer, "Temperature: %d°C, Humidity: %d%%\r\n", temperature, humidity);USART1_SendString(buffer);}Delay_ms(2000);  // 2秒钟读取一次数据}
}

将代码下载到STM32F103ZET6开发板上,接上DHT11。当成功运行时,环境温湿度数据会通过USART1串口打印出来。

3.2 读取土壤湿度值

通过ADC1的通道1采集土壤传感器的湿度值,打印到串口.

#include "stm32f10x.h"
#include "stdio.h"// 函数声明
void ADC_Configuration(void);
void UART_Configuration(void);
void USART1_SendChar(char ch);int main(void)
{// 初始化ADC和串口ADC_Configuration();UART_Configuration();while (1){// 启动ADC转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待转换完成while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));// 读取ADC值uint16_t adcValue = ADC_GetConversionValue(ADC1);// 将ADC值转换为湿度百分比float humidity = (float)adcValue / 4095 * 100;// 将湿度值打印到串口char buffer[20];sprintf(buffer, "Humidity: %.2f%%\r\n", humidity);for (int i = 0; buffer[i] != '\0'; i++){USART1_SendChar(buffer[i]);}// 延时一段时间for (int i = 0; i < 1000000; i++);}
}// ADC配置
void ADC_Configuration(void)
{ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;// 使能ADC1和GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置GPIOA.1为模拟输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// ADC配置ADC_DeInit(ADC1);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);// 配置ADC1的通道1为采样通道ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);// 使能ADC1ADC_Cmd(ADC1, ENABLE);// ADC校准ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}// 串口配置
void UART_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 使能USART1和GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置USART1引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// USART配置USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);// 使能USART1USART_Cmd(USART1, ENABLE);
}// 发送字符到USART1
void USART1_SendChar(char ch)
{USART_SendData(USART1, (uint8_t)ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

以上代码使用STM32的标准库函数进行配置和操作。在ADC_Configuration函数中进行ADC的初始化配置,包括GPIO引脚配置、ADC时钟使能、通道配置等。
UART_Configuration函数中进行串口USART1的初始化配置,包括GPIO引脚配置、波特率设置等。

在主函数中,进入一个无限循环。在循环中,启动ADC转换,并等待转换完成。
通过ADC_GetConversionValue函数读取ADC转换结果,将其转换为湿度百分比。
使用sprintf函数将湿度值格式化为字符串,并使用USART1_SendChar函数将字符串逐个字符发送到USART1串口。
通过延时函数进行一段时间的延时,以控制打印速率。

3.3 大棚补光灯控制

以下是使用STM32F103ZET6读取BH1750光照传感器输出的光照强度,并根据阈值控制LED补光灯灯开关实现代码:

#include "stm32f10x.h"
#include "i2c.h"
#include "delay.h"#define BH1750_ADDRESS 0x23void BH1750_Init()
{// 初始化I2C总线I2C_Init();
}void BH1750_Start()
{// 启动BH1750测量uint8_t cmd = 0x01; // 单次高分辨率模式I2C_Start();I2C_SendByte(BH1750_ADDRESS);I2C_WaitAck();I2C_SendByte(cmd);I2C_WaitAck();I2C_Stop();
}uint16_t BH1750_Read()
{// 读取BH1750测量结果uint16_t lux;I2C_Start();I2C_SendByte(BH1750_ADDRESS + 1); // 发送读命令I2C_WaitAck();lux = I2C_ReceiveByte() << 8; // 读取高字节I2C_Ack();lux |= I2C_ReceiveByte(); // 读取低字节I2C_NAck();I2C_Stop();return lux;
}void LED_Control(uint8_t state)
{// 控制LED照明灯开关if (state)GPIO_SetBits(GPIOA, GPIO_Pin_8); // 打开LEDelseGPIO_ResetBits(GPIOA, GPIO_Pin_8); // 关闭LED
}int main(void)
{// 初始化GPIO口GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 初始化BH1750传感器BH1750_Init();while (1){// 启动测量BH1750_Start();// 延时等待测量完成DelayMs(200);// 读取光照强度uint16_t lux = BH1750_Read();// 判断阈值并控制LEDif (lux > 1000)LED_Control(1); // 光照强度高于阈值,打开LEDelseLED_Control(0); // 光照强度低于阈值,关闭LED}
}

代码中初始化I2C总线和BH1750传感器,通过BH1750_Init()函数实现。在主循环中,启动测量延时等待测量完成。使用BH1750_Read()函数读取测量结果,即光照强度。根据阈值判断光照强度是否高于设定值,通过LED_Control()函数控制LED的开关状态。

四、总结

本项目基于STM32微控制器实现了一个蔬菜大棚温湿度智能控制系统。系统的主控芯片采用了STM32F103ZET6,用于控制和协调各个硬件模块的工作。系统包括空气温湿度采集模块(DHT11)、土壤湿度采集模块(ADC接口)、通风风机(5V小风扇+继电器控制)、照明灯(LED白色灯模块)、灌溉系统(抽水电机+继电器控制)以及LCD显示屏。

系统的功能包括温湿度的实时监测、土壤湿度的检测、通风风扇的自动控制、灌溉系统的自动控制和数据的显示。通过按键设置土壤湿度阈值,实现自动浇水功能,当土壤湿度低于阈值时,系统自动开启灌溉系统进行浇水。同时,根据设定的温度阈值,系统自动控制通风风扇进行降温。

蔬菜大棚温湿度智能控制系统利用STM32微控制器和各种传感器实现了对环境参数的监测和控制,提高了蔬菜大棚的自动化程度和生产效率。同时,通过自动控制灌溉和通风系统,能够更好地满足蔬菜生长的需求,提高农作物的产量和质量。

这篇关于基于STM32的蔬菜大棚温湿度智能控制系统设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/814234

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

SprinBoot+Vue网络商城海鲜市场的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者,全网30w+