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

Posted DS小龙哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于CC2530(ZigBee)设计的自动照明系统相关的知识,希望对你有一定的参考价值。

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));    
               
          
       
    

以上是关于基于CC2530(ZigBee)设计的自动照明系统的主要内容,如果未能解决你的问题,请参考以下文章

CC2530_ZigBee+华为云IOT:设计一套属于自己的冷链采集系统

基于CC2530(ZigBee设计)的温度报警器

基于CC2530的ZigBee转以太网网关的设计与实现

Zigbee折腾之旅:CC2530最小系统

ZigBee硬件平台小记(CC2530)

ZigBee硬件平台小记(CC2530)