基于51单片机的wifi智能led灯的毕业设计

您所在的位置:网站首页 物联网智能灯控 基于51单片机的wifi智能led灯的毕业设计

基于51单片机的wifi智能led灯的毕业设计

2024-07-14 15:52:58| 来源: 网络整理| 查看: 265

基于51单片机的wifi智能led灯的毕业设计 摘要

      系统基于STC89C52RC单片机设计,拥有自动与手动两种模式,自动模式下可以过热释红外传感器检测是否有人,采用光敏电阻构成的电路检测环境光的强度,从而自动实现灯的自动开启和关闭;手动模式下可以使用wifi连接手机,通过手机app手动控制不同灯的开启和关闭并可控制各LED灯的光亮度,并采用可移动充电式电源供电,满足不同场景的需求。系统简单易行、控制方便,可用于传统照明的节能改造。

设计思路

      本系统基于STC89C52单片机设计,可实现灯具的自动控制;同时,结合esp8266wifi模块通过安卓手机端app与wifi模块进行数据通信,实现对被控对象的无线连接手动控制。主要功能如下:

(1)自动模式: 通过光敏电阻和热释红外传感器分别自动检测光的强弱和是否有人,室内无人或者光照充足时自动灭灯,灭灯时间延时一分钟;有人到且光照不足时自动开灯;该模式即节约了人力资源又节约了大量电能。 (2)手动模式:开启手机wifi,通过手机APP手动控制灯的开启和关闭,使用手机轻松控制灯的开关,方便快捷。

图1 系统框图 在这里插入图片描述 在这里插入图片描述

硬件设计 wifi模块

      wifi模块采用esp8266,对wifi模块进行配置就需要使用到AT指令集。其最基础的一些AT指令集在下面贴出,部分会在代码中使用到。

WIFIAT+CIPMUX=1AT+CIPSERVER=1,80 //修改端口号 AT+CWMODE=3 //设置模式 AT+RST //重启 AT+CWJAP="WiFixdd","xiaojieying" //搜索并连接路由器 AT+CIPMODE=1 //透传 AT+CIPMUX=0 //单路模式 AT+CIPSTART="TCP","172.29.242.2",8080 //连接手机端 AT+CIPSEND //进入透传

若想深入研究自行找资料学习AT指令集。

热释电传感器

      HC-SR501 人体红外传感器模块是基于红外技术的自动控制模块,它可以检测人或某些动物发出的红外辐射并输出电信号我们使用的 。 在这里插入图片描述 在这里插入图片描述

电源模块

      电源模块采用18650可充电电池,由于其供电电压为3.6V,不能很好的为电路工作,所以我们通过升压模块对其进行电压放大,以达到标准供电电压5V。并能通过变压充电模块为18650电池充电。 在这里插入图片描述

驱动电路

      由于52单片机的IO口驱动能力较弱,无法满足大型LED灯的需要,所以我们在这里通过三极管进行电流放大,该驱动电路通过电阻对单片机IO口进行降压,使得三极管得以导通,并对单片机IO口电流进行放大,以达到驱动该大型灯泡的能力,并给每一个LED灯串联一个限流电阻,已达到保护LED灯延长使用寿命的作用。该电路共使用六个大型LED灯照明,三黄三白,不同颜色交替摆放,已保证单种颜色灯光的照明范围。 在这里插入图片描述 要注意的是实物硬件电路板对led灯的一个布局,以及合理跳线的一个问题。

代码实施

      程序主要模块是通过单片机串口与蓝牙进行通信。由于STC89c52没有独立的波特率发生器,所以我们这里将定时计数器T1改装成波特率发生器,产生9600的标准波特率,并通过串口中断函数对读取数据进行接收,并将串口中断优先级调到最高。 在这里插入图片描述       下面是手机APP与单片机的简单通信协议,创建单独协议的目的是为了对以后项目扩展,技术升级留下足够的预留空间,并可以保证产品的加密安全性。 在这里插入图片描述       通过对程序的算法设计,该智能灯泡可达到黑夜可自动控制,有人经过则自动开起,并保持最大可调时间10分钟后自动熄灭。通过手机APP控制LED的开关以及亮度调节,若夜晚通过手机APP开起灯光,人经过后无需手机关闭即可自动关闭,以防止由于忘关造成的电力浪费。以下是主程序流程图。 在这里插入图片描述 main.c

