NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

Occupancy Sensor

From Texas Instruments Wiki
Jump to: navigation, search

This sample demonstrates how to implement an occupancy sensor device and how the sensor communicates with other devices using the standard ZigBee Home Automation profile. The example is written for ease of use first, performance second. There is most likely a faster way to do everything, but we wanted to ensure that the examples are easy to understand.

The installer that will add the sample application to an existing Z-Stack Home installation can be downloaded here.

Sample Devices[edit]

In this sample, two devices are implemented. One is an occupancy sensor device and the other is a general on/off light with occupancy sensing client.

  • Occupancy Sensor Device
  • OnOff Light Device

Occupancy Sensor Device Detail[edit]

  • Cluster Implemented. (In HA spec, the mandatory cluster of occupancy sensor is Occupancy Sensing Cluster)
    • Server: Occupancy Sensing Cluster
    • Client: None

<syntaxhighlight lang='c'> // zcl_SampleOcc_data.c // This is the Cluster ID List and should be filled with Application // specific cluster IDs.

  1. define ZCLSampleOcc_MAX_INCLUSTERS 2

const cId_t zclSampleOcc_InClusterList[ZCLSampleOcc_MAX_INCLUSTERS] = {

 ZCL_CLUSTER_ID_GEN_BASIC,
 ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING

};


SimpleDescriptionFormat_t zclSampleOcc_SimpleDesc = {

 SampleOcc_ENDPOINT,                  //  int Endpoint;
 ZCL_HA_PROFILE_ID,                   //  uint16 AppProfId[2];
 ZCL_HA_DEVICEID_OCCUPANCY_SENSOR,    //  uint16 AppDeviceId[2];
 SampleOcc_DEVICE_VERSION,            //  int   AppDevVer:4;
 SampleOcc_FLAGS,                     //  int   AppFlags:4;
 ZCLSampleOcc_MAX_INCLUSTERS,         //  byte  AppNumInClusters;
 (cId_t *)zclSampleOcc_InClusterList, //  byte *pAppInClusterList;
 0,                                   //  byte  AppNumInClusters;
 NULL                                 //  byte *pAppInClusterList;

}; </syntaxhighlight>

  • Attribute Implemented
    • 0x0000: Occupancy
    • 0x0001: OccupancySensorType
    • 0x0010: PIROccupiedToUnoccupiedDelay
    • 0x0011: PIRUnoccupiedToOccupiedDelay

<syntaxhighlight lang='c'> // zcl_SampleOcc_data.c // Occupancy Cluster uint8 zclSampleOcc_Occupied = 0; /* Set default to Not be occupied */ uint8 zclSampleOcc_OccType = MS_OCCUPANCY_SENSOR_TYPE_PIR; uint8 zclSampleOcc_PirOccupiedToUnoccupiedDelay = 5; uint8 zclSampleOcc_PirUnoccupiedToOccupiedDelay = 5;

/*********************************************************************

* ATTRIBUTE DEFINITIONS - Uses REAL cluster IDs
*/

