基于51单片机和物联网的智能家居系统(ESP8266物联网模块)

前言

该智能家居系统以 STC89C52单片机为控制核心,结合 LCD1602 液晶显示屏、L298N电机驱动模块、光敏电阻,ESP8266WiFi模块,DS18B20温度计设计并实现了自动感光窗帘与居室内外温度检测器。通过最终的调试,实现了基本部分和发挥部分的全部功能。温度检测系统在环境温度改变的状况下能够实现偏差为 0.5℃的基本温度测量。而智能窗帘系统在光照强度不一样的状况下电机表现了不一样的转动状态,故该系统具备感光自动开关的功能,同时该系统经过物联网模块实现了用户与窗帘交互的功能,能够手动调节窗帘的开关。如下是我和个人两名队友花了四天三夜共同完成的做品实物图
在这里插入图片描述javascript

虽然外观不是很好看?,可是基本能够实现全部所须要的功能,如下是对该做品的设计与总结java

目录

1、系统方案
1.系统整体方案设计
2.系统结构框图web

2、电路与程序设计
1.各部分电路设计
2.程序设计数组

3、测试结果
1.测试方案
2.测试结果及分析网络

4、结论svg

5、附录.
1.电路原理图
2.程序清单函数

1、系统方案
1.系统整体方案设计
(1)居室内外温度检测系统
本系统以 STC89C52 芯片做为控制中心,DS18B20 温度传感器为测温元件,LCD1602 液晶显示屏为显示器件。DS1802 数字温度计提供 9 位温度读数,指示器件的温度。信息通过单线接口送入DS1820 或从 DS1820 送出。当信息送入,通过单片机处理后在液晶上显示。其系统框图如图 1 所示。
(2)智能窗帘
本系统由光照检测电路、电机驱动电路以及物联网模块三个部分组成。窗帘自动控制系统的光控功能是能够根据光照的强弱来自动控制窗帘的开闭的,所以须要用到光照传感元器件,在本设计中采用了光敏电阻,并和一个常规电阻串联在一块儿,根据光线的变化改变光敏电阻的分压值,而后经过 XPT2046数模转换芯片传输给单片机,而后根据转换后的数值对电机的转动状态进行调控。同时用户能够经过物联网模块对电机的转动状态进行了解和调控。其系统框图如图2所示。学习

2.系统结构框图测试

图1ui

图二图2

2、电路与程序设计
1.各部分电路设计
(1)温度检测模块
在温度检测系统中,该模块起到检测外部环境温度的做用。DS1802 数字温度计提供 9 位温度读数,指示器件的温度。信息通过单线接口送入 DS1820 或从DS1820 送出,所以从中央处理器到 DS1820 仅需链接一条线(和地)。读、写和完成温度变换所需的电源能够由数据线自己提供,而不须要外部电源。
(2)AD 转换模块
为使被检测到的温度数据转换为电信号后传输至单片机,故设计一个 AD 转换模块以达到目的。其中 XPT2046 是一款 4 线制电阻式触摸屏控制器,内含 12位分辨率 125KHz 转换速率逐步逼近型 A/D 转换器。XPT2046 支持从 1.5V 到 5.25V的低电压 I/O 接口。内部自带 2.5V 参考电压,能够做为辅助输入、温度测量和电池监测之用,电池监测的电压范围能够从 0V 到 6V。所以能够知足系统要求。
(3)电机驱动模块
在智能窗帘系统中,电机模块用于使智能窗帘实现自动开关的功能。若要对电机进行 PWM 调速,需设置 IN1 和 IN2,肯定电机的转动方向,而后对使能端输出 PWM 脉冲,便可实现调速。当使能信号为 0 时,电机处于自由中止状态;当使能信号为 1 时,且 IN1 和 IN2 为 00 或 11 时,电机处于制动状态,阻止电机转动。所以可在不一样状况下,根据外部环境改变电机的转动状态,知足系统要求。 (4)STC90C52本设计选用单片机 STC89C52 做为控制核心,它是宏晶科技推出的新一代超强抗干扰、高速、低功耗的单片机,基于 Intel 标准的 8052,指令代码彻底兼容传统的 8051 系列单片机,12 时钟/机器周期和 6 时钟/机器周期可任意选择,最新的 D 版本内集成 MAX810 专用复位电路。
(5)LCD 液晶显示屏
在温度检测系统中用于显示场景的温度数据以及在智能窗帘系统中用于显示光照强度数据。为工业字符型液晶,可以同时显示 16x2 即 32 个字符。
(6)ESP8266-01
为使用户能够随时了解并控制窗帘的开闭状态,故设计物联网模块以实现智能窗帘与用户交互的功能。其中 ESP8266 是一款超低功耗的 UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备链接到 Wi-Fi 无线网络上,进行互联网或局域网通讯,实现联网功能。
2.程序设计
(1)居室内外温度检测系统
本系统以 STC89C52 做为主控芯片,实现温度检测功能。其中温度检测模块检测环境温度,LCD1602 显示温度数据。流程图如图 3 所示。
(2)智能窗帘
本系统以 STC89C52 做为主控芯片,实现窗帘根据环境中光照强度自动开关的功能,且同时用户也能够经过移动终端了解并控制窗帘状态。其中光照检测系统检测环境中光照强度,电机驱动系统控制电机转动状态,物联网模块实现窗帘与用户交互功能。流程图如图 3 所示。

