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

举报
DS小龙哥 发表于 2022/01/13 08:53:48 2022/01/13
【摘要】 这是基于ZigBee设计的自动照明系统,连接了光感传感器,ESP8266WIFI模块。通过ESP8266与手机APP之间通信,ESP8266创建热点,配置为TCP服务器模式; 手机APP连接上ESP8266的热点之后,再连接ESP8266创建的服务器,完成通信。

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灯,模拟家里客厅的照明设备,实现控制效果演示。

image-20220111104700542

image-20220111103544808

image-20220111104619684

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数据打印到串口。
也可以自己打印其他一些调试信息。

image-20220111104742622

image-20220111104753325

image-20220111104851404

2.2 光敏传感器

image-20220111105037476

image-20220111105048153

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

项目Get地址: https://download.csdn.net/download/xiaolong1126626497/75317115

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。