用51单片机实现简单智能家居

前言

学了这么长,今天给大家分享一个小项目的雏形。这次智能家居,我们暂且实现一个智能灯。有三种控制方式的智能灯:

1、按键控制开关(单片机独立按键)
2、WiFi控制开关(ESP8266模块)
3、传感器控制开关(光敏电阻)
单片机(普中51A2)

当然还有一个必不可少的东西,液晶显示当前的状态。
开始吧!

预备知识

快速入门51单片机
快速学习51单片机中断
快速学习51单片机串口通信
以及单片机按键与液晶的使用

正文

(因为疫情原因,没开学只能用开发板)

ESP8266模块的配置

据说好多小伙伴都栽在这一步了。就目前我们这个小项目只需要大家简单配置即可。
拿到模块后我们用杜邦线连接到烧入工具上面,连接很简单。就是
TXD-RXD
RXD-TXD
VCC-VCC
GND-GND
连这四个足够了,然后插入电脑中,打开串口调试助手
设置串口调试助手的波特率为115200(因为模块初始化的波特率为这个)
1、测试模块
用串口调试助手发送AT,如果收到OK,证明模块没问题。
2、修改模块串口的波特率(因为单片机的波特率设置不了这么大,我们就设置为9600即可)
用串口调试助手发送:
AT+UART=9600,8,1,0,0
方便我们用串口通信的方式1
3、用模块连接自己家的wifi(注意此时串口调试助手的波特率记得改成9600)
AT+CWJAP=“WiFi名称”,“WiFi密码”

好了目前设置这么多就行了。

代码设计

这边我先把代码打出来,具体的说明,我会在你看完代码再进行讲解。

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit mode=P2^0;			//mode=0为按键和WiFi控制  mode=1为传感器控制
sbit S1=P1^7;
sbit S2=P1^3;
sbit light=P2^1;
sbit key1=P3^2;    //按键3
sbit key2=P3^3;		 //按键4		

sbit DIN=P3^4;
sbit CS=P3^5;
sbit DCLK=P3^6;
sbit DOUT=P3^7;

sbit EN=P2^7;
sbit RS=P2^6;
sbit lcdWR=P2^5;

uchar code table1[]="loading...";
uchar code table2[]="OK";
uchar code table3[]="status";
uchar code table4[]="Light";
uchar code table5[]="low ";
uchar code table6[]="high";
uchar code table7[]="on ";
uchar code table8[]="off";
void lcdWriteCom(uchar dat);
void lcdString(uchar *str,uint length);
/*延时ms函数*/
void delayms(uint z)
{
	uint i,j;
	for(i=z;i>0;i--)
		for(j=110;j>0;j--);
}
/*灯的开关*/
void switchLight(uchar i)
{
	if(i==1)
		light=0;
	if(i==2)
		light=1;
}
/*按键控制小灯开关*/
void keyControl(void)
{
	if(key1==0)
	{
		delayms(10);
		if(key1==0)
		{
			switchLight(1);
		}
		while(!key1);
	}
	if(key2==0)
	{
		delayms(10);
		if(key2==0)
		{
			switchLight(2);
		}
		while(!key2);
	}
}
/*光敏传感器控制灯开关*/

//AD写入操作
void adWrite(uchar dat)
{
	uint i;
	CS=0;
	DCLK=0;
	for(i=0;i<8;i++)
	{
		DIN=dat>>7;
		dat<<=1;
		DCLK=0;
		
		DCLK=1;
	}
}
//AD读取数据操作
uint adRead()
{
	uint i,dat=0;
	CS=0;
	DCLK=0;
	for(i=0;i<12;i++)
	{
		
		dat<<=1;
		DCLK=1;
		DCLK=0;
		dat|=DOUT;
		
	}
	return dat;
}
//命令转换操作
uint adReadData()		//光敏电阻为 0xa4
{
	uint i,AD_value;
	DCLK=0;
	CS=0;
	adWrite(0xa4);
	for(i=6;i>0;i--);
	DCLK=1;
	_nop_();
	_nop_();
	DCLK=0;
	_nop_();
	_nop_();
	AD_value=adRead();
	CS=1;
	return AD_value;
}
//封装开关
void adSwitch()
{
	if(adReadData()<150)
	{
		switchLight(1);
		delayms(10);
	}
	else
	{
		switchLight(2);
		delayms(10);
	}
}

