1、自动开关灌溉设备
2、自动开关排风扇及喷洒设备
3、自动开关补光灯及窗户换气
系统运行后,LCD1602显示温湿度值、光照强度、二氧化碳浓度、土壤湿度值。可通过按键K3进入阈值设置界面,K3每按一次切换温湿度、光照强度、二氧化碳浓度、土壤湿度上下限阈值设置界面,通过K1/K2键进行加减数据,设置好后可按K4键保存并返回主菜单。系统不断检测比较当前传感器值与阈值,若超限控制对应的设备工作。最终可实现:
1、自动开关灌溉设备
2、自动开关排风扇及喷洒设备
3、自动开关补光灯及窗户换气
1、51单片机核心模块
2、PCF8591 ADC/DAC模块
3、LCD1602模块
4、水泵/风扇/窗户/补光灯开关模块
5、DS18B20温度/光敏/CO2/湿度检测模块
6、按键/蜂鸣器报警模块
主要代码如下:
/*
作者:嗨小易(QQ:3443792007)
版权:本教程版权归嗨小易(QQ:3443792007)所有,未经授权不得转载、摘编或用于其他商业用途!!!
一经发现,后果自负!!!
*/
#include "appdemo.h"
#include "lcd1602.h"
#include "key.h"
#include "beep.h"
#include "pcf8591.h"
#include "ds18b20.h"
#include "exti.h"
//定义风扇控制脚
sbit MOTOR=P1^0;
//定义水泵控制脚
sbit PUMP=P1^1;
//定义窗户控制脚
sbit WINDOW=P1^2;
//定义补光灯控制脚
sbit LED=P1^3;
//定义结构体
_sys_ctrl sys_ctrl;
void exti0(void) interrupt 0 //外部中断0中断函数
{
delay_10us(1000);//消斗
if(KEY3==0)//再次判断K3键是否按下
{
sys_ctrl.mode++;
if(sys_ctrl.mode==8)sys_ctrl.mode=1;
lcd1602_clear();
delay_ms(10);
switch(sys_ctrl.mode)
{
case 1://温度上限设置显示界面
lcd1602_show_string(0,0,"TempH Set:");
break;
case 2://温度下限设置显示界面
lcd1602_show_string(0,0,"TempL Set:");
break;
case 3://土壤湿度上限设置显示界面
lcd1602_show_string(0,0,"SoilH Set:");
break;
case 4://土壤湿度下限设置显示界面
lcd1602_show_string(0,0,"SoilL Set:");
break;
case 5://光照强度上限设置显示界面
lcd1602_show_string(0,0,"BeamH Set:");
break;
case 6://光照强度下限设置显示界面
lcd1602_show_string(0,0,"BeamL Set:");
break;
case 7://CO2上限设置显示界面
lcd1602_show_string(0,0," CO2H Set:");
break;
}
}
}
void exti1(void) interrupt 2 //外部中断1中断函数
{
delay_10us(1000);//消斗
if(KEY4==0)//再次判断K4键是否按下
{
sys_ctrl.mode=0;
lcd1602_clear();
delay_ms(10);
lcd1602_show_string(0,0,"Tp: C");
lcd1602_show_string(9,0,"So: ");
lcd1602_show_string(0,1,"Bm: ");
lcd1602_show_string(9,1,"C2: ");
}
}
//阈值设定
void key_set_threshold(void)
{
u8 key=0;
//温度上限设置
while(sys_ctrl.mode==1)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.temph+=THRESHOLD_STEP;
if(sys_ctrl.temph>=80)sys_ctrl.temph=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.temph-=THRESHOLD_STEP;
if(sys_ctrl.temph<=0)sys_ctrl.temph=80;
}
lcd1602_show_nums(10,0,sys_ctrl.temph,2,0);
}
//温度下限设置
while(sys_ctrl.mode==2)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.templ+=THRESHOLD_STEP;
if(sys_ctrl.templ>=40)sys_ctrl.templ=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.templ-=THRESHOLD_STEP;
if(sys_ctrl.templ<=0)sys_ctrl.templ=40;
}
lcd1602_show_nums(10,0,sys_ctrl.templ,2,0);
}
//土壤湿度上限设置
while(sys_ctrl.mode==3)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.soilh+=THRESHOLD_STEP*10;
if(sys_ctrl.soilh>=250)sys_ctrl.soilh=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.soilh-=THRESHOLD_STEP*10;
if(sys_ctrl.soilh<=0)sys_ctrl.soilh=250;
}
lcd1602_show_nums(10,0,sys_ctrl.soilh,4,0);
}
//土壤湿度下限设置
while(sys_ctrl.mode==4)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.soill+=THRESHOLD_STEP*10;
if(sys_ctrl.soill>=250)sys_ctrl.soill=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.soill-=THRESHOLD_STEP*10;
if(sys_ctrl.soill<=0)sys_ctrl.soill=250;
}
lcd1602_show_nums(10,0,sys_ctrl.soill,4,0);
}
//光照强度上限设置
while(sys_ctrl.mode==5)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.beamh+=THRESHOLD_STEP*10;
if(sys_ctrl.beamh>=250)sys_ctrl.beamh=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.beamh-=THRESHOLD_STEP*10;
if(sys_ctrl.beamh<=0)sys_ctrl.beamh=250;
}
lcd1602_show_nums(10,0,sys_ctrl.beamh,4,0);
}
//光照强度下限设置
while(sys_ctrl.mode==6)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.beaml+=THRESHOLD_STEP*10;
if(sys_ctrl.beaml>=250)sys_ctrl.beaml=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.beaml-=THRESHOLD_STEP*10;
if(sys_ctrl.beaml<=0)sys_ctrl.beaml=250;
}
lcd1602_show_nums(10,0,sys_ctrl.beaml,4,0);
}
//CO2溶度上限设置
while(sys_ctrl.mode==7)
{
key=key_scan(0);
if(key==KEY1_PRESS)//加
{
sys_ctrl.co2h+=THRESHOLD_STEP*10;
if(sys_ctrl.co2h>=250)sys_ctrl.co2h=0;
}
else if(key==KEY2_PRESS)//减
{
sys_ctrl.co2h-=THRESHOLD_STEP*10;
if(sys_ctrl.co2h<=0)sys_ctrl.co2h=250;
}
lcd1602_show_nums(10,0,sys_ctrl.co2h,4,0);
}
}
//参数初始化
void sys_para_init(void)
{
sys_ctrl.mode=0;
sys_ctrl.temph=30;
sys_ctrl.templ=20;
sys_ctrl.soilh=200;
sys_ctrl.soill=100;
sys_ctrl.beamh=200;
sys_ctrl.beaml=100;
sys_ctrl.co2h=200;
}
//数据采集
void sys_get_data(void)
{
u8 i=0;
while(sys_ctrl.mode==0)
{
i++;
if(i%200==0)
{
//读取DS18B20温度值
sys_ctrl.temp=ds18b20_read_temperture();
//读取光照强度值
sys_ctrl.beam=pcf8591_read_adcvalue(1);
//读取土壤湿度值
sys_ctrl.soil=pcf8591_read_adcvalue(2);
//读取CO2值
sys_ctrl.co2=pcf8591_read_adcvalue(0);
break;
}
delay_ms(1);
}
}
//采集数据显示
void sys_data_show(void)
{
while(sys_ctrl.mode==0)
{
lcd1602_show_nums(3,0,sys_ctrl.temp,2,0);
lcd1602_show_nums(12,0,sys_ctrl.soil,4,0);
lcd1602_show_nums(3,1,sys_ctrl.beam,4,0);
lcd1602_show_nums(12,1,sys_ctrl.co2,4,0);
break;
}
}
//温湿度自动控制
void auto_control(void)
{
while(sys_ctrl.mode==0)
{
//当土壤湿度低于下限值,开启水泵,否则若土壤湿度高于上下值,关闭水泵
if(sys_ctrl.soil<sys_ctrl.soill)
PUMP=0;//开启水泵
else if(sys_ctrl.soil>=sys_ctrl.soilh)
PUMP=1;//关闭水泵
//当空气温度高于上限值,开启风扇,蜂鸣器报警
if(sys_ctrl.temp>=sys_ctrl.temph)
{
MOTOR=0;//开启风扇
beep_alarm(100,20);//蜂鸣器报警
}
else if(sys_ctrl.temp<sys_ctrl.templ)
{
MOTOR=1;//关闭风扇
beep_alarm(100,20);//蜂鸣器报警
}
//当CO2溶度高于上限,打开窗户,蜂鸣器报警
if(sys_ctrl.co2>=sys_ctrl.co2h)
{
WINDOW=0;//开启窗户
beep_alarm(100,20);//蜂鸣器报警
}
else
WINDOW=1;//关闭窗户
//当光照强度低于下限,打开补光灯
if(sys_ctrl.beam<sys_ctrl.beaml)
LED=0;//打开补光灯
else if(sys_ctrl.beam>=sys_ctrl.beamh)
LED=1;//关闭补光灯
break;
}
}
//智能温湿度大棚控制系统
void appdemo_show(void)
{
lcd1602_init();
ds18b20_init();
sys_ctrl.temp=ds18b20_read_temperture();
delay_ms(1000);
exti0_init();
exti1_init();
//初始界面
lcd1602_show_string(0,0,"Tp: C");
lcd1602_show_string(9,0,"So: ");
lcd1602_show_string(0,1,"Bm: ");
lcd1602_show_string(9,1,"C2: ");
sys_para_init();//系统参数初始化
while(1)
{
key_set_threshold();//阈值设定
sys_get_data();//数据采集
sys_data_show();//采集数据显示
auto_control();//温湿度自动控制
}
}
B站演示视频:https://space.bilibili.com/444388619
①开机界面
②阈值设置界面
其他阈值设置界面截图这里就不一一列出。。。
③自动控制
B站演示视频:https://space.bilibili.com/444388619
可提供手把手教学服务,资料获取请联系作者QQ:3443792007
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。