5.1 Multiprotocol (BLE+ZIGBEE) Concurrent Application

This application demonstrates on creating Multiprotocol (BLE and ZIGBEE) example project using MCC. This step by step procedure helps user to generate the Multiprotocol project from scratch and guides in understanding few API calls needed for data transaction between two protocols.

Hardware Requirement

Table 5-1. Hardware Requirement
Tool Qty
WBZ451 Curiosity Board2
Micro USB cable2
Android/iOS Mobile1

SDK Setup

Software Requirement

Smartphone App

  • Microchip Bluetooth Data (MBD) iOS/Android app available in stores

Programming the Precompiled Hex File or Application Example

This demo needs two devices, as described below:

  1. combinedInterface.X: One of the WBZ451 Curiosity boards is programmed with Combined Interface which can act as Zigbee Gateway/Coordinator. Program the CI pre-compiled hex image by following the steps mentioned in the “Programming the precompiled hex file or Application Example” section of the Zigbee Centralized Network Formation by Combined Interface application, on one curiosity board.
  2. ble_zigbee_basic.X: On Another WBZ451 Curiosity board program with ble_zigbee_basic application. Follow the below step for programming ble_zigbee_basic.X application on another curiosity board.

Programming the .hex File using MPLAB X IPE

  1. Import and program the precompiled .hex file is located in "<Harmony Content Path>\wireless_apps_pic32cxbz2_wbz45\apps\multiprotocol\ble_zigbee_basic\hex" folder
  2. For more details on the steps, go to Programming a Device
    Note: Users must choose the correct device and tool information

Programming the Application using MPLAB X IDE

  1. Follow steps mentioned in the Running a Precompiled Example section.
  2. Open and program the application example "ble_zigbee_basic.X" located in "<Harmony Content Path>\wireless_apps_pic32cxbz2_wbz45\apps\multiprotocol\ble_zigbee_basic\firmware" using MPLAB X IDE

    For more details on finding the Harmony content path, refer to Installing the MCC Plugin

Demo Description

This application demonstrates the Zigbee ON/OFF light joining to Zigbee Gateway (Combined Interface) and the Microchip Proprietary Transparent Service based BLE peripheral running concurrently with Zigbee protocol connects with the mobile app. When the Zigbee light gets the light ON/OFF command from CI, it will be reflected in the mobile app. Hence, this application is a demonstration of the simple concurrent operation of Multiprotocol. This application focuses on Lights and Bridge (CI) devices, with the understanding that the WiFi/Ethernet gateway falls outside the scope of this application. The third party Gateway like Amazon Echo plus can also be used instead of CI.

Figure 5-1. Demonstration

Testing

This section assumes that user has already programmed the Multiprotocol application example and Combined Interface application example on two WBZ451 Curiosity boards.

