基于zigbee光照感应系统之节点单播通信(4)

本文介绍基于Zigbee的光照感应系统中,路由器如何通过单播方式向协调器发送光照强度数据。项目使用GL7516光照传感器,详细讲解了配置过程、数据采集及发送机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于zigbee光照感应系统之节点单播通信
在上一篇博客已经介绍了如和配置协调器与路由器之间的广播通信,本文将介绍路由器与协调器之间的单播通信。
本项目在路由器节点上外加了一个GL7516光照传感器,在路由器节点上不断采集光照传感器的光照强度,然后路由器将光照传感器的信号通过单播的方式发送给协调器,同时将串口助手上打印出来。
首先,来介绍一下GL7516光照传感器:

光敏电阻式一种半导体材料制成的电阻,其电导率随着光照度的变化而变化。利用这一特性可以制成不同形状和受光面积的光敏电阻。GL7516 就是其中的一种,光越强阻值越小。光敏电阻广泛应用于玩具、灯具、照相机等行业。
在这里插入图片描述
通过光敏电阻的电路图我们可以看出,当有光照是光敏电阻的阻值变小,P0.1引脚为高电平;没有光照是光敏电阻的阻值为大P0.1引脚为低电平。

在协议栈里配置光照传感器引脚:

#define LIGHT P0_1  //光敏为P0.1口控制
P0DIR&=~0X02;       //配置p0.1为输出口

第二步,配置接收方(协调器)的配置:
在void SampleApp_Init( uint8 task_id )函数配置接收放为点播

 SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
  SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
 SampleApp_Periodic_DstAddr.addr.shortAddr = 0x0000;

通信方式位16位单播,目标地址为0x0000(协调器的地址)

第三步,在事件处理函数里uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )启动定时器,我们需要自动不断采集P0.1引脚的电平:

 case ZDO_STATE_CHANGE:
          SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
          if ( 
//              (SampleApp_NwkState == DEV_ZB_COORD)|| 
              (SampleApp_NwkState == DEV_ROUTER)
//              || (SampleApp_NwkState == DEV_END_DEVICE) 
                )
          {
            
            //LS164_BYTE(8);//数码管显示0-9
            // Start sending the periodic message in a regular interval.
            osal_start_timerEx( SampleApp_TaskID,
                              SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                              SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
            
             //路由器双闪五次
            HalLedBlink(0x03,5,50,1000);
            HalUARTWrite(0,"I am RouterEB\n",sizeof("I am RouterEB\n"));
          }
          else
          {
            // Device is no longer in the network
          }
          break;

第四步,因为定时器函数是指向的是SAMPLEAPP_SEND_PERIODIC_MSG_EVT事件,然后我在SAMPLEAPP_SEND_PERIODIC_MSG_EVT事件里定义了一个路由器发送函数: SampleApp_SendRouterMessage()通过定时器指向一个事件而在一个事件里定义一个发送函数;通过这个简单的步骤就可以使发送函数不断执行也就是 SampleApp_SendRouterMessage()函数

 if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
  {
    // Send the periodic message
    //SampleApp_SendPeriodicMessage();
    SampleApp_SendRouterMessage();

    // Setup to send message again in normal period (+ a little jitter)
    osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
        (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );

    // return unprocessed events
    return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
  }

  // Discard unknown events
  return 0;
}

第五步,在发送函数SampleApp_SendRouterMessage()里

void SampleApp_SendRouterMessage(void)
{
  uint8 islight[1];
  if(P0_1==1)//强光
    osal_memcpy(islight,"1",1);
  else        //弱光
    osal_memcpy(islight,"0",1); 
 if( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
                       SAMPLEAPP_PERIODIC_CLUSTERID,
                       1,
                       islight,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS )==afStatus_SUCCESS)
 {
    HalUARTWrite(0,"send light",10);
    HalUARTWrite(0,"\n",1);
 }
 else{
 }

定义一个8位的数组uint8 islight[1],通过if语句判断P0.1引脚是否为1,如果为1的话 通过osal_memcpy函数,将字符1赋值给数组islight[1];然后通过 AF_DataRequest函数通过单播的方式将islight发送出去

if( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
                       SAMPLEAPP_PERIODIC_CLUSTERID,
                       1,
                       islight,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS )==afStatus_SUCCESS)
 {
    HalUARTWrite(0,"send light",10);
    HalUARTWrite(0,"\n",1);
 }
 else{
 }

第六步,协调器接收路由器的数据:
在SampleApp_MessageMSGCB函数

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
  uint16 flashTime;
  uint8 islight[8];

  switch ( pkt->clusterId )
  {
    case SAMPLEAPP_PERIODIC_CLUSTERID:
       if(osal_memcmp(pkt->cmd.Data,"1",1)){//强光
          HalLedSet (0x03, HAL_LED_MODE_ON);
        osal_memcpy(islight,"light",sizeof("light"));
         HalUARTWrite(0,"light",5);
         HalUARTWrite(0,"\n",1);
        
      }
      else{             //弱光
        HalLedSet (0x03, HAL_LED_MODE_OFF);
        osal_memcpy(islight,"dark",sizeof("dark"));
         HalUARTWrite(0,"dark",4);
         HalUARTWrite(0,"\n",1);
      }
      HalUARTWrite(0,islight,sizeof(islight));
      
      break;

协调器接收数据代码比较简单我就不在多讲了

通过以上几步就可以实现路由器不断采集光照传感器的信号,通过单播的方式发送给协调器。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值