基于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<stdio.h> 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 <=  whitenum)        {               LED_W=1;           LED_W1=1;          LED_W2=1;      }       else        {               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<=yellownum)      {           LED_Y=1;           LED_Y1=1;          LED_Y2=1;      }       else        {           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 <stdio.h>
#include <string.h>
#include <stdlib.h>#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

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

  1. 基于51单片机小板的led灯全亮全灭

    #include<reg51.h> //led灯在小板里用P0口 unsigned char i=5000;//定义一个短暂的延时 void main(){ P0=0x00; while( ...

  2. 基于51单片机六车道智能交通灯设计(仿真+源程序+PCB+论文)

    资料编号:204 功能介绍:(全套毕设资料齐全) 本设计的交通灯以十字路口为模型,在实现基本的功能前提下增加了时间及温度的液晶显示.从而还增加了路口高峰期的智能化人工管理机制. 实际生活中交通信号灯的 ...

  3. 基于51单片机多功能智能台灯设计 视力灯 坐姿矫正套件 台灯 人体感应 包括实物+电路原理图+程序+proteus仿真

    基于51单片机多功能智能台灯设计 视力灯 坐姿矫正套件 台灯 人体感应 包括实物+电路原理图+程序+proteus仿真 ID:69100646120443268太白路自信的桔梗

  4. 基于51单片机的教室智能照明控制设计

    具体实现功能 系统由STC89C52单片机+时钟芯片DS1302+液晶屏LCD1602+光敏电阻+红外对管+LED灯模块+按键模块构成. 具体功能: 1.用4个LED灯模拟教室的照明灯,人数小于10人 ...

  5. 最简单DIY基于STM32单片机的WIFI智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇:最简单DIY基于STM32F ...

  6. 基于51单片机的电动智能小车(完整论文)

    基于51单片机的电动智能小车(完整论文): 摘 要 80C51单片机是一款八位单片机,他的易用性和多功能性受到了广大使用者的好评.这里介绍的是如何用80C51单片机来实现长春工业大学的毕业设计,该设计 ...

  7. 用51单片机实现按键控制LED灯亮灭

    用51单片机实现按键控制LED灯亮灭 #include<reg51.h>//头文件 sbit LED=P2^0;//位定义LED灯 sbit k1=P3^1;//位定义按键 void de ...

  8. 基于stm32单片机的WIFI智能联网天气预报自动校时系统(源码+原理图+全套资料)

    资料编号:071 通过wifi 联网获取任何城市的时间和天气,OLED显示,城市位置可以调整, 具体功能请看演示视频  全套资料齐全: 71-基于stm32单片机的WIFI智能联网天气预报自动校时系统 ...

  9. 51单片机入门 第一篇:LED灯

    文章目录 前言 一.LED原理图 二.创建keil5工程 三.代码的编写 四.程序的烧录 总结 前言 本篇文章讲正式带大家开始学习51单片机,希望这些文章能够很好的帮助到大家学习51单片机. 一.LE ...

最新文章

  1. 如何通过终端快速删除文件和目录(bash shell)[关闭]
  2. ubuntu16.04分区
  3. Using KernelShark to analyze the real-time scheduler【转】
  4. 二叉树最近公共祖先相关题目(Leetcode题解-Python语言)
  5. CF438E:The Child and Binary Tree(生成函数)
  6. 工厂模式 构建者模式_实践中的构建者模式
  7. php默认语法,php基本语法
  8. 【MyBatis框架】查询缓存-二级缓存-整合ehcache
  9. SAP License:FICO重要概念(一)
  10. 开启Golang编程第一章
  11. Unity3d之Http通讯GET方法和POST方法
  12. NYOJ 82:迷宫寻宝(一)(BFS)
  13. 如何选择梯度下降法中的学习速率α(Gradient Descent Learning Rate Alpha)
  14. Mac电脑Docker拉取Mysql报错?no matching manifest for linux/arm64/v8 in the manifest list entries
  15. 100%解决VMware虚拟机NAT上网方式,保姆教学
  16. oracle alter命令大全
  17. Python实现百度地图、高德地图地理编码及高德地图经纬度坐标转百度地图经纬度坐标
  18. xv6操作系统中增加一个系统调用
  19. 一个完整react项目的目录结构
  20. PaddlePaddle - 人脸关键点检测课程笔记

热门文章

  1. 《白夜行》——我的雪穗
  2. vue 中遍历数组对象 存到一个新数组里
  3. php合并PDF FPDI
  4. Boson模拟Cisco配置网络
  5. 网页嵌套的视频下载方法
  6. 831003车床拨叉课程设计(拨叉831003加工工艺及钻φ22花键底孔夹具设计)(说明书 CAD图纸 SolidWorks 三维图 工序卡……)
  7. Teamcenter账号(TC账号)不够怎么办
  8. 硬核 | 50 家企业 C++ 面经分享
  9. UI界面教程:用PS设计运动app跑友圈页面
  10. PPP 模式在我国智慧城市建设领域应用与发展