Demo Experience while using a Smart Phone (MBD App) as the Central Device
  1. Reset the Combined Interface programmed on the WBZ451 Curiosity board.
  2. Open TeraTerm and configure as mentioned below:
    Terminal Settings
    • Baud Rate/Speed – 115200 (as configured in SERCOM configuration)
    • Parity – None
    • Data Bits – 8
    • Stop Bits – 1
    • Flow Control – None

    For more details on how to set the “Serial Port” and “Speed”, refer to COM Port Setup

  3. Enable CR+LF for RX, TX in Terminal setup.
  4. Send command: resetToFN and look for the below logs for successful Zigbee network formation on CI
    Figure 5-2. Network Formation Logs
  5. Reset Combo device and send command: resetToFN. Look for combo device joining with Combined Interface. The ON/OFF light cluster search and binding between two devices is successful, and Combo device ON/OFF light attributes reports are seen in CI. During the 180sec commissioning period, the RED LED Toggles.
    Figure 5-3. Combined Interface and Combo Device Logs
  6. Open Microchip Bluetooth Data (MBD) App on the smart phone,
    1. Select BLE Smart
    2. Select the advertisement with Device Name Combo, to connect with the combo device
      Figure 5-4. MBD Combo Device Conection
  7. Enable Notify/Indicate option to receive data from the Combo device
    Figure 5-5. Notify/Indicate
  8. After the 180 seconds commissioning period, write 8F01 to switch ON RED LED and look for ON/OFF attribute value changing to 0x01 in CI logs, and RED LED getting ON. Similarly write 8F00 to switch OFF RED LED and look for attribute value changing to 0x00 in CI logs. As previously stated, the updated report value will be reflected in the CI logs following the minimum report interval.
    Figure 5-6. Write to Switch ON
    Figure 5-7. Control Commands
  9. By sending ON/OFF command from CI the RED LED can be switched ON/OFF. This value can be seen in MBD app as well
    1. The network address of the Combo device is needed to send light control commands to Combo device from CI. This network address can be obtained from Combined Interface console logs, while the joining was done.
      Figure 5-8. Device Address
    2. Another way to obtain the network address from Combo device is by executing the below command in Combo light side

      Command

      ← getNetworkAddress

      Response

      → 493f

      Example

      ←getNetworkAddress
      →493f
      ←onOff 0x0 0x4937 0x20 -on  // Light ON
      ←onOff 0x0 0x4937 0x20 -off // Light OFF
      //0x20 is zigbee end point number used for light can be taken from MCC configurator
      Figure 5-9. EndPoint Address
  10. Read Notify
    Figure 5-10. Read Notify

Developing the Application from Scratch using MCC

The following steps helps to understand the PIC32CXBZ2 device Zigbee and BLE stack programming structure. Recommendation is to follow the steps. If wish is to have Out-of-Box experience with the precompiled hex file go to the top of this section.
Note: It is recommended that new users of MCC to go through the overview.

For developing combined interface from scratch, refer to the “Creating Application Device Types from Scratch using MCC” section of the Zigbee Centralized Network Formation by Combined Interface

This tutorial explains developing ble_zigbee_basic application from scratch

Pull-in MCC Components

  1. Create a new MCC Harmony Project. For more details, refer to 2.5 Creating a New MCC Harmony Project.
  2. Import component configuration – This step helps users setup the basic components and configuration required to develop this application. The imported file is of format .mc3 and is located in the path "<Harmony Content Path>\wireless_apps_pic32cxbz2_wbz45\apps\multiprotocol\ble_zigbee_basic\firmware\ble_zigbee_basic.X".

    For more details on importing the component configuration , refer to 14.3 Importing Existing App Example Configuration

    Note: Import and export functionality of Harmony component configuration will help users to start from a known working setup of MCC configuration
  3. Verify the project graph and configuration options shown in the below steps.
  4. Another method is manually adding and configuring the components in project graph
    1. From “Device Resources” field, select + onoff Light component (Zigbee component), to add it in project graph.
    2. Accept Dependencies or satisfiers, select Yes
      Figure 5-11. Auto-Activation and Auto-Connection Request
      Figure 5-12. Project Graph
    3. From “Device Resources” field, select + BLE Stack component, to add it in project graph.
      1. BLE Stack component
        Figure 5-13. BLE Stack Component
    4. From “Device Resources” field, select Transparent service and profile components, to add it in project graph.
      Figure 5-14. Transparent Service and Profile
    5. Add UART component needed for console logs and commands. Right click on the yellow triangle on + onoff Light component to add satisfiers as illustrated below. Verify the UART SERCOM configuration as in Zigbee Console Commands
      Figure 5-15. SERCOM0
    6. From “Device Resources” field, select + TCC2 component, to add it in project graph.
      Figure 5-16. TCC2
  5. Verify if the project graph window has all the expected components. as illustrated in the following figure:
    Figure 5-17. Project Graph

Edit BLE Stack Specific Configurations

  1. Select BLE Stack component in project graph, to open component configuration and configure as illustrated in the following figure

    Figure 5-18. BLE Stack Configuration
  2. Select Transparent Profile component in project graph, to open component configuration and configure as illustrated in the following figure

    Figure 5-19. Transparent Profile Configuration