#include "reg52.h" #include"uart.h" #include"led.h" #include sbit MAN=P1^4; int main() { unsigned char dat=0; NewLineReceived = 0; MAN=1; ColorLED_Init(); //LED灯初始化 Serial_Init(); //串口初始化 ms_delay(1000); WIFI_Init(); //WIFI模块初始化 timer0_init(); //定时计数器零初始化 color_led_pwm(0, 0); while(1) { if(MAN==0) { color_led_pwm(255, 255); while(MAN==0) ; color_led_pwm(0, 0); } if(NewLineReceived == 1) { uart_send_string("Init OK!"); serial_led();//调用串口解析函数 NewLineReceived = 0; } } }

led.c

#include "reg52.h" sbit LED_W = P1^0; sbit LED_W1=P1^1; sbit LED_W2=P1^2; sbit LED_Y = P1^5; sbit LED_Y1 = P1^6; sbit LED_Y2 = P1^7; unsigned char whitenum=0; unsigned char yellownum=0; unsigned char ledWnum=0; unsigned char ledYnum=0; void ColorLED_Init() { LED_W = 1; LED_W1 = 1; LED_W2 = 1; LED_Y = 1; LED_Y1 = 1; LED_Y2 = 1;} void color_led_pwm(unsigned char v_iwhite, unsigned char v_iyellow)//点亮相应颜色的灯 { whitenum = v_iwhite; yellownum = v_iyellow; } /*** Function ledRPwmWrite* @author Danny* @date 2017.08.16* @brief LED_R产生pwm* @param void* @retval void* @par History 无*/ void ledWPwmWrite() { if((whitenum != 0) && (whitenum!=255)) { if(ledWnum LED_W=0; LED_W1=0; LED_W2=0; } } else if(whitenum==0) { LED_W=0; LED_W1=0; LED_W2=0; } else if(whitenum==255) { LED_W=1; LED_W1=1; LED_W2=1; }} /*** Function ledGPwmWrite* @author Danny* @date 2017.08.16* @brief LED_G产生pwm* @param void* @retval void* @par History 无*/ void ledYPwmWrite() { if((yellownum != 0)&&(yellownum!=255)) { if(ledYnum LED_Y=0; LED_Y1=0; LED_Y2=0; } } else if(yellownum==0) { LED_Y=0; LED_Y1=0; LED_Y2=0; } else if(yellownum==255) { LED_Y=1; LED_Y1=1; LED_Y2=1; }} void Update_ColorPWM() { ledWPwmWrite(); ledYPwmWrite();} void timer0_init() { TMOD|=0X01; //定时器T0工作方式1,定时器T1工作方式2 TH0=0XFF; //100us定时,装入初值 TL0=0XA4; TR0=1; //启动T0工作 ET0=1; //允许T0中断 EA =1; //开总中断 PT0=0; } void timer0() interrupt 1 { TH0=0XFF; //50us定时,装入初值 TL0=0XD2; //控制pwmled ledWnum++; ledYnum++; Update_ColorPWM(); }

uart.c

