写点什么

基于 CC2530(ZigBee) 设计的自动照明系统

作者:DS小龙哥
  • 2022 年 2 月 21 日
  • 本文字数:4347 字

    阅读完需:约 14 分钟

1. 功能介绍

设计题目的名称: 基于 ZigBee 的自动照明系统设计


一共使用 3 个 CC2530 ZigBee 开发板,代号分别为 ABC。


A 开发板当做主机: 上面连接了光感传感器,ESP8266WIFI 模块。通过 ESP8266 与手机 APP 之间通信,ESP8266 创建热点,配置为 TCP 服务器模式; 手机 APP 连接上 ESP8266 的热点之后,再连接 ESP8266 创建的服务器,完成通信。 手机 APP 上通过按钮可以控制 B,C 开发板上 LED 灯的开关。


手机 APP 上可以设置自动照明的模式:


  1. 自动照明模式: 根据 A 开发板上的光感模块,采集光照强度,控制 B、C 开发板上的 LED 灯开关。

  2. 手动模式: 手机 APP 上可以选择单独控制 B、C 开发板上的 LED 灯开关。

  3. 支持设置光感阀值: 在手机 APP 上可以设置 A 开发板的光感传感器阀值(也就是控制灯亮灭的阀值)。

  4. 支持设置亮度,也可以自动根据环境光控制亮度


B 开发板当做从机节点: B 开发板上使用板载的 LED 灯,模拟家里卧室的照明设备,实现控制效果演示。


C 开发板当做从机节点: C 开发板上使用板载的 LED 灯,模拟家里客厅的照明设备,实现控制效果演示。





完整项目代码下载地址: https://download.csdn.net/download/xiaolong1126626497/75317115

2. 硬件介绍

2.1 ESP8266 wifi

采用的 ESP8266 系列无线模块是高性价比 WIFI SOC 模组,该系列模块支持标准的 IEEE802.11b/g/n 协议,内置完整的 TCP/IP 协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。


CC2530 开发板上本身就有一个 ESP8266 专用的接口,插上去就行了。


ES8266 WIFI 模块接在 串口 1 上面(P0.4/P0.5 口) ,波特率为 115200 。


CC2530 的串口 0 作为常规调试串口(P0_2 和 P0_3 端口),可以把采集的 AD 数据打印到串口。也可以自己打印其他一些调试信息。




2.2 光敏传感器


3. 项目代码

3.1 串口代码

#include "uart.h"/*函数功能:串口0初始化*/void Init_Uart0(void){  PERCFG&=~(1<<0);  //串口0的引脚映射到位置1,即P0_2和P0_3  P0SEL|=0x3<<2;   //将P0_2和P0_3端口设置成外设功能  U0BAUD = 216;     //32MHz的系统时钟产生115200BPS的波特率  U0GCR&=~(0x1F<<0);//清空波特率指数  U0GCR|=11<<0;      //32MHz的系统时钟产生115200BPS的波特率  U0UCR |= 0x80;    //禁止流控,8位数据,清除缓冲器  U0CSR |= 0x3<<6;  //选择UART模式,使能接收器}