CONST zclAttrRec_t zclSampleOcc_Attrs[SampleOcc_MAX_ATTRIBUTES] = {

 // *** Occupancy Cluster Attributes ***
 {
   ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING,
   { // Attribute record
     ATTRID_MS_OCCUPANCY_SENSING_CONFIG_OCCUPANCY,
     ZCL_DATATYPE_BITMAP8,
     ACCESS_CONTROL_READ,
     (void *)&zclSampleOcc_Occupied
   }
 },
 // *** Occupancy Cluster Attributes ***
 {
   ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING,
   { // Attribute record
     ATTRID_MS_OCCUPANCY_SENSING_CONFIG_OCCUPANCY_SENSOR_TYPE,
     ZCL_DATATYPE_ENUM8,
     ACCESS_CONTROL_READ,
     (void *)&zclSampleOcc_OccType
   }
 },
 // *** Occupancy Cluster Attribute ***
 {
   ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING,
   { // Attribute record
     ATTRID_MS_OCCUPANCY_SENSING_CONFIG_PIR_O_TO_U_DELAY,
     ZCL_DATATYPE_UINT16,
     (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
     (void *)&zclSampleOcc_PirOccupiedToUnoccupiedDelay
   }
 },
 // *** Occupancy Cluster Attribute ***
 {
   ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING,
   { // Attribute record
     ATTRID_MS_OCCUPANCY_SENSING_CONFIG_PIR_U_TO_O_DELAY,
     ZCL_DATATYPE_UINT16,
     (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
     (void *)&zclSampleOcc_PirUnoccupiedToOccupiedDelay
   }
 },

}; </syntaxhighlight>

  • Commands Implemented
    • ZCL Report Attribute Command

Lighting Device Detail[edit]

The occupancy light device is the successor of Switch/Light sample, so it contains the feature of OnOff. Besides, it also has the ability to handle the report command of occupancy state.

  • Cluster Implemented. (In HA Spec, the mandatory cluster of OnOff Light is OnOff, Scene, Group cluster. Occupancy sensing cluster is optional)
    • Server: Basic, Scene, Group, OnOff, Level Control
    • Client: Occupancy Sensing

<syntaxhighlight lang='c'> //zcl_samplelight_data.c

  1. define ZCLSAMPLELIGHT_MAX_INCLUSTERS 5

const cId_t zclSampleLight_InClusterList[ZCLSAMPLELIGHT_MAX_INCLUSTERS] = {

 ZCL_CLUSTER_ID_GEN_BASIC,
 ZCL_CLUSTER_ID_GEN_SCENES,
 ZCL_CLUSTER_ID_GEN_GROUPS,
 ZCL_CLUSTER_ID_GEN_ON_OFF,
 ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL

};


  1. define ZCLSAMPLELIGHT_MAX_OUTCLUSTERS 2

const cId_t zclSampleLight_OutClusterList[ZCLSAMPLELIGHT_MAX_OUTCLUSTERS] = {

 ZCL_CLUSTER_ID_GEN_BASIC,
 ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING

};

SimpleDescriptionFormat_t zclSampleLight_SimpleDesc = {

 SAMPLELIGHT_ENDPOINT,                  //  int Endpoint;
 ZCL_HA_PROFILE_ID,                     //  uint16 AppProfId[2];
 ZCL_HA_DEVICEID_DIMMABLE_LIGHT,        //  uint16 AppDeviceId[2];
 SAMPLELIGHT_DEVICE_VERSION,            //  int   AppDevVer:4;
 SAMPLELIGHT_FLAGS,                     //  int   AppFlags:4;
 ZCLSAMPLELIGHT_MAX_INCLUSTERS,         //  byte  AppNumInClusters;
 (cId_t *)zclSampleLight_InClusterList, //  byte *pAppInClusterList;
 ZCLSAMPLELIGHT_MAX_OUTCLUSTERS,        //  byte  AppNumInClusters;
 (cId_t *)zclSampleLight_OutClusterList //  byte *pAppInClusterList;

}; </syntaxhighlight>

  • Attribute Implemented
    • 0x0000: OnOff

<syntaxhighlight lang='c'> // zcl_samplelight_data.c // On/Off Cluster uint8 zclSampleLight_OnOff = LIGHT_OFF; CONST zclAttrRec_t zclSampleLight_Attrs[SAMPLELIGHT_MAX_ATTRIBUTES] = {

 // *** On/Off Cluster Attributes ***
 {
   ZCL_CLUSTER_ID_GEN_ON_OFF,
   { // Attribute record
     ATTRID_ON_OFF,
     ZCL_DATATYPE_UINT8,
     ACCESS_CONTROL_READ,
     (void *)&zclSampleLight_OnOff
   }
 },

}; </syntaxhighlight>

  • Commands Implemented
    • None

Basic Operation[edit]

  • Network Start: In this sample, we run the Light Device as the Coordinator and the Occupancy Sensor Device as Router. Of course they also can be configured to other types, it depends on the different use case. So here Light form the network and Occupancy Sensor join it accordingly.
  • Service Discovery / End device binding: After the network starts successfully, there are two possible methods for the nodes to set up communication at the application level. One is the Match Descriptor Request/Response mechanism and another is End Device Binding. In this example, we use the former one in which the user must press LEFT (push joystick left on SmartRF05, left button on SmartRF06) on the Router to send a Match Descriptor Request which the Coordinator responds.

<syntaxhighlight lang='c'> // zcl_SampleOcc.c /*********************************************************************

  • @fn zclSampleSw_ProcessZDOMsgs()
  • @brief Process response messages
  • @param none
  • @return none
  • /

void zclSampleOcc_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg ) {

 switch ( inMsg->clusterID )
 {
   case Match_Desc_rsp:
     ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
     if ( pRsp )
     {
       if ( pRsp->status == ZSuccess && pRsp->cnt )
       {
         zclSampleOcc_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
         zclSampleOcc_DstAddr.addr.shortAddr = pRsp->nwkAddr;
         // Take the first endpoint, Can be changed to search through endpoints
         zclSampleOcc_DstAddr.endPoint = pRsp->epList[0];
         // Light LED
         HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
       }
       osal_mem_free( pRsp );
     }
   }
   break;
 }

} </syntaxhighlight>

  • Occupancy sensor simulating. The hardware platform we used for this example is SmartRF05/SmartRF06 board, which does not have an occupancy sensor in it. So we use a Joystick/Button to simulate it. Push DOWN the joystick / press DOWN button once to make the occupancy state be OCCUPIED and push / press DOWN again to change the status to UNOCCUPIED.

<syntaxhighlight lang='c'> // zcl_SampleOcc.c static void zclSampleOcc_HandleKeys( byte shift, byte keys ) {

 if ( keys & HAL_KEY_SW_3 )
 {
   osal_stop_timerEx (zclSampleOcc_TaskID, SampleOcc_STATUS_CHANGE_EVT);
   // change the occupancy status
   zclSampleOcc_Input = ~zclSampleOcc_Input;
  1. ifdef LCD_SUPPORTED
   HalLcdWriteScreen ((zclSampleOcc_Input)? "Occupied" : "Unoccupied", "");
  1. endif
   osal_start_timerEx( zclSampleOcc_TaskID,
                       SampleOcc_STATUS_CHANGE_EVT,
                       (zclSampleOcc_Input)?
                         zclSampleOcc_PirOccupiedToUnoccupiedDelay * 1000 :
                         zclSampleOcc_PirUnoccupiedToOccupiedDelay * 1000);
 }

} </syntaxhighlight>

  • Reporting Attribute. Once the occupancy state changed, it won't report until zclSampleOcc_PirOccupiedToUnoccupiedDelay/zclSampleOcc_PirUnoccupiedToOccupiedDelay elapse.

<syntaxhighlight lang='c'> // zcl_SampleOcc.c

  1. ifdef ZCL_REPORT

/*********************************************************************

* @fn      zclSampleOcc_ProcessStatusChange
*
* @brief   Called to send report command when occupancy status really change.
*
* @param   none
*
* @return  none
*/

static void zclSampleOcc_ProcessStatusChange( void ) {

 zclReportCmd_t reportCmd;
 zclSampleOcc_Occupied = zclSampleOcc_Input ? 1 : 0;
 reportCmd.numAttr = 1;
 reportCmd.attrList[0].attrID = ATTRID_MS_OCCUPANCY_SENSING_CONFIG_OCCUPANCY;
 reportCmd.attrList[0].dataType = ZCL_DATATYPE_UINT8;
 reportCmd.attrList[0].attrData = &zclSampleOcc_Occupied;
 zcl_SendReportCmd(SampleOcc_ENDPOINT,
                   &zclSampleOcc_DstAddr,
                   ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING,
                   &reportCmd,
                   1,0,1);

}

  1. endif

</syntaxhighlight>

  • Light Operation. When receiving the report command, the light device will set it's OnOff attribute accordingly.

<syntaxhighlight lang='c'> // zcl_samplelight.c

  1. ifdef ZCL_REPORT

/*********************************************************************

* @fn      zclSampleLight_ProcessInReportCmd
*
* @brief   Process the "Profile" Report Command
*
* @param   pInMsg - incoming message to process
*
* @return  none
*/

static void zclSampleLight_ProcessInReportCmd( zclIncomingMsg_t *pInMsg ) {

 zclReportCmd_t *pReportCmd;
 pReportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
  1. if defined( LCD_SUPPORTED )
 HalLcdWriteScreen( "Occ Report Rcvd", "" );
  1. endif
 if (pReportCmd->attrList[0].attrID == ATTRID_MS_OCCUPANCY_SENSING_CONFIG_OCCUPANCY)
 {
   if (*pReportCmd->attrList[0].attrData == OCC_STATE_UNOCCUPIED)
   {
     HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
     zclSampleLight_OnOff = LIGHT_OFF;
  1. if defined( LCD_SUPPORTED )
     HalLcdWriteScreen( "Occ Report Rcvd", "value = 0" );
  1. endif
   }
   else
   {
     HalLedSet ( HAL_LED_4, HAL_LED_MODE_ON );
     zclSampleLight_OnOff = LIGHT_ON;
  1. if defined( LCD_SUPPORTED )
     HalLcdWriteScreen( "Occ Report Rcvd", "value = 1" );
  1. endif
   }
 }

}

  1. endif /* ZCL_REPORT */

</syntaxhighlight>

E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Occupancy Sensor here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Occupancy Sensor here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article Occupancy Sensor here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article Occupancy Sensor here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article Occupancy Sensor here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Occupancy Sensor here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Occupancy Sensor here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article Occupancy Sensor here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Occupancy Sensor here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity