找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16648|回复: 19
打印 上一主题 下一主题
收起左侧

可用手机APP控制的智能插座制作 附单片机源码

  [复制链接]
跳转到指定楼层
楼主
1.作品的整机外观图片或焊接组装好的PCBA图片;
智能插座实物图:

手机APP:

2.作品的研究背景、目的和功能、市场应用前景;
随着科技的不断进步,各种各样的电子产品已经慢慢进入到了我们的日常生活中,由于人们的不合理的使用,经常导致电能的无故浪费。然而在当今这个社会,人口数量的不断增加,再生能源的不断减少,全球温室效应日益严重,节能减排尤为重要。为了解决这样一对矛盾,我们了解到,越来越多的产品有了待机功能,如电视机,电脑,冰箱,空调等家用电器。据调查,我国城市家庭的平均待机能耗,相当于每个家庭每天都在亮着一盏15瓦到30瓦的长明灯。据测算,家电待机能耗占到中国家庭电力消耗的10%以上。而正是由于这种长期的待机状态,使得插座的负荷也越来越大,带来了非常严重的安全隐患。故需要一款能够控制使用时间的插座来解决这个问题,这款插座也可以由此走进千家万户!

3.趣味性
    用户再通过手机APP控制插座时,可通过插座中央的喜趣表情判断插座状态,给用户在使用的过程中带来些许的乐趣

二、系统构架图

三、硬件部分的描述
1.附上原理图&PCB实物图的图片或者源文件(官方建议大家尽量用源文件上传),如果是图片,请确保图片是清晰可辨的;

2.用文字把该作品的实现原理、系统的工作过程大致讲解一下。

该系统采用51单片机STC89C52在Keil开发平台上通过C语言编程控制继电器的通、断来实现控制插座的通、断电,而继电器的通、断由定时组别确定。在定时范围内继电器导通,否则断开。并用LCD1602显示出时钟及定时时间等信息。当时钟走到定时开始时间时,继电器接通,插座给负载供电;时钟走到定时结束时间时,继电器断开,插座停止给负载供电。
1.实现功能
系统总体设计主要实现以下功能:
(1)时间预设功能:设置预设时间,控制继电器各个时间段的工作状态。
(2)数据存储功能:将数据存储在外部储存芯片中,防止单片机意外掉电数据清零。
(3)时间温度功能:实时显示环境温度和时间。
(4)蓝牙遥控功能:单片机通过蓝牙模块与手机进行通讯,用户通过手机APP控制单片机工作。


四、材料清单(BOM列表)

(1)单片机STC89C52:CPU
(2)LCD1602液晶显示屏:专门用来显示字母、数字、符号等的点阵型液晶模块
(3)DS1302时钟模块:本设计的时间预设模式需要精准时间来控制继电器的动作,为为保证单片机掉电后时间信号依旧继续工作,故采用DS1302外部时间计时。DS1302一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能
(4)继电器模块:该系统通过单片机控制继电器转而控制插座的通断。
(5)AT24C02存储模块:AT24C02作为外部存储芯片,将数据实时储存,防止单片机意外掉电导致数据清零
(6)BT-08B蓝牙模块:通过此模块实现单片机与手机的通信
(7)DS18B20温度模块:它具有微型化,低功耗,高性能,抗干扰能力强,易配微处理器等优点,可直接将温度转化成数字信号处理器处理。


五、软件部分的描述(选填)

设计思想:将该项目每一个功能独立成每一模块,然后每一个模块单独开发,并独立测试。

(1)主程序:主要是在单片机的控制下,建立人机操作界面,对设定时间进行储存,对相关功能进行设置,驱动液晶显示出相关信息,并通过判断定时时间,控制继电器的通、断,从而达到控制插座的通、断电。
主程序流程图
(2) AT24C02程序:包括I2C总线程序和AT24C02写入和读取程序

写入流程图和读取流程图


(3)DS1302程序:包含写操作、读操作、初始化操作和读取时间操作函数


读取流程图和写入流程图

(4)LCD1602液晶程序:包含延时函数、写入命令子函数、写入数据子函数、初始化函数


  写指令和写数据流程图



(5)BT-08B蓝牙模块程序:包含串口初始化函数和延时函数

蓝牙串口控制流程图


(6)DS18B20温度模块程序:包含延时函数、初始化函数、写数据函数、读数据函数、转换温度函数、发送读取温度命令函数和读取温度函数
  
温度读取流程图


