功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602实时显示当前环境温湿度,烟雾浓度,室外是否下雨
2.按键可设定烟雾浓度,环境温湿度阈值,雨滴检测阈值
3.当环境适宜时,打开窗户,当外面下雨时,关闭窗户
4.当室内烟雾浓度超过设定阈值时,无论如何都将打开窗户
5.可手动控制窗户开关状态
6.可通过WIFI控制窗户开关状态
*1O# 表示打开窗户
*1C# 表示关闭窗户
WIFI控制窗户后,进入手动模式
*1A# 表示可恢复自动模式
*1M# 表示可进入手动模式
原理图:
PCB:
主程序:
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include "delay.h"
#include "dht11.h"
#include "lcd1602.h"
#include "tlc0832.h"
#include "28BYJ48.h"
sbit KEY_SWITCH = P3^5; //确认按键
sbit KEY_SET = P3^3; //设置按键
sbit KEY_ADD = P3^4; //加按键
sbit KEY_SUB = P3^6; //减按键
#define ON 0
#define OFF 1
enum {NORMAL=1, SET_TEMP, SET_HM, SET_SMOG} DispMode;
unsigned char dis0[18]; //数组暂存
unsigned char R_buf[4];
bit refreshFlag = 0;
bit setFlag = 0; //设置标志
bit setIndex = 0;
bit autoFlag = 1;
bit openFlag = 0;
bit rainFlag = 0;
int temp = 0;
int humidity = 0;
int smogConc = 0;
int minTemp = 20;
int maxTemp = 35;
int minEvHm = 35;
int maxEvHm = 85;
int maxSmogConc = 30;
int water = 0;
unsigned char motorDir = 0;
void Timer0_Init(); //函数声明
void UART_Init();
void UART_SendByte(unsigned char dat);
void UART_SendStr(unsigned char *s, unsigned char length);
void DispNormal(void);
void DispSetTemp(setFlag, setIndex);
void DispSetHm(setFlag, setIndex);
void DispSetSmog(setFlag, setIndex);
void WindowCtrl(void);
void MotorCtrl(void);
void KeyScan(void);
void main()
{
Timer0_Init(); //定时器0初始化
LCD_Init(); //LCD初始化
LCD_Clear();
LCD_DispStr(4, 0, "Welcome!");
DelayS(1); //等待WIFI启动
UART_Init(); //串口初始化
UART_SendStr("AT+CIPMUX=1\r\n", 13); //打开多连接
DelayS(1);
UART_SendStr("AT+CIPSERVER=1,8080\r\n", 21); //建立服务 端口号为8080
DelayS(1);
DispMode = NORMAL;
while (1) //主循环
{
if (refreshFlag == 1) //刷新数据标志
{
static unsigned char cnt = 0;
refreshFlag = 0;
//检测数据
TR0 = 0; //关总中断
if (cnt % 5 == 0)
{
DHT11_ReadData(); //检测温湿度
temp = U8T_data_H;
humidity = U8RH_data_H;
}
smogConc = 100 * ReadADC(AIN1_GND) / 255; //检测烟雾浓度
if (smogConc < 0)
{
smogConc = 0;
}
else if (smogConc > 99)
{
smogConc = 99;
}
water = 100 - 100 * ReadADC(AIN0_GND) / 255; //检测雨滴
if (water >= 10)
{
rainFlag = 1;
}
else
{
rainFlag = 0;
}
WindowCtrl();
if (DispMode == NORMAL)
{
DispNormal();
}
else if (DispMode == SET_TEMP)
{
DispSetTemp(setFlag, setIndex);
}
else if (DispMode == SET_HM)
{
DispSetHm(setFlag, setIndex);
}
else if (DispMode == SET_SMOG)
{
DispSetSmog(setFlag, setIndex);
}
TR0 = 1; //开总中断
if (cnt >= 10) // 5秒发送一次
{
cnt = 0;
// WIFI发送数据
UART_SendStr("AT+CIPSEND=0,35\r\n", 17); //发送AT命令
DelayMs(100);
sprintf(dis0, "Temp:%02d'C Hm:%02d%% \r\n", temp, humidity);
UART_SendStr(dis0, 19); //发送内容
if (autoFlag == 1) //自动模式
{
sprintf(dis0, "Smog:%3d%% A ", smogConc);
}
else
{
sprintf(dis0, "Smog:%3d%% M ", smogConc);
}
UART_SendStr(dis0, 12); //发送内容
if (openFlag == 1)
{
UART_SendStr("O ", 2); //发送内容
}
else
{
UART_SendStr("C ", 2); //发送内容
}
if (rainFlag == 1)
{
UART_SendStr("YY\r\n", 3); //发送内容
}
else
{
UART_SendStr("WY\r\n", 3); //发送内容
}
}
else
{
cnt++;
}
}
EA = 0;
MotorCtrl();
EA = 1;
KeyScan();
}
}
void WindowCtrl(void)
{
static bit Flag1 = 0;
static bit Flag2 = 0;
static bit Flag3 = 0;
static bit openFlagBuf = 0;
if (autoFlag == 1)
{
if (smogConc >= maxSmogConc) //烟雾浓度过高
{
Flag1 = 1; //打开窗户标志1
}
else
{
Flag1 = 0; //关闭窗户标志1
}
if (rainFlag == 0) //未下雨
{
Flag2 = 1; //打开窗户标志2
}
else
{
Flag2 = 0; //关闭窗户标志2
}
if ((temp >= minTemp && temp <= maxTemp) && (humidity >= minEvHm && humidity <= maxEvHm)) //环境适宜时
{
Flag3 = 1; //打开窗户标志3
}
else
{
Flag3 = 0; //关闭窗户标志3
}
if (Flag1) //烟雾浓度超高,优先级最高
{
openFlag = 1;
}
else
{
if (Flag2) //确认没有下雨,优先级次之
{
if (Flag3) //确认环境适宜,优先级最低
{
openFlag = 1;
}
else
{
openFlag = 0;
}
}
else
{
openFlag = 0;
}
}
}
if (~openFlagBuf && openFlag) //开窗
{
motorDir = 1; //正转标志
}
else if (openFlagBuf && ~openFlag) //关窗
{
motorDir = 2; //反转标志
}
openFlagBuf = openFlag;
}
void MotorCtrl(void)
{
static int motorCnt = 0;
if (motorDir == 1)
{
motorCnt++;
motor_z();
if (motorCnt == 64)
{
motorDir = 0;
}
}
else if (motorDir == 2)
{
motorCnt--;
motor_f();
if (motorCnt == 0)
{
motorDir = 0;
}
}
}
void DispNormal(void)
{
//LCD显示数据
sprintf(dis0, "Temp:%2d", temp);
LCD_DispStr(0, 0, dis0);
LCD_DispOneChar(7, 0, 0xdf); //摄氏度的点
sprintf(dis0, "C Hm:%2d%%", humidity);
LCD_DispStr(8, 0, dis0);
if (autoFlag == 1)
{
sprintf(dis0, "Smog:%3d%% A", smogConc); //自动模式
}
else
{
sprintf(dis0, "Smog:%3d%% M", smogConc); //WIFI控制,手动模式显示
}
LCD_DispStr(0, 1, dis0);
if (openFlag == 1) //窗户打开
{
LCD_DispStr(12, 1, "O ");
}
else //窗户关闭
{
LCD_DispStr(12, 1, "C ");
}
if (rainFlag == 1)
{
LCD_DispStr(14, 1, "YY"); //有雨
}
else
{
LCD_DispStr(14, 1, "WY"); //无雨
}
}