#include "reg52.h" #include #include #include #include"led.h" bit NewLineReceived = 0; //串口接收完成标志位bit StartBit = 0; //协议开始标志int g_num=0; //定义变量int g_packnum=0;char InputString[50] = {0}; //用来储存接收到的内容 /*** Function StringFind* @author Danny* @date 2017.08.16 * @brief 字符串查找* @param[in] pSrc:源字符串; pDst:查找的字符串; v_iStartPos:源字符串起始位置* @param[out] void* @retval void* @par History 无*/int StringFind(const char *pSrc, const char *pDst, int v_iStartPos) { int i, j; for (i = v_iStartPos; pSrc[i]!='\0'; i++) //判断是否到了源字符串的结束符 { if(pSrc[i]!=pDst[0]) //与所要查找的字符串的第一个字节作比较 continue; j = 0; while(pDst[j] !='\0' && pSrc[i+j]!='\0') //判断是否到了所要查找字符串以及源字符串的结束符 { j++; if(pDst[j]!=pSrc[i+j]) break; } if(pDst[j]=='\0') //判断是否到了所要查找字符串的结束符 return i; } return -1; } /*** Function uart_send_byte* @author Danny* @date 2017.08.16* @brief 串口发送一个字符* @param[in] data:字符* @param[out] void* @retval void* @par History 无*/void uart_send_byte(unsigned char dat){ SBUF = dat; //把数据放到SBUF中 while(TI == 0); //未发送完毕就等待 TI=0; //发送完毕后,要把TI重置0} /*** Function uart_send_string* @author Danny* @date 2017.08.16* @brief 串口发送一个字符串* @param[in] void* @param[out] void* @retval void* @par History 无*/void uart_send_string(unsigned char *str){ while(*str != '\0') //判断指针str是否指向字符串的末尾 { uart_send_byte(*str); //往串口上发送字符串 str++; //指针自增,按照一个字节一个字节发送字符串 }} /*** Function Serial_Init* @author Danny* @date 2017.08.16* @brief 串口初始化函数* @param void* @retval void* @par History 无*/void Serial_Init(){ SCON=0x50; //[bit6:5]SM1 SM2 = 1 0;[bit4]REN=1 /* AUXR=0x11; //[bit4]BRTR=1,允许独立波特率发生器运行;[bit0]SIBRS=1, //独立波特率作为串口1的波特率发生器,此时定时器1释放 BRT=0XFD; //独特波特率发生器定时器(产生波特率9600) */ TMOD|=0X20; PCON=0; TH1=TL1=0XFD; TR1=1; ES=1; //开串口中断 EA=1; //开总中断 PS=1;} /*** Function serial_IRQHandler* @author Danny* @date 2017.08.16* @brief 串口中断处理接收串口数据函数* @param void* @retval void* @par History 无*/void serial_IRQHandler(void) interrupt 4 using 1 //串行口中断,第一组寄存器{ unsigned char date = 0; if(RI) { RI=0; //清除接收中断标志位 date=SBUF; //串行口接收到的数据 if(date == '$') { StartBit = 1; //协议开始 g_num = 0; } if(StartBit == 1) { InputString[g_num]=date; //将接收到的数据存储到定义的数组中 } if(StartBit == 1 && date == '#') { NewLineReceived = 1; //串口接收完成标志 StartBit = 0; //协议关闭 g_packnum = g_num; } g_num++; //g_num自增 if(g_num >= 80) { g_num=0; //将g_num清零 StartBit=0; NewLineReceived=0; //串口接收完成标志 } }}/******************************************************************函 数: void ms_delay(int t)功 能: 毫秒级延时参 数: 无返回值: 无*******************************************************************/void ms_delay(int t) { int i,j; for(i=t;i>0;i--) for(j=110;j>0;j--); }/******************************************************************函 数: void WIFI_Init(void)功 能: wifi初始化(名字:esp8266;密码:1234567890)参 数: 无返回值: 无*******************************************************************/ void WIFI_Init(void) { ES = 0; TI = 1; printf("AT+RST\r\n"); ms_delay(1000) ; printf("AT+CWMODE=3\r\n"); ms_delay(1000) ; printf("AT+CIPMUX=1\r\n"); ms_delay(1000) ; printf("AT+CIPSERVER=1,8080\r\n"); ms_delay(1000) ;printf("AT+CIOBAUD=9600\r\n"); // 设置与单片机一致的波特率 ms_delay(1000) ; while(!TI); TI = 0; ES = 1;} /*void WIFI_Init(void) { ES = 0; TI = 1; uart_send_string("AT+RST\r\n"); ms_delay(1000) ; uart_send_string("AT+CWMODE=3\r\n"); ms_delay(1000) ; uart_send_string("AT+CIPMUX=1\r\n"); ms_delay(1000) ; uart_send_string("AT+CIPSERVER=1,8080\r\n"); ms_delay(1000) ;uart_send_string("AT+CIOBAUD=9600\r\n"); // 设置与单片机一致的波特率 ms_delay(1000) ; while(!TI); TI = 0; ES = 1;} */void serial_led(){ //解析蓝牙APP发来的灯控信息 //如:$JC,CLW255,CLY000# 亮白灯 if (StringFind((const char *)InputString, (const char *)"CLW", 0) > 0) //判断是否查找到了字符串"CLW" { int m_kp, i, ii, white, yellow; //定义变量 char m_skp[5] = {0}; //寻找以CLW开头,,结束中间的字符 //定义数组存放数据 i = StringFind((const char *)InputString, (const char *)"CLW", 0); //查找到字符串"CLW"的位置赋值给i ii = StringFind((const char *)InputString, (const char *)",", i); //查找到字符串","的位置赋值给ii if (ii > i) //判断ii与i的关系大小 { memcpy(m_skp, InputString + i + 3, ii - i -3); //从InputString + i + 3所指的内存地址的起始位置开始拷贝(ii-i-3)个字节到m_skp所指的内存地址的起始位置中 m_kp = atoi(m_skp); //将找到的字符串m_skp转换成整形数赋值给m_kp white = m_kp; } //寻找以CLY开头,#结束中间的字符 i = StringFind((const char *)InputString, (const char *)"CLY", 0); //查找到字符串"CLY"的位置赋值给i ii = StringFind((const char *)InputString, (const char *)"#", i); //查找到字符串","的位置赋值给ii if (ii > i) //判断ii与i的关系大小 { memset(m_skp, 0x00, sizeof(m_skp)); //清空m_skp中的数据 memcpy(m_skp, InputString + i + 3, ii - i -3); //从InputString + i + 3所指的内存地址的起始位置开始拷贝(ii-i-3)个字节到m_skp所指的内存地址的起始位置中 m_kp = atoi(m_skp); //将找到的字符串m_skp转换成整形数赋值给m_kp yellow = m_kp; //sprintf(ReturnTemp, "%d", green); //uart_send_string(ReturnTemp); color_led_pwm(white, yellow); //点亮相应颜色的灯 NewLineReceived = 0; memset(InputString, 0x00, sizeof(InputString)); //清空串口数据 return; } } if (StringFind((const char *)InputString, (const char *)"JC", 0) == -1 ) //判断是否查找到了字符串"4WD" { //点灯判断 if (InputString[1] == 'W') //白灯 { if(InputString[2]=='1') color_led_pwm(255, 0); if(InputString[2]=='0') color_led_pwm(0, 0); } else if (InputString[1] == 'Y') //黄灯 { if(InputString[2]=='1') color_led_pwm(0, 255); if(InputString[2]=='0') color_led_pwm(0, 0); } else if (InputString[1] == 'O') //全部灯 { if(InputString[2]=='1') color_led_pwm(255,255); if(InputString[2]=='0') color_led_pwm(0, 0); } } }

由于格式问题,代码格式是乱的,可自行整理,并添加.h文件,或通过下方链接下载。

手机APP程序

      可自行制作或下载第三方软件WiFi调试助手。 凭借其开放性的巨大优势,安卓平台在设备开发应用中广受欢迎。安卓平台允许开发者根据自己的喜好和应用需求,设计出具有不同特色的实用软件。同时,安卓平台还能够适配多种硬件开发平台,对于硬件开发门槛要求低,极大地方便了用户对其进行相关的开发研究。此外,凭借其巨大的优势,安卓平台在当前开发平台领域中呈现逐年上升的趋势。因此在本设计中采用安卓平台进行本项目的设计开发。

注:需要源文件请到我个人主页下载,代码仅供参考。

下载链接://download.csdn.net/download/weixin_44313435/12152854



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