在这里插入图片描述 图3

3、测试结果
1.测试方案
(1)居室内外温度检测系统
改变温度检测模块附近环境温度,观察 LCD1602 液晶屏所显示温度数据,测试结果为显示数据与实际环境温度基本吻合。
(2)智能窗帘
首先用手电筒照射装置,使光照强度大于 300,测试结果为窗帘打开,而后将装置放到阴暗处,使光照强度低于 90,测试结果为窗帘关闭。接着按下装置上方按键,将窗帘由自动模式转为手动模式,用手机链接装置的 WiFi 模块,控制窗帘的状态,测试结果为手机发送 1 时窗帘打开,发送 2 时窗帘关闭。
2.测试结果及分析
由测试结果能够看出,温度检测系统与智能窗帘系统可实现题目的基本要求部分和发挥部分的全部功能。其中温度检测系统能够在偏差为 0.5℃的状况下检测出环境温度;智能窗帘系统能够实现强光与弱光环境下自动开关。另外部分功能如智能窗帘系统能够经过物联网模块使用户能在移动终控制窗帘状态。

4、结论
温度检测系统与智能窗帘系统实现了基本部分的所有功能以及完成了一些发挥部分,符合全部指标。本系统经过理论计算获得了合理的设计方案,以 STC89C52 单片机为控制核心,结LCD1602 液晶显示屏、L298N 电机驱动模块、光敏电阻,设计并实现了自动感光窗帘与居所内外温度检测器。经过实际测试,温度检测系统在环境温度改变的状况下实现了偏差为0.5℃的基本温度测量。而智能窗帘系统在光照强度不一样的状况下电机表现了不一样的转动状态,故该系统具备感光自动开关的功能,同时该系统经过物联网模块实现了用户与窗帘交互的功能。

5、附录
1.电路原理图

在这里插入图片描述2.程序清单(因代码太长,这里就只放上主程序了,所有源程序包括原理图见文末)

#include<reg52.h>
#include"lcd.h"
#include"temp.h"
#include"XPT2046.h"
void LcdDisplay(int);//LCD显示函数
void UsartConfiguration();//串口初始化函数
void connect_init();//ESP8266初始化函数

uint temp;
uchar CNCHAR[6] = "摄氏度";
uint i=0;
uint j=0;
int flag=1; //手动 or 自动标志位
int ji=1; //正反转中止标志位
uchar receive[10];//接收数组