/*WIFI控制小灯的亮灭*/
//初始化
void wifiInit()
{
	TMOD=0x20;		//波特率9600
	TL1=0xfd;
	TH1=0xfd;
	TR1=1;
	SM0=0;
	SM1=1;
	REN=1;
	EA=1;
	ES=1;
}
//设置WiFi打开端口号
void wifiConfig()
{
	//液晶显示正在设置
	lcdWriteCom(0x80+0x02);
	lcdString(table1,10);
	ES=0;
	TI=1;
	delayms(3000);

	printf("AT+CIPMUX=1\r\n");//开启模块的多连接功能,即设置为server
	delayms(2000);
	printf("AT+CIPSERVER=1,8080\r\n");//这里我们开放8080端口
	delayms(2000);
	while(!TI);
	TI=0;
	ES=1;
	//液晶显示设置成功
	lcdWriteCom(0x01);
	lcdWriteCom(0x80);
	lcdString(table2,2);
}

/*液晶实时状态回显*/
//液晶写命令
void lcdWriteCom(uchar dat)
{
	RS=0;
	lcdWR=0;
	P0=dat;
	delayms(5);
	EN=1;
	delayms(5);
	EN=0;
}
//液晶写数据
void lcdWriteData(uchar dat)
{
	RS=1;
	lcdWR=0;
	P0=dat;
	delayms(5);
	EN=1;
	delayms(5);
	EN=0;
}
//初始化液晶
void lcdInit()
{
	lcdWriteCom(0x38);
	lcdWriteCom(0x0c);
	lcdWriteCom(0x06);
	lcdWriteCom(0x01);
}
//字符串显示函数
void lcdString(uchar *str,uint length)
{
	uint i;
	for(i=0;i<length;i++)
	{
		lcdWriteData(str[i]);
	}
}
//光强显示
void lcdLight()
{
	lcdWriteCom(0x80+0x40);
	lcdString(table4,5);
	lcdWriteCom(0x80+0x46);
	if(adReadData()<200)
		lcdString(table5,4);
	else
		lcdString(table6,4);
}
//液晶显示灯的状态变化
void lcdStatus()
{
	lcdWriteCom(0x80);
	if(light==0)
		lcdString(table7,3);
	if(light==1)
		lcdString(table8,3);
}
/*模式设置*/
void modeConfig()
{
	if(S1==0)
	{
		delayms(10);
		if(S1==0)
		{
			mode=~mode;
		}
		while(!S1);
	}
	if(mode==1)
	{
		adSwitch();
	}
}
/*主函数*/
void main()
{
	wifiInit();
	lcdInit();
	wifiConfig();
	mode=0;
	S1=1;
	S2=0;
	while(1)
	{
		lcdStatus();
		lcdLight();
		keyControl();
	//	wifiSwitch();
		modeConfig();
	}
}
//WiFi封装开关
void wifi() interrupt 4
{
	uchar a;
	a=SBUF;
	if(a=='1')
		switchLight(1);
	if(a=='2')
		switchLight(2);
	RI=0;
}

好的,代码大概两百多行。以下我给大家讲一下说明书。(啧)

我们的小灯是用P21这个灯来模拟的。(当然我接了继电器,接不接都一样)

两种大的模式(模式的选择是用矩阵按键进行选择)
mode0:可以用WiFi控制灯的开关以及WiFi控制灯的开关
mode1:用光敏电阻进行控制灯的开关(本来想加人体红外模块的,可是那个模块坏了–)
这里用两种方式,因为光敏电阻和强制性的开关冲突
按键控制开关
在mode0下,我们用两个按键控制灯的打开与关闭,分别是K3和K4(K1和K2与串口通信冲突)
WiFi控制开关
在mode0中,这边我们给单片机发送1即打开灯,发送2即关闭灯(这里我们是用手机上的一个别人做好的软件,目前能力有限还开发不出来app)
光敏电阻控制开关
在mode1中,如果灯光的亮度过暗,即打开电灯,反之关闭电灯(这里我们设置了光敏电阻的参数,让其小于150即打开)
液晶实时显示状态
当我们开机的时候,会有一个loading…的字符显示,证明在初始化(初始化的过程就是创建为TCPsever端以及打开可用的端口)
正在初始化(这个过程大概会初始化5秒左右)
之后会显示目前灯的状态、目前光线亮度以及模式
在这里插入图片描述目前程序已经测试过了,没有问题可以正常工作。
这里大家要注意一个事情,在你连接WIFI的时候,务必要与WiFi模块连接同一个模块,让其处于同一个网络号,不然不能通信。至于为什么这边就不多说了,不然又要写一篇

总结

经过前一阶段的学习,以及这个小项目的练手,估计大家对单片机的基本操作已经熟悉了。现在可以回过头去读一些以前你看不懂的书了。
这个项目还只是个雏形,等开学后估计会进一步完善,加上语音模块之类的。(目前由于没开学手上的资源仅有这么多)
关于项目的更新,有兴趣的可以在我的github上面看:链接在这
(可恶的疫情,开学就要升大二了。上学不过三个月)


受惠于互联网,感恩于互联网

  • 14
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值