Edit Zigbee Stack Specific Configurations

  1. Select Onoff Light component in project graph, to open component configuration and configure as illustrated in the following figure
    1. The "Commissioning Configuration" is edited to enable only Steering option
    Figure 5-20. Onoff Light Configuration

Edit PDS_SubSystem Specific Configurations

  1. Select PDS_SubSystem component in project graph, to open component configuration and configure as illustrated in the following figure
    Figure 5-21. PDS_SubSystem Configuration

Edit Peripheral Specific Configurations

  1. Select SERCOM0 component in project graph, to open component configuration and configure as illustrated in the following figure
    Figure 5-22. SERCOM0 Configuration
  2. Edit Pin Configuration in project graph, for RED LED GPIO configuration, as illustrated in the following figure
    Figure 5-23. Pin Configuration

Files and Routines Automatically Generated by the MCC

After generating the code from MCC interface by clicking Generate Code, below is the project folder structure.
Figure 5-24. Project Files

BLE, Zigbee Stack Initialization and Application Callback Registration:

The RF System, BLE System, ZIGBEE, PERIPHERAL initialization routine executed during program initialization can be found in SYS_Initialize() of initialization.c file.

Zigbee stack provides various APIs for application, and those APIs belong to the specific module within dedicated group. The sequence of initialization is already taken care in the stack when Zigbee_Init() from initialization.c is called.
Figure 5-25. initialization.c

The BLE stack initialization routine executed during application initialization can be found in APP_BleStackInit() in app.c. This call initializes and configures different BLE layers like GAP, GATT, SMP, L2CAP and BLE middleware layers and registers the application layer callbacks. The event callbacks from BLE stack, BLE middleware and profile/service layer are registered.

Also, the MCC configured advertisement data payload can be seen in APP_BleConfigBasic()
Figure 5-26. APP_BleConfigBasic()
Similar to BLE, Zigbee stack also generate events to inform application if there is any status changed or activity. Application may need to get the relevant information from Zigbee Stack and do the corresponding procedure.
Figure 5-27. app.c
BLE, Zigbee stack application events handling: app.c file is autogenerated and has a state machine for application callback handling from BLE, Zigbee stacks
Figure 5-28. app.c

User Application Development

Compile MCC Auto-generated Project