sbit K1=P3^3; //按键 IO 口
sbit M2PWM = P1^0; //电机 IO 口
sbit M2B = P1^1; 
sbit M2A = P1^2;
/******************************************************************************* * 函 数 名 : delay和delayms * 函数功能 :10us和1ms的延时 *******************************************************************************/
void delay(unsigned int  i)
{
	while(i--);	
}

void delayms(unsigned int x)
{
	unsigned int i,j;
	for(i=x;i>0;i--)
		for(j=110;j>0;j--);
}
/******************************************************************************* * 函数名 :datapros() * 函数功能 :数据处理光敏函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/
void datapros()
{
		delay(5000);
		temp = Read_AD_Data(0xA4);		// AIN2 光敏电阻
}
/******************************************************************************* * 函数名 : main * 函数功能 : 主函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/

void main()
{	
    UsartConfiguration(); //串口初始化
	connect_init();      //ESP8266初始化
	LcdInit();			 //初始化LCD1602
	LcdWriteCom(0x88);	//写地址 80表示初始地址
	LcdWriteData('C');
	connect_init();   //再次ESP8266初始化
	while(1)
	{	datapros();	 //数据处理函数
	    LcdWriteCom(0x8A);
		LcdWriteData('0'+temp/1000); //千位
		LcdWriteCom(0x8B);
		LcdWriteData('0'+temp%1000/100);  //百位
		LcdWriteCom(0x8C);
		LcdWriteData('0'+temp%1000%100/10);	 //十位
		LcdWriteCom(0x8D);
		LcdWriteData('0'+temp%1000%100%10/10);	//个位 
    if(flag==1)
	{  
	  if(temp<90&&ji==-1)
	   {
		M2PWM=1;
		M2B=1;
		M2A=0;
		delayms(1000);	//转动1s
		M2PWM=0;
		M2B=0;
		M2A=0;
		ji=1;
	   }
	   else if(temp>300&&ji==1)
	   {
		M2PWM=1;
		M2B=0;
		M2A=1;
		delayms(1000); //转动1s
		M2PWM=0;
		M2B=0;
		M2A=0;
		ji=-1;
	   }
	   else
	   {
	   M2PWM=0;
	   M2B=0;
	   M2A=0;
	   } 
      
	}

   if(!K1)			  //手动切自动按键
   {
    delayms(5);		   //消抖
	if(!K1)
	{
	 flag=-flag;
	}
   }
	LcdDisplay(Ds18b20ReadTemp());	//显示温度 光照AD值
	

  }
 }

/******************************************************************************* * 函数名 : LcdDisplay() * 函数功能 : LCD显示读取到的温度 * 输入 : v * 输出 : 无 *******************************************************************************/