/*函数功能:UART0发送字符串函数*/void UR0SendString(char *str){ while(*str!='\0') { U0DBUF = *str; //将要发送的1字节数据写入U0DBUF while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 str++; }}
/*函数功能: 模仿printf风格的格式化打印功能*/char USART0_PRINT_BUFF[200]; //格式化数据缓存数据void USART0_Printf(const char *format,...){ char *str=NULL; /*1. 格式化转换*/ va_list ap; // va_list---->char * va_start(ap,format); //初始化参数列表 vsprintf(USART0_PRINT_BUFF, format, ap); //格式化打印 va_end(ap); //结束参数获取 /*2. 串口打印*/ str=USART0_PRINT_BUFF;//指针赋值 while(*str!='\0') { U0DBUF=*str; //发送一个字节的数据 str++; //指针自增,指向下一个数据 while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 }}
复制代码

3.2 按键代码

#include "key.h"
/*函数功能:按键IO口初始化硬件连接:KEY1-->P0_1 KEY2-->P2_0 */void KEY_Init(void){ P0SEL&=~(0x1<<1); //配置P0_1处于通用GPIO口模式 P0DIR&=~(0x1<<1); //配置P0_1为输入模式 P0INP|= 0x1<<1; //上拉 P2SEL&=~(0x1<<0); //配置P2_0处于通用GPIO口模式 P2DIR&=~(0x1<<0); //配置P2_0为输入模式 P2INP|= 0x1<<0; //上拉 }
/*函数功能:按键扫描返 回 值:按下的按键值*/unsigned char Key_Scan(void){ static unsigned char stat=1; if((KEY1==0||KEY2==0)&&stat) { stat=0; delay10ms(); if(KEY1==0)return 1; if(KEY2==0)return 2; } else { if(KEY1&&KEY2)stat=1; } return 0;}
复制代码

3.3 延时函数

#include "delay.h"
/*延时200毫秒*/void delay200ms(void) //误差 -0.125us{ unsigned char a,b,c; for(c=95;c>0;c--) for(b=181;b>0;b--) for(a=14;a>0;a--);}

void delay10ms(void) //误差 0us{ unsigned char a,b,c; for(c=193;c>0;c--) for(b=118;b>0;b--) for(a=2;a>0;a--);}
/****************************************** * 函数描述:32M系统时钟下的毫秒延时函数 ******************************************/ void DelayMs(unsigned int ms) { unsigned int i,j; for(i = 0; i < ms; i++) { for(j = 0;j < 1774; j++); } }
void Onboard_wait( int timeout ){ while (timeout--) { asm("NOP"); asm("NOP"); asm("NOP"); }}
//延时函数void DelayUs(int us) //1 us延时{ Onboard_wait(us); }
复制代码

3.4 A 开发板(协调器)主函数代码

/*主函数*/void main(void){    u8 time_cnt=0;    unsigned char key;    u8 switch_val=150;  //开关阀值        u8 mode=1; //0 表示手动模式  1表示自动模式        //延时等待系统稳定    DelayMs(1000);    DelayMs(1000);        init_clk();   //配置时钟    LED_Init();   //初始化LED灯控制IO口    KEY_Init();   //按键初始化    Init_Uart0(); //初始化串口0    RF_Init();    //RF初始化    Init_Uart1(); //初始化串口1--连接WIFI    SetWifi();  //复位WIFI    SetESP8266_AP_TCP_Server(); //初始化WIFI    adc_Init();        clearBuffU1(); //清空BUFF        //运行正常提示    USART0_Printf("当前运行的是A开发板程序,一切正常.\r\n");              while(1)              {         //按键检测       key=Key_Scan();       if(key)       {          LED2 = !LED2;       }         /*  服务器发出的数据value:100   //阀值led1_on   //卧室LED开led1_off  //卧室LED关led2_on   //客厅LED开led2_off  //客厅LED关yes_auto_mode  //自动模式no_auto_mode   //手动模式*/        //判断是否收到了WIFI的数据       if(lenU1>=13)       {           RecdataU1[lenU1]='\0';                      //串口打印数据           USART0_Printf("WIFI收到的数据:%s\n",(u8*)RecdataU1);                       //卧室LED开           if(strstr((char*)RecdataU1,"led1_on"))           {                USART0_Printf("卧室LED开.\n");                 u8 buff[100]="B:1---";                //发送数据                tx_data(buff,strlen((char*)buff));                //运行状态灯                LED1 = !LED1;            }           //卧室LED关           else  if(strstr((char*)RecdataU1,"led1_off"))           {                USART0_Printf("卧室LED关.\n");                  u8 buff[100]="B:0---";                 //发送数据                tx_data(buff,strlen((char*)buff));                //运行状态灯                LED1 = !LED1;            }            //客厅LED开           else  if(strstr((char*)RecdataU1,"led2_on"))           {                 USART0_Printf("客厅LED开.\n");                  u8 buff[100]="C:1---";                 //发送数据                tx_data(buff,strlen((char*)buff));                //运行状态灯                LED1 = !LED1;            }            //自动模式           else  if(strstr((char*)RecdataU1,"yes_auto_mode"))           {                 USART0_Printf("设置为自动模式.\n");                  mode=1;           }            //手动模式           else  if(strstr((char*)RecdataU1,"no_auto_mode"))           {                  USART0_Printf("设置为手动模式.\n");                  mode=0;           }           //阀值           else  if(strstr((char*)RecdataU1,"value:"))           {                //运行状态灯                LED1 = !LED1;                                 char *p=strstr((char*)RecdataU1,"value:");                if(p)                {                    int a=atoi(p+6);                    if(a>0)                    {                      switch_val=a;  //得到新的阀值                    }                }                                USART0_Printf("设置新的阀值:%d.\n",switch_val);            }                      clearBuffU1(); //清理缓存       }                    time_cnt++;        DelayMs(10);                  //1秒钟时间到达       if(time_cnt>100)       {           time_cnt=0;                     //读取ADC值--也就是光照传感器的值          GasData = ReadGasData();                    //发送光照传感器的值到上位机          USART0_Printf("光照度:%d,模式:%d\n",GasData,mode);                    //如果是自动模式          if(mode)          {               //根据阀值判断是否开启关闭卧室,客厅的LED灯               if(GasData  >  switch_val )               {                    //开灯                        u8 buff1[10]="B:1---";                     //发送数据                    tx_data(buff1,strlen((char*)buff1));                      //开灯                        u8 buff2[10]="C:1---";                     //发送数据                    tx_data(buff2,strlen((char*)buff2));               }               else               {                      //关灯                        u8 buff1[10]="B:0---";                     //发送数据                    tx_data(buff1,strlen((char*)buff1));                      //关灯                        u8 buff2[10]="C:0---";                     //发送数据                    tx_data(buff2,strlen((char*)buff2));                   }          }       }    }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于CC2530(ZigBee)设计的自动照明系统