单片机源程序如下:
  1. #include <reg52.h>                        
  2. #include "ds1302.h"
  3. #include "temp.h"        
  4. #include "lcd.h"
  5. #include "BT.h"
  6. #include "i2c.h"
  7. #define GPIO_KEY P1

  8. sbit relay=P2^3;        //继电器信号输入管脚定义
  9. sbit beep=P1^5;                //定义蜂鸣器

  10. typedef unsigned int u16;          //对数据类型进行声明定义
  11. typedef unsigned char u8;

  12. u8 sign=0;//声音判断标志        
  13. u8 h,m,s;//时,分,秒
  14. u8 KeyValue=16;        //用来存放读取到的键值
  15. u8 tempData[3];//接收温度数据
  16. u8 dateData[8];        //接收日期数据
  17. u8 timingData[8];//接收定时数据        
  18. u8 timeData[8];//接收时间数据
  19.                               
  20. /*******************************************************************************
  21. * 函 数 名         : delay()
  22. * 函数功能                   : 延时函数
  23. * 输    入         : i
  24. * 输    出         : 无
  25. *******************************************************************************/
  26. void delay(u16 i)
  27. {
  28.            while(i--);
  29. }
  30. /*******************************************************************************
  31. * 函 数 名         : sound()
  32. * 函数功能                   : 声音函数
  33. * 输    入         : 无
  34. * 输    出         : 无
  35. *******************************************************************************/
  36. void sound()
  37. {
  38.         u8 i=100;
  39.         while(i--)
  40.         {
  41.                 beep=~beep;
  42.                 delay(30);
  43.                 beep=~beep;
  44.                 delay(10);        
  45.         }
  46. }

  47. /*******************************************************************************
  48. * 函 数 名         : Timer0Init()
  49. * 函数功能                   : 定时器0初始化
  50. * 输    入         : 无
  51. * 输    出         : 无
  52. *******************************************************************************/
  53. void Timer0Init()
  54. {
  55.         TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。                                    
  56.         TH0=0XFC;        //给定时器赋初值,定时1ms
  57.         TL0=0X18;        
  58.         ET0=1;//打开定时器0中断允许
  59.         EA=1;//打开总中断
  60.         TR0=1;//打开定时器                                
  61. }
  62. /*******************************************************************************
  63. * 函 数 名         : KeyChoose()
  64. * 函数功能                   : 按键选择
  65. * 输    入         : 无
  66. * 输    出         : 无
  67. *******************************************************************************/
  68. void KeyChoose()
  69. {
  70.         if(sign!=switch_pattern)        //判断声音标志sign是否与switch_pattern相等,不相等则表明开关状态有变化,输出提示音,并令sign=switch_pattern
  71.         {
  72.                 sound();
  73.                 sound();
  74.                 sign=switch_pattern;
  75.         }
  76.    switch(KeyValue)
  77.         {
  78.                 case 0:
  79.                         sound();
  80.                         sound();
  81.                         if(switch_pattern==1)
  82.                          switch_pattern=0;
  83.                     else
  84.                          switch_pattern=1;
  85.                     timing_pattern=2;//重置非定时状态
  86.                     KeyValue=16;//防止未按键依旧进入该条选择语句,下同
  87.                         break;
  88.                 case 1:
  89.                         sound();
  90.                         sound();
  91.                         switch_pattern=1;
  92.                         timing_pattern=0;//定时关闭;
  93.                         KeyValue=16;
  94.                         break;
  95.                 case 2:
  96.                         sound();
  97.                         sound();
  98.                         switch_pattern=0;
  99.                         timing_pattern=1;//定时开启;
  100.                         KeyValue=16;
  101.                         break;
  102.                 case 3:
  103.                         sound();
  104.                         sound();
  105.                         h=0;  //将其他两位置为0,下同
  106.                         s=0;
  107.                         m=1;// 定时1分钟,下同
  108.                         KeyValue=16;
  109.                         break;           
  110.                 case 4:
  111.                         sound();
  112.                         sound();
  113.                         h=0;
  114.                         s=0;
  115.                         m=30;
  116.                         KeyValue=16;
  117.                         break;
  118.                 case 5:
  119.                         sound();
  120.                         sound();
  121.                         m=0;
  122.                         s=0;
  123.                         h=1;
  124.                         KeyValue=16;
  125.                         break;
  126.                 case 6:
  127.                         sound();
  128.                         sound();
  129.                     m=0;
  130.                         s=0;
  131.                         h=2;
  132.                         KeyValue=16;
  133.                         break;
  134.                 case 7:
  135.                         sound();
  136.                         sound();
  137.                         m=0;
  138.                         s=0;
  139.                         h=3;
  140.                         KeyValue=16;
  141.                         break;
  142.                 case 8:
  143.                         sound();
  144.                         sound();
  145.                         m=0;
  146.                         s=0;
  147.                         h=4;
  148.                         KeyValue=16;
  149.                         break;
  150.                 case 9:
  151.                         sound();
  152.                         sound();
  153.                         m=0;
  154.                         s=0;
  155.                         h=6;
  156.                         KeyValue=16;
  157.                         break;
  158.                 case 10:
  159.                         sound();
  160.                         sound();
  161.                         m=0;
  162.                         s=0;
  163.                         h=8;
  164.                         KeyValue=16;
  165.                         break;
  166.                 case 11:
  167.                         sound();
  168.                         sound();
  169.                         m=0;
  170.                         s=0;
  171.                         h=10;
  172.                         KeyValue=16;
  173.                         break;
  174.                 case 12:
  175.                         sound();
  176.                 sound();
  177.                         m=0;
  178.                         s=0;
  179.                         h=12;
  180.                         KeyValue=16;
  181.                         break;
  182.                 case 13:
  183.                         sound();
  184.                         sound();
  185.                         m=0;
  186.                         s=0;
  187.                         h=14;
  188.                         KeyValue=16;
  189.                         break;
  190.                 case 14:
  191.                         sound();
  192.                         sound();
  193.                         m=0;
  194.                         s=0;
  195.                         h=20;
  196.                         KeyValue=16;
  197.                         break;
  198.                 case 15:
  199.                         sound();
  200.                         sound();        
  201.                         m=0;
  202.                         s=0;
  203.                         h=24;
  204.                         KeyValue=16;
  205.                         break;
  206.                         
  207.         }

  208. }
  209. /*******************************************************************************
  210. * 函 数 名         : Timer0()
  211. * 函数功能                   : 实现1s定时操作
  212. * 输    入         : 无
  213. * 输    出         : 无
  214. *******************************************************************************/
  215. void Timer0() interrupt 1
  216. {
  217.         static u16 i;

  218.         TH0=0XFC;        //给定时器赋初值,定时1ms
  219.         TL0=0X18;               
  220.         i++;
  221.         if(i>=1000)//定时一秒则
  222.         {
  223.            i=0;
  224.            if((h||m||s)&&timing_pattern<=1)//如果定时没有结束且为定时状态,则定时继续
  225.                 {
  226.                    if(s==0)
  227.                    {
  228.                           s=59;
  229.                           if(m==0)
  230.                           {
  231.                                   m=59;
  232.                                 h--;
  233.                           }
  234.                           else
  235.                           m--;
  236.                    }
  237.                    else
  238.                    s--;
  239.                if(s==0&&m==0&&h==0)//如果定时结束
  240.                    {
  241.                       relay=~relay;        
  242.                           if(switch_pattern==0)
  243.                                   switch_pattern=1;
  244.                           else
  245.                                 switch_pattern=0;                                          
  246.                           timing_pattern=2;//重置为非定时状态
  247.                           sound();
  248.                           sound();
  249.                           sound();
  250.                           sound();                                          
  251.                }
  252.                 }
  253.         }
  254.         if(switch_pattern!=0)//如果状态为开则relay=0;
  255.         {        
  256.                 relay=0;
  257.                 while(!switch_pattern);//判断开关是否切换
  258.         }
  259.         if(!switch_pattern)        //如果状态为关则relay=1;
  260.         {               
  261.                 relay=1;
  262.                 while(switch_pattern);//判断开关是否切换        
  263.         }
  264.         if(timing_pattern==2)//非定时状态时将时间重置为00:00:00
  265.         {
  266.                    h=0;
  267.             m=0;
  268.             s=0;
  269.         }
  270.         if(timing_pattern<=1&&timing_time!=0)//获取蓝牙传入的时间
  271.         {
  272.                 sound();
  273.                 sound();
  274.                    h=timing_time-1;
  275.                 m=59;
  276.                 s=59;
  277.                 timing_time=0;
  278.         }
  279. }


  280. /*******************************************************************************
  281. * 函 数 名         : KeyDown()
  282. * 函数功能                   : 按键判断函数
  283. * 输    入         : 无
  284. * 输    出         : 无
  285. *******************************************************************************/
  286. void KeyDown(void)
  287. {
  288.         char a=0;
  289.         GPIO_KEY=0x0f;
  290.         if(GPIO_KEY!=0x0f)//读取按键是否按下
  291.         {
  292.                 Delay1ms(10);//延时10ms进行消抖
  293.                 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
  294.                 {        
  295.                         //测试列
  296.                         GPIO_KEY=0X0F;
  297.                         switch(GPIO_KEY)
  298.                         {
  299.                                 case(0x07):        KeyValue=0;break;
  300.                                 case(0X0b):        KeyValue=1;break;
  301.                                 case(0X0d):        KeyValue=2;break;
  302.                                 case(0X0e): KeyValue=3;break;
  303.                         }
  304.                         //测试行
  305.                         GPIO_KEY=0XF0;
  306.                         switch(GPIO_KEY)
  307.                         {
  308.                                 case(0x70):        KeyValue=KeyValue;break;
  309.                                 case(0Xb0):        KeyValue=KeyValue+4;break;
  310.                                 case(0Xd0):        KeyValue=KeyValue+8;break;
  311.                                 case(0Xe0): KeyValue=KeyValue+12;break;
  312.                         }
  313.                         while((a<50)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
  314.                         {
  315.                                 Delay1ms(10);
  316.                                 a++;
  317.                         }
  318.                 }
  319.         }

  320. }

  321. /*******************************************************************************
  322. * 函 数 名         : datapros_temp()
  323. * 函数功能                   : 温度读取处理函数
  324. * 输    入         : temp
  325. * 输    出         : 无
  326. *******************************************************************************/
  327.   
  328. void datapros_temp(int temp)         
  329. {
  330.            float tp;  
  331.         if(temp<0)                                //当温度值为负数
  332.           {
  333.                 tempData[0]='-';
  334.                 temp=temp-1;
  335.                 temp=~temp;
  336.                 tp=temp;
  337.                 temp=tp*0.0625*100+0.5;        
  338.           }
  339.          else                                        //当温度为正数
  340.           {        
  341.                 tempData[0]='+';               
  342.                 tp=temp;
  343.                 temp=tp*0.0625*100+0.5;        
  344.         }
  345.         tempData[1] =temp/1000+'0';
  346.         tempData[2] =temp%1000/100+'0';
  347. }
  348. /*******************************************************************************
  349. * 函 数 名         : datapros_time()
  350. * 函数功能                   : 时间读取处理函数
  351. * 输    入         : 无
  352. * 输    出         : 无
  353. *******************************************************************************/
  354. void datapros_time()         
  355. {
  356.            Ds1302ReadTime();
  357.         timingData[0] = h/10+'0';                                //定时-时
  358.         timingData[1] = h%10+'0';                                          
  359.         timingData[2] = ':';
  360.         timingData[3] = m/10+'0';                                //定时-分
  361.         timingData[4] = m%10+'0';        
  362.         timingData[5] = ':';
  363.         timingData[6] = s/10+'0';                                //定时-秒
  364.         timingData[7] =s%10+'0';
  365.         dateData[0]= (TIME[6]/16)+'0';                                //年
  366.         dateData[1]=(TIME[6]&0x0f)+'0';
  367.         dateData[2]='-';
  368.         dateData[3]= (TIME[4]/16)+'0';                                  //月                                
  369.         dateData[4]=(TIME[4]&0x0f)+'0';
  370.         dateData[5]='-';
  371.         dateData[6]= (TIME[3]/16)+'0';                                  //日                                
  372.         dateData[7]=(TIME[3]&0x0f)+'0';
  373.         timeData[0]=(TIME[2]/16)+'0';                                //时
  374.         timeData[1]=(TIME[2]&0x0f)+'0';
  375.         timeData[2]=':';
  376.         timeData[3]=(TIME[1]/16)+'0';                                //分
  377.         timeData[4]=(TIME[1]&0x0f)+'0';
  378.         timeData[5]=':';
  379.         timeData[6]=(TIME[0]/16)+'0';                                //秒
  380.         timeData[7]=(TIME[0]&0x0f)+'0';

  381. }


  382. /*******************************************************************************
  383. * 函 数 名         : lcdDisplay()
  384. * 函数功能                   : 显示函数
  385. * 输    入         : 无
  386. * 输    出         : 无
  387. *******************************************************************************/
  388. void lcdDisplay()
  389. {
  390.         u8 i;
  391.         LcdWriteCom(0x80);//从第一行开始写入        
  392.         LcdWriteData('2');
  393.         LcdWriteData('0');
  394.     for(i=0;i<8;i++)                 //显示日期
  395.         {
  396.                  LcdWriteData(dateData[i]);
  397.         }
  398.         LcdWriteData(' ');
  399.         LcdWriteData(' ');
  400.         if(switch_pattern==0)//显示开关状态
  401.         {
  402.                 LcdWriteData('O');
  403.                 LcdWriteData('F');
  404.                 LcdWriteData('F');
  405.                 LcdWriteData(' ');
  406.         }
  407.         else
  408.         {
  409.                 LcdWriteData('O');
  410.                 LcdWriteData('N');
  411.                 LcdWriteData(' ');
  412.                 LcdWriteData(' ');
  413.         }
  414.         LcdWriteCom(0x80+0x40);        //换到lcd第二行开头
  415.         for(i=0;i<3;i++)                //显示温度
  416.         {
  417.                  LcdWriteData(tempData[i]);
  418.         }
  419.         LcdWriteData(' ');
  420.         LcdWriteData(' ');
  421.         LcdWriteData(' ');
  422.         if(timing_pattern<2)        //判断是否是定时状态。timing_pattern<2则是非定时状态,显示时间信息;否则显示定时信息                                                
  423.                 for(i=0;i<8;i++)
  424.                 {        
  425.                         LcdWriteData(timingData[i]);
  426.                 }
  427.         else
  428.                 for(i=0;i<8;i++)
  429.                 {        
  430.                          LcdWriteData(timeData[i]);
  431.                 }
  432.         LcdWriteData(' ');
  433.         LcdWriteData(' ');
  434.         LcdWriteCom(0x80);        
  435. }
  436. /*******************************************************************************
  437. * 函 数 名         : save_write()
  438. * 函数功能                   : 将定时数据存储在At24c02中
  439. * 输    入         : 无
  440. * 输    出         : 无
  441. * 备    注                     :要注意每写入一次,应有一段延时。
  442. *******************************************************************************/                  
  443. void save_write()
  444. {                                   
  445.      At24c02Write(6,timing_pattern);
  446.          Delay1ms(2);
  447.          At24c02Write(5,switch_pattern);
  448.          Delay1ms(2);
  449. ……………………

  450. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
单片机源代码.rar (83.06 KB, 下载次数: 202)
蓝牙开关app.rar (362.22 KB, 下载次数: 188)



评分

参与人数 3黑币 +79 收起 理由
lzp0425 + 8 绝世好帖!
kevin666999 + 21 共享资料的黑币奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏19 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:146874 发表于 2018-8-20 08:52 | 只看该作者
谢谢楼主分享  
回复

使用道具 举报

板凳
ID:384558 发表于 2018-8-22 11:01 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

地板
ID:392360 发表于 2018-9-1 21:34 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

5#
ID:171327 发表于 2019-1-14 02:10 | 只看该作者
你好,请问您这个app的源码有吗?我想请教一下,最近在弄这个想在宿舍装一个,
回复

使用道具 举报

6#
ID:66761 发表于 2019-1-17 10:59 | 只看该作者
最近正研究这个呢,谢谢楼主分享
回复

使用道具 举报

7#
ID:471573 发表于 2019-1-23 16:27 | 只看该作者
太强大了!!!
回复

使用道具 举报

8#
ID:430254 发表于 2019-1-24 17:06 | 只看该作者
非常不错,好帖
回复

使用道具 举报

9#
ID:508022 发表于 2019-4-9 16:58 | 只看该作者

请问您会做这个吗,想请教一下您
回复

使用道具 举报

10#
ID:508022 发表于 2019-4-9 16:59 | 只看该作者
请问怎么联系作者啊,想请教一下
回复

使用道具 举报

11#
ID:692945 发表于 2020-2-15 00:10 | 只看该作者
你好,你还有这个app的源码吗?我想学习一下
回复

使用道具 举报

12#
ID:692945 发表于 2020-3-11 18:12 | 只看该作者
小白请教,不是用蓝牙控制吗,为什么还用到按键?
回复

使用道具 举报

13#
ID:65956 发表于 2020-3-12 08:47 | 只看该作者
这个充其量也只能是算局部室内手机遥控器,算不上什么智能
回复

使用道具 举报

14#
ID:540642 发表于 2020-3-15 17:25 | 只看该作者
这个插座是220v交流电吗
回复

使用道具 举报

15#
ID:342911 发表于 2020-3-17 11:38 | 只看该作者
感谢分享 太强了
回复

使用道具 举报

16#
ID:555216 发表于 2020-3-20 17:33 | 只看该作者
谢谢,请问这个APP时可以用AS打开吗
回复

使用道具 举报

17#
ID:494479 发表于 2020-4-5 12:23 | 只看该作者
这个有全部的元器件清单么
回复

使用道具 举报

18#
ID:281879 发表于 2020-4-5 14:11 | 只看该作者
谢谢分享 太牛了
回复

使用道具 举报

19#
ID:630878 发表于 2020-4-24 11:38 来自手机 | 只看该作者
作者您好,请问app在哪开发
回复

使用道具 举报

20#
ID:739951 发表于 2020-4-28 11:16 | 只看该作者
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表