void LcdDisplay(int temp) 	 //lcd显示
{
    
  	uchar datas[] = {0, 0, 0, 0, 0}; //定义数组
	float tp;  
	if(temp< 0)				//当温度值为负数
  	{
	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
	    LcdWriteData('-');  		//显示负
		//由于读取的温度是实际温度的补码,因此减1,再取反求出原码
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
		//留两个小数点就*100,+0.5是四舍五入,由于C语言浮点数转换为整型的时候把小数点
		//后面的数自动去掉,不论是否大于0.5,而+0.5以后大于0.5的就是进1了,小于0.5的就
		//算.5,仍是在小数点后面。
 
  	}
 	else
  	{			
	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
	    LcdWriteData('+'); 		//显示正
		tp=temp;//由于数据处理有小数点因此将温度赋给一个浮点型变量
		//若是温度是正的那么,那么正数的原码就是补码它自己
		temp=tp*0.0625*100+0.5;	
		//留两个小数点就*100,+0.5是四舍五入,由于C语言浮点数转换为整型的时候把小数点
		//后面的数自动去掉,不论是否大于0.5,而+0.5以后大于0.5的就是进1了,小于0.5的就
		//算加上0.5,仍是在小数点后面。
	}
	datas[0] = temp / 10000;
	datas[1] = temp % 10000 / 1000;
	datas[2] = temp % 1000 / 100;
	datas[3] = temp % 100 / 10;
	datas[4] = temp % 10;

	LcdWriteCom(0x82);		  //写地址 80表示初始地址
	LcdWriteData('0'+datas[0]); //百位 

	LcdWriteCom(0x83);		 //写地址 80表示初始地址
	LcdWriteData('0'+datas[1]); //十位

	LcdWriteCom(0x84);		//写地址 80表示初始地址
	LcdWriteData('0'+datas[2]); //个位 

	LcdWriteCom(0x85);		//写地址 80表示初始地址
	LcdWriteData('.'); 		//显示 ‘.’

	LcdWriteCom(0x86);		 //写地址 80表示初始地址
	LcdWriteData('0'+datas[3]); //显示小数点 

	LcdWriteCom(0x87);		 //写地址 80表示初始地址
	LcdWriteData('0'+datas[4]); //显示小数点 

	 
}
/******************************************************************************* * 函 数 名 :UsartConfiguration() * 函数功能 :设置串口 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/

void UsartConfiguration()
{
	SCON=0X50;			//设置为工做方式1
	TMOD|=0X20;			//设置计数器工做方式2
	PCON|=0X80;			//波特率加倍
	TH1=0XF3;				//计数器初始值设置,注意波特率是4800的
	TL1=0XF3;
	ES=1;						//打开接收中断
	EA=1;						//打开总中断
	TR1=1;					//打开计数器
}





void connect_init()
{
    char *a="AT+CIPMUX=1\r\n";
    char *b="AT+CIPSERVER=1,8080\r\n";
    while(*a!='\0')
    {
        SBUF=*a;      //写入要发送的字符
        while(!TI);    //等待发送完成
        TI=0;          //发送
        a++;
    }
    delay(500);//这里添加延时函数,延时5ms左右,给ESP8266反应时间
    while(*b!='\0')
    {
        SBUF=*b;  
        while(!TI);    //等待发送完成
        TI=0;
        b++;
    }
}

void UART_SER (void) interrupt 4 //串行中断服务程序
{   
    char res;
    res=SBUF;         //取出接受到的数据
    RI=0;              //清除接受中断标志位
    if(res==':'||i>0)    //i是全局变量
    {
        receive[i]=res;   //receive数组也是全局变量
        i++;
        if(res=='\n')
        {
            if(receive[1]=='1')		  //添加对收到信息的处理代码 1表明打开窗帘
           {
		     if(flag==-1)     
			{
			M2PWM=1;
	       	M2B=0;
	     	M2A=1;
			delayms(1000);	   // 转动1s
		    M2PWM=0;
	     	M2B=0;
		    M2A=0;
			}
		   }
		    else if(receive[1]=='2')   //添加对收到信息的处理代码 2表明关闭窗帘
		   {
		      if(flag==-1)
			{
			 M2PWM=1;
	         M2B=1;
		     M2A=0;
			 delayms(1000);	  //转动1s
		     M2PWM=0;
		     M2B=0;
		     M2A=0;
			}
		   }
		   i=0;
        }
    }
 }

总结

这是我第一次在CSDN这样官方的IT论坛上发表本身的做品,不只是但愿能给须要学习这方面的人一些指引而且提供个人思路和想法,更是但愿这篇文章可以记录下我学习单片机的点滴,这是我学习51这么久以来最有综合性的项目,也多是我最后一个用51单片机作的项目了(真香警告),接下来就要开始苦逼的学习STM32的道路了?,文章中可能会有些缺陷或者错误,也可能会有由于我水平的缘由而作得不足的地方(即将大二的学生),欢迎大佬来指正和讨论,一块儿学习!!

最后附上所有源代码,原理图以及ESP8266WIFI模块的资料

连接:https://pan.baidu.com/s/1dJGa_3IoGPDGS44_TnPzmA 提取码:bkq1