Build Project, upon building project user action is required as mentioned User Action.

  1. BLE Specific Code Addition
    1. Start Advertisement (app.c)

      Advertisement payload is already auto generated based on MCC configuration as mentioned in Edit BLE Stack Specific Configurations. It is only required to start the advertisement, by adding the below API in APP_STATE_INIT state.

      BLE_GAP_SetAdvEnable(true, 0);

      void APP_Tasks ( void )
      {
          APP_Msg_T    appMsg[1];
          APP_Msg_T   *p_appMsg;
          p_appMsg=appMsg;
      
          ZB_AppGenericCallbackParam_t cb;
          /* Check the application's current state. */
          switch ( appData.state )
          {
              /* Application's initial state. */
              case APP_STATE_INIT:
              {
                  bool appInitialized = true;
                  //appData.appQueue = xQueueCreate( 10, sizeof(APP_Msg_T) );
                  APP_BleStackInit();
                  BLE_GAP_SetAdvEnable(true, 0);
    2. Connected and Disconnected Events (app_ble_handler.c)

      The BLE application specific callbacks from BLE stack is handled in app_ble_handler.c file. Few events needed for this application to be handled by the user code as below.

      1. Connection Handler

        • In app_ble_handler.c, BLE_GAP_EVT_CONNECTED event will be generated when a BLE peripheral is connected with Central (mobile app)

        • Connection handle associated with the peer central device needs to be saved for data exchange after a BLE connection. Add the below code in APP_BleGapEvtHandler().

        • Console log is also added to print the connected message and respective #include file is also added.

          #include <app_zigbee/zigbee_console/console.h>
          
          void APP_BleGapEvtHandler(BLE_GAP_Event_T *p_event)
          {
              switch(p_event->eventId)
              {
                  case BLE_GAP_EVT_CONNECTED:
                  {
                      /* TODO: implement your application code.*/
                      appSnprintf("[BLE} Connected\n\r");
                      conn_hdl = p_event->eventField.evtConnect.connHandle;
                      linkState = APP_BLE_STATE_CONNECTED;
                  }
                  break;

          In app_ble_handler.h add the below definitions which are used in above step

          // *****************************************************************************
          // *****************************************************************************
          // Section: Type Definitions
          // *****************************************************************************
          // *****************************************************************************
          uint16_t conn_hdl;
          uint8_t linkState;
          
          #define APP_BLE_STATE_CONNECTED 0x01
          #define APP_BLE_STATE_STANDBY  0x00
      2. Disconnection Handler
        • In app_ble_handler.c, BLE_GAP_EVT_DISCONNECTED event will be generated when BLE peripheral is disconnected from Central (mobile app)

        • Advertisement can be started again to enable another connection
        • Console log is also added to print the disconnected message
          case BLE_GAP_EVT_DISCONNECTED:
          {
              /* TODO: implement your application code.*/
              appSnprintf("[BLE} DisConnected\n\r");
              BLE_GAP_SetAdvEnable(true, 0);
              linkState = APP_BLE_STATE_STANDBY;               
          }
          break;
  2. Zigbee Specific Code Addition (app_zigbee_handler.c)

    There will be three major events which the stack would provide to the user application in app_zigbee_handler.c file. They are:
    • Zigbee Events which is defined as "EVENT_ZIGBEE"
    • ZCL and Cluster Events defined as "EVENT_CLUSTER"
    • Board Specific Package (BSP) Events defined as "EVENT_BSP"
    1. ZCL EVENT_CLUSTER event handling for on/off Light cluster

      ZCL (Zigbee cluster library)

      • ZCL is a repository for cluster functionalities
      • Regularly updated with new functionality added
      • Not to “re-invent the wheel” for new application development

      Cluster

      • Cluster is a set of attributes and commands which are defined for a particular application functionality/feature.
      • Attributes and their data types are defined
      • Uses client/server model of communication
      • Standard commands/messages ensure interoperability, abstracts the commands for developers.

      For example: On/Off cluster

      Attributes: OnOff, OnTime, OffWaitTime

      Commands: Off, On, Toggle, OffWithEffect, OnWithRecallGlobalScene, OnWithTimedOff

      -Explore

      For more details regarding clusters, refer to the specification from Zigbee Alliance Zigbee Cluster Library Specification by Zigbee Alliance

      This project uses ON/OFF device type. Hence uses On/Off light cluster from Zigbee defined cluster library. When the ON/OFF command to control the light is received from CI Gateway, CMD_ZCL_ON, CMD_ZCL_OFF of ZCL EVENT_CLUSTER will be received on light device. A simple console print is already added in those event callbacks as below.

      void Cluster_Event_Handler(APP_Zigbee_Event_t event)
      {
          switch(event.eventId)
          {
              case CMD_ZCL_ON:
              {
                  /* ZCL Command ON received */
                  //Access - > event.eventData.zclEventData.addressing;
                  //Access - > event.eventData.zclEventData.payloadLength;
                  //Access - > event.eventData.zclEventData.payload;
                  appSnprintf("On\r\n");
                  uint8_t onCmd;
                  onCmd = 0x01;
                  
                  if(linkState == APP_BLE_STATE_CONNECTED)
                      BLE_TRSPS_SendVendorCommand(conn_hdl, 0x8F, 0x01, &onCmd);            
              }
              break;
              case CMD_ZCL_OFF:
              {
                  /* ZCL Command Off received */
                  //Access - > event.eventData.zclEventData.addressing;
                  //Access - > event.eventData.zclEventData.payloadLength;
                  //Access - > event.eventData.zclEventData.payload;
                  appSnprintf("Off\r\n");
                  uint8_t offCmd;
                  offCmd = 0x00;
                  
                  if(linkState == APP_BLE_STATE_CONNECTED)
                      BLE_TRSPS_SendVendorCommand(conn_hdl, 0x8F, 0x01, &offCmd);             
              }
              break;
    2. EVENT_BSP Event Handling for ON/OFF Light Control

      • In addition to above ZCL event, BSP event will also be called when ON/OFF command is received. This will enable the user to write the board specific functionality code like switch ON/OFF the on board LED. CMD_LED_BRIGHTNESS single event is called for both ON or OFF, since On/Off cluster is added in many other device types like dimmable light, color control light, where light functionality is also mapped to brightness/color and not simple ON/OFF. Add below code to control on board RED LED.

        void BSP_Event_Handler(APP_Zigbee_Event_t event)
        {
            // User to handle  board Support package events
            switch(event.eventId)
            {
                case CMD_LED_BRIGHTNESS:
                {
                    /* Set the given LED brightness */
                    //Access - > event.eventData.value;
                    //appSnprintf("Led Brightness \r\n");
                    if(event.eventData.value == 255)// MAX_BRIGHTNESS_LEVEL for On
                       RED_LED_Set();
                    else if (event.eventData.value == 0) //MIN_BRIGHTNESS_LEVEL for Off
                       RED_LED_Clear();
                        
                }
                break;
      • Add the include file needed for LED GPIO functionality in app_zigbee_handler.c

        #include "peripheral/gpio/plib_gpio.h"
    3. Edit Device Unique ID (zigbeeAppDeviceSelect.h)

      All the zigbee devices/modules will hold their unique IEEE address purchased from IEEE. For the demo purpose, where UID is not present in internal NVM, the pre-compiled fixed UID to be used. Edit the CS_UID to user defined value and not matching with combined interface UID (default 0xbee) as below in zigbeeAppDeviceSelect.h

      Figure 5-29. zigbeeAppDeviceSelect.h
    4. Data Transaction Between BLE to Zigbee Protocol and Vice Versa

      Transparent Profile and Service (TRP/TRS) is the proprietary BLE service by microchip to establish data and control channel between BLE Central (Phone) and Peripheral (device). The custom 128-bit GATT characteristics are defined under this service.
      Table 5-2. Definition of Transparent Service and Characteristics UUID's
      Characteristic NameUUIDProperties
      TRS Service49535343-FE7D-4AE5-8FA9-9FAFD205E455
      TRS TxD- Tx Data to Client role (Data pipe)49535343-1E4D-4BD9-BA61-23C647249616Notify, Write
      TRS TxD - Client Characteristic Configuration DescriptorRead, Write
      TRS RxD- Rx Data from Client role (Data pipe)49535343-8841-43F4-A8D4-ECBE34729BB3Write, Write without response
      TRS Ctrl Pt - Command and Response (Ctrl pipe)49535343-4C8A-39B3-2F49-511CFF073B7ENotify, Write, Write without response
      TRS Ctrl Pt - Client Characteristic Configuration descriptorRead, Write

      Send Data over BLE (app_zigbee_handler.c)

      When the On/Off command is received from CI, send single byte of data to mobile app using Transparent service. We use TRS Ctrl Pt characteristic in this example project to send and receive data from mobile app.

      • BLE_TRSPS_SendVendorCommand(conn_hdl, 0x8F, 0x01, &onCmd) is the API to be used for sending data towards the central device. Here 0x8F is any custom command value for identification and 0x01 is length of the command data. Add this API call in Zigbee On/Off ZCL event callbacks as below.

        void Cluster_Event_Handler(APP_Zigbee_Event_t event)
        {
            switch(event.eventId)
            {
                case CMD_ZCL_ON:
                {
                    /* ZCL Command ON received */
                    //Access - > event.eventData.zclEventData.addressing;
                    //Access - > event.eventData.zclEventData.payloadLength;
                    //Access - > event.eventData.zclEventData.payload;
                    appSnprintf("On\r\n");
                    uint8_t onCmd;
                    onCmd = 0x01;
        
                    if(linkState == APP_BLE_STATE_CONNECTED)
                        BLE_TRSPS_SendVendorCommand(conn_hdl, 0x8F, 0x01, &onCmd);            
                }
                break;
                case CMD_ZCL_OFF:
                {
                    /* ZCL Command Off received */
                    //Access - > event.eventData.zclEventData.addressing;
                    //Access - > event.eventData.zclEventData.payloadLength;
                    //Access - > event.eventData.zclEventData.payload;
                    appSnprintf("Off\r\n");
                    uint8_t offCmd;
                    offCmd = 0x00;
        
                    if(linkState == APP_BLE_STATE_CONNECTED)
                        BLE_TRSPS_SendVendorCommand(conn_hdl, 0x8F, 0x01, &offCmd);             
                }
                break;
      • Add the include file needed for the above BLE APIs in app_zigbee_handler.c

        #include "app_ble_handler.h"
        #include "ble/profile_ble/ble_trsps/ble_trsps.h"

      Send Data over Zigbee (app_trsps_handler.c)

      • When the On/Off single byte data is received from mobile app using Transparent service, change the global variable which holds the On/Off attribute value.
      • On/Off attribute data is sent periodically at defined MAX interval to CI. When the On/Off attribute value is changed by BLE, an additional report will be sent at MIN report interval with the changed value. The reporting interval is configured in auto generated Zigbee middleware include file firmware\src\config\default\zigbee\z3device\light\include\lightOnOffCluster.h (unit in seconds)
        /******************************************************************************
                            Definition(s) section
        ******************************************************************************/
        #define ONOFF_VAL_MIN_REPORT_PERIOD 30
        #define ONOFF_VAL_MAX_REPORT_PERIOD 120
      • When the non zero value is sent from mobile app using TRPS Ctrl pt characteristic, the LED is switched ON and for zero value LED is switched OFF in BLE_TRSPS_EVT_VENDOR_CMD event callback. Add the below code to update the On/Off attribute value and to change RED LED Status. ZCL_ReportOnChangeIfNeeded() API is called to initiate the additional report at ONOFF_VAL_MIN_REPORT_PERIOD interval. lightOnOffClusterServerAttributes.onOff is the global variable defined in Zigbee middleware which holds the OnOFF attribute value.

        void APP_TrspsEvtHandler(BLE_TRSPS_Event_T *p_event)
        {
            switch(p_event->eventId)
            {
                case BLE_TRSPS_EVT_VENDOR_CMD:
                {
                    /* TODO: implement your application code.*/
                    if(p_event->eventField.onVendorCmd.length)
                    {                 
                        if(p_event->eventField.onVendorCmd.p_payLoad[1])
                        {    
                            lightOnOffClusterServerAttributes.onOff.value = 1;
                            RED_LED_Set();
                            appSnprintf("[BLE} On Command\n\r");                    
                        }    
                        else
                        {    
                            lightOnOffClusterServerAttributes.onOff.value = 0;
                            RED_LED_Clear();
                            appSnprintf("[BLE} Off Command\n\r");                    
                        }                   
                        ZCL_ReportOnChangeIfNeeded(&lightOnOffClusterServerAttributes.onOff);
                    }    
                }
                break;
      • Add the include file needed for the above ZIGBEE API and GPIO in app_trsps_handler.c

        #include <app_zigbee/zigbee_console/console.h>
        #include <z3device/light/include/lightOnOffCluster.h>
        #include "peripheral/gpio/plib_gpio.h"
        Note: The sample project with all the above code changes is available in ble_zigbee_basic for your reference.

Where to go from Here