jjzjj

基于51单片机的温室大棚环境检测系统

Svan. 2023-04-14 原文

**

基于51单片机的温室大棚环境监测系统

空气温湿度监测,土壤温湿度监测,光照监测,无线传输数据

**

文末尾附带源码

1.1 研究背景

    随着人们生活水平的不断提高,人们对自身的健康越来越关注,对各类食物的要求也越来越高,温室大棚作为培育瓜果蔬菜的生长基地,因此对温室大棚中植物的生长环境进行实时监测是尤为重要的,所以对温室大棚环境监测系统设计的研究是很有必要的。

1.2 设计要求
(1)选择合适的传感器,并设计传感器信号调理电路;
(2)用液晶显示器12864实时显示大棚环境参数;
(3)设计按键电路能够设置环境参数的上下限;
(4)设声光报警电路,通过按键设置阈值,在超限后报警;
(5)通过NRF24L01模块实现无线传输;
(6)屏幕显示实时时间,并可进行调整;

2.1 系统方案框图

2.2 方案分析
以GY-30光照模块,DS18B20土壤温度模块,YL-69土壤湿度模块和DHT11温湿度模块和STC89C52单片机为控制核心组成环境监测系统的发射板,实现对现场光照,土壤温湿度以及空气温湿度数据的采集。
以DS1302实时时钟模块,LCD12864显示模块以及蜂鸣器报警模块和STC89C52单片机为控制核心组成环境监测系统的接收板,实现对实时始终数据的采集和对发射板接收数据的显示,以及实现在超限后声光报警。
通过NRF24L01无线模块进而实现发射板和接收板之间的数据通信。
1. 单片机选择
单片机采用宏晶科技的单片机STC89C52。STC89C52是一种低功耗、高性能CMOS8位微控制器。STC89C52使用经典的MCS-51内核,拥有灵巧的8 位CPU 和在系统可编程Flash。
2. 光照模块电路
采用GY-30构成光照模块电路。GY-30是一款内置ROHM-BH1750FLV芯片的数字光照强度模块。芯片内置16bitAD转换器,可直接数字输出,测量光照强度范围为0-65535lx(精度可选)。除此之外,模块内置电平转换,支持3-5V供电,可与5V单片机IO直接连接;对外提供IIC接口,方便使用。

3. 土壤温度模块电路
采用DS18B20构成土壤温度模块电路。DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。它的接线方便,封装成后可应用于多种场合。

4. 土壤湿度模块电路
土壤湿度模块电路采用YL-69。YL-69 是一个简单的土壤湿度传感器,是一种电容式传感器,主要使用的是湿敏电容。当环境的湿度发生改变时,会使得湿敏电容存在的环境中的介质发生改变,导致湿敏电容中的电容数值产生变化,电容的数值正比于湿度值 。由于湿敏电容的灵敏度高、响应速度快、滞后量小,此外微小的体积、极低的功耗,使得湿敏电容很容易小型化和集成化。YL-69 采用 CMOS 工艺,可以确保其低功耗,同时还具有很高的可靠性和稳定性。传感器内部含有一个电容性聚合体湿度敏感元件和一个用能隙材料做成的温度传感器,在同一芯片上,与 A/D 转换器及串行接口电路实现连接。

5. 空气温湿度模块电路
空气温湿度模块电路采用DHT11模块,DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。

6.无线模块电路
无线模块电路采用NRF24L01模块,NRF24L01是一款新型单片射频收发器件,工作于2.4 GHz~2.5 GHz ISM频段。内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和通信频道可通过程序进行配置。

7.LCD12864显示模块电路
带中文字库的128X64 是一种具有4 位/8 位并行、2 线或3 线串行多种接口方式,内部含有国标一级、二级简体 中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192 个1616 点汉字,和128 个168 点ASCII 字符 集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。

8.报警模块电路
本设计的报警电路采用了一个电磁式有源蜂鸣器来实现。报警电路连接在单片机的某一特定管脚,随时会根据输出信号控制报警电路的工作与否。设定一个温度界限,当采集到的温度超过界限的时候,蜂鸣器则会一直响;当温度在温度界限内时,蜂鸣器停止鸣叫。
9.实时时钟模块电路
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。

4.1 主程序设计

整个软件部分分为发射板空气温湿度,土壤温湿度和光照数据的采集和数据的无线传输以及接收板数据的显示。
首先DHT11进行初始化,通过调用采集数据函数,分别采集空气的湿度信息,温度信息,返回数据,再通过内部AD转换将采集到的数据串行的存入发送缓冲器;
通过YL-69初始化函数初始化模块,再调用采集数据函数,读取当前传感器的探头湿度信息,为当前的探头电容值,对采集土壤湿度信息,因为模块没有AD转换电路,所以外接ADC0832芯片,通过对ADC0832芯片初始化,进行AD转换,返回数据,再将数据存入发送缓冲器中;
通过DS18B20初始化函数初始化模块的工作方式,调用采集土壤温度信息函数,内部采用减法计数器的原理,最终得到的当前温度数据,返回数据,将数据串行存入发送缓冲器中;
通过GY-30初始化初始化函数初始化工作方式,调用并采集光照信息的函数,采集到的信息分为8位,将数据按位取出来,分别×对应位置的倍数得到最终的数据,返回数据,将得到的数据存入发送缓冲器中;
通过最后通过设置NRF24L01初始化,将发送缓冲器的数组给到NRF24L01的数据发送函数,NRF24L01根据对应缓冲器中的数据长度,将发送缓冲器中的数据串行按位发送给接收板,发送给接收单片机。
将上述模块化的程序放入while大循环里,从而实现了对数据的实时采集,实时发送。实现了本次课设的基本要求,下图为发送板的主程序框图:

数据接受板,通过无线模块对数据进行接收,将发送缓冲器的数据存入接收缓冲器,再通过对接收缓冲器中的对应位置数据进行显示,分别读取对应索引的数值。
调用12864显示函数对数值数字化显示,在通过接收DS1302实时时钟芯片对应时、分、秒的引脚的数据,通过程序控制进位,调用对应日期和相应实时传输的数据的显示函数进行显示;
在程序中定义对应位置的按键,sbit定义按键对应单片机的引脚,设置按键的功能从S1-S5对应功能分别为:时间设置,阈值设置,加计数,减计数,确认。
按下时间设置可以对时间的秒进行设置,再次按下时可以对应光标为分位置,再按下可以进入时的位置,以此类推;
按下阈值设置按键可以分别进入空气温度,湿度设置,光照设置,土壤温度,土壤湿度阈值设置,从而实现对相应数据进行设置。
按下S5即最后一个按键,可以对设置的当前时间、阈值进行确认;之后程序进入对通过标志位flag判断为1超过阈值,对于温度,空气湿度,土壤温度,土壤湿度超过阈值的当前实时数据进行监测,超过阈值则蜂鸣器报警,否则flag判断为0,继续执行。
将上述程序放入大的循环中,从而实现了对发送板发送的数据进行实时采集的功能,下图分别为接收板程序设计图:

部分实物图,PCB展示


需要实物pcb板的朋友请私信

部分程序源码

部分源码 采用keil4编写.

// 发射板源代码:
#include <stc89c52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define FOSC 11059200L      //System frequency
#define BAUD 2400           //UART baudrate
unsigned char flagcom=0;
//2401IO端口定义sbit 	MISO	=P0^2;
sbit 	MOSI	=P0^4;
sbit	SCK	    =P0^1;
sbit	CE	    =P0^0;
sbit	CSN		=P0^5;
sbit	IRQ		=P0^3;
unsigned char xdata TxBuf[32]=0;		//2401 发送寄存器
sbit     DQ=P2^7;        //DHT11
//bh1750
sbit	  SCL=P2^1;      //IIC时钟引脚定义
sbit  	  SDA=P2^2;      //IIC数据引脚定义
#define	  SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                              //ALT  ADDRESS引脚接地时地址为0x46,接电源时地址为0x3A
typedef   unsigned char BYTE;
typedef   unsigned short WORD;
uchar   BUF[8];                         //接收数据缓存区  
unsigned char  xdata    ge,shi,bai,qian,wan;            //显示变量
uchar tem;  //温度
uchar  hum;  //湿度
uint guangzhao=0;		//光照
uint pm25=0;			//pm2.5
uint tw=0;  //土壤温度 
uint ts=0;  //土壤湿度 
uint flag1=0;
sbit 	LED1=P1^1;
sbit 	LED2=P1^4;
//*************************************ADC0832定义*****************/
//ADC0832 
sbit CS = P1^5;
sbit CLK = P1^6;
sbit DIO = P1^7; 
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5   	// 5 uints TX address width
#define RX_ADR_WIDTH    5   	// 5 uints RX address width
#define TX_PLOAD_WIDTH  32  	// 20 uints TX payload
#define RX_PLOAD_WIDTH  32  	// 20 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00  	// 读寄存器指令
#define WRITE_REG       0x20 	// 写寄存器指令
#define RD_RX_PLOAD     0x61  	// 读取接收数据指令
#define WR_TX_PLOAD     0xA0  	// 写待发数据指令
#延时函数
void inerDelay_us(unsigned char n)
{
	for(;n>0;n--)
		_nop_();
}
void Delay5ms()
{
    WORD n = 560;
    while (n--);
}
void delay_nms(unsigned int k)	
{						
unsigned int i,j;				
for(i=0;i<k;i++)
{			
for(j=0;j<121;j++)			
{;}}						
}
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
}
//******************************复位ds18b20************/ 
void Init_ds18b20(void) {
	DQ = 1; 
	delay(1); 
	DQ = 0; 
	delay(250); 
	DQ = 1; 
	delay(100);
}

#NRF24L01初始化
void init_NRF24L01(void)
{
    inerDelay_us(100);
 	CE=0;    // chip enable
 	CSN=1;   // Spi disable 
 	SCK=0;   // Spi clock line init high
	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址	
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动	ACK应答允许	
	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
	SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   设置信道工作为2.4GHZ,收发必须一致
	SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   		//设置发射速率为1MHZ,发射功率为最大值0dB	
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);   		 // IRQ收发完成中断响应,16位CRC,主发送

}

有关基于51单片机的温室大棚环境检测系统的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  6. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  7. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

  8. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  9. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  10. ruby - Ruby 脚本如何检测到它正在 irb 中运行? - 2

    我有一个定义类的Ruby脚本。我希望脚本执行语句BoolParser.generate:file_base=>'bool_parser'仅当脚本作为可执行文件被调用时,而不是当它被irbrequire(或通过-r在命令行上传递)时。我可以用什么来包装上面的语句,以防止它在我的Ruby文件加载时执行? 最佳答案 条件$0==__FILE__...!/usr/bin/ruby1.8classBoolParserdefself.generate(args)p['BoolParser.generate',args]endendif$0==_

随机推荐