cancel
Showing results for 
Search instead for 
Did you mean: 

BLE_ZIGBEE_RFD_Dynamic consumption testing report

DL_Weng
Associate II

Testing Background:

The current device requirements are as follows:

  1. It should operate in low-power Bluetooth mode as a BLE controller (only running the Bluetooth protocol).
  2. It should be able to run both the Zigbee and Bluetooth protocols simultaneously in low-power mode.

Thus, we need to test if the Dynamic M0 firmware can run the Bluetooth protocol alone and the BLE and Zigbee protocols together in terms of functionality and power consumption requirements.

Power Consumption Testing Conditions:

  • Hardware Conditions:
    • Nucleo development board
    • JP2 jumper cap removed
  • Power Supply Conditions:
    • Powered via JP3 and GND
  • Firmware Conditions:
    • M0: stm32wb5x_BLE_Zigbee_RFD_dynamic_fw.bin
    • M4: ble_zigbee_SED_Dyn.hex

 

Test 1:

With the original ble_zigbee_SED_Dyn.hex source code:

1.1 When the development board connects successfully to both the Zigbee (Home Assistant Zigbee hub) and ST BLE app, it enters low-power mode with a current of 300-400 µA.

DL_Weng_0-1731059960113.png

 

 

1.2 When connected only to the ST BLE app and not to Zigbee, the average power consumption is 4-5 mA, with a minimum of 2.7-3 mA.

DL_Weng_1-1731059960151.png

 

 

Test 2:

Disabling the Zigbee initialization code.

DL_Weng_2-1731059960158.png

 

Test Results: The development board failed to connect to the ST BLE app, and the Bluetooth device was not visible in the ST BLE app.

 

Test 3:

With both Zigbee and BLE initialized, Zigbee does not connect and is set to low-power mode.

Code Changes: The code modifies the APP_ZIGBEE_NwkForm function to set Zigbee into low-power mode after a single broadcast.

/**

 * @brief  Handle Zigbee network forming and joining

 * @PAram  None

 * @retval None

 */

static void APP_ZIGBEE_NwkForm(void)

{

  if ((zigbee_app_info.join_status != ZB_STATUS_SUCCESS) && (HAL_GetTick() >= zigbee_app_info.join_delay))

  {

    struct ZbStartupT config;

    enum ZbStatusCodeT status;

 

    if (zigbee_logging_done == FALSE)

    {

      /* Configure Zigbee Logging (only need to do this once, but this is a good place to put it) */

      ZbSetLogging(zigbee_app_info.zb, ZB_LOG_MASK_LEVEL_5, NULL);

      zigbee_logging_done = TRUE;

    }

 

    /* Attempt to join a zigbee network */

    ZbStartupConfigGetProDefaults(&config);

 

    zigbee_app_info.startupControl = ZbStartTypeJoin;

    config.startupControl = zigbee_app_info.startupControl;

 

    /* Using the default HA preconfigured Link Key */

    memcpy(config.security.preconfiguredLinkKey, sec_key_ha, ZB_SEC_KEYSIZE);  

    config.channelList.count = 1;

    config.channelList.list[0].page = 0;

    config.channelList.list[0].channelMask = 1 << CHANNEL; /* Channel in use*/

    //config.channelList.list[0].channelMask = CHANNELMASK_12TO14; /* Channels in use*/

 

    /* Add Sleepy End device configuration */

    config.capability &= ~(MCP_ASSOC_CAP_RXONIDLE

                          | MCP_ASSOC_CAP_DEV_TYPE

                          | MCP_ASSOC_CAP_ALT_COORD);

    config.endDeviceTimeout = SED_SLEEP_TIME_30S /* 30sec sleep time unit */;

 

    APP_DBG("Network config : APP_STARTUP_SED");

 

    APP_DBG("*** zigbee_start_nb value = %d ***", APP_ZIGBEE_GetStartNb());

#ifdef WITH_PERSISTANT

    if(APP_ZIGBEE_GetStartNb() < 2U)

#endif

    {

      /* Using ZbStartupWait (blocking) here instead of ZbStartup, in order to demonstrate how to do

       * a blocking call on the M4. */

      status = ZbStartupWait(zigbee_app_info.zb, &config);

 

      APP_DBG("ZbStartup Callback (status = 0x%02x)\n", status);

      zigbee_app_info.join_status = status;

 

      if (status == ZB_STATUS_SUCCESS) {

        join_time_duration = (double)(HAL_GetTick() - join_start_time)/1000;

        APP_DBG("%s==> JOIN SUCCESS, Duration = (%.2f seconds)%s\n", COL_MAGENTA, join_time_duration, COL_NORM);

        zigbee_app_info.join_delay = 0U;

        zigbee_app_info.init_after_join = true;

        BSP_LED_On(LED_BLUE);

      }

      else

      {

        APP_DBG("Startup failed, attempting again after a short delay (%d ms)", APP_ZIGBEE_STARTUP_FAIL_DELAY);

        zigbee_app_info.join_delay = HAL_GetTick() + APP_ZIGBEE_STARTUP_FAIL_DELAY;

      }

    }

#ifdef WITH_PERSISTANT

    else

    {

      /* Restart from persistence */

      if (APP_ZIGBEE_ZbStartupPersist(zigbee_app_info.zb) == ZB_STATUS_SUCCESS)

      {

        APP_DBG("APP_ZIGBEE_ZbStartupPersist SUCCESS!");

        zigbee_app_info.join_status = ZB_STATUS_SUCCESS;

        BSP_LED_On(LED_BLUE);

      }

      else

      {

        APP_DBG("APP_ZIGBEE_ZbStartupPersist FAILED!");

      }

    }

#endif //WITH_PERSISTANT

  }

 

  /* If Network forming/joining was not successful reschedule the current task to retry the process */

  if (zigbee_app_info.join_status != ZB_STATUS_SUCCESS)

  {

#if (CFG_FULL_LOW_POWER == 1)

      /* Enabling Stop mode */

      UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);

#endif /* CFG_FULL_LOW_POWER */

    //UTIL_SEQ_SetTask(1U << CFG_TASK_ZIGBEE_NETWORK_FORM, CFG_SCH_PRIO_0);

 

  }

  else  /* JOIN successful */

  {

    zigbee_app_info.init_after_join = false;

 

    /* Do it only first time */

    if(APP_ZIGBEE_GetStartNb() == 1U)

    {

#if (CFG_FULL_LOW_POWER == 1)

      /* Enabling Stop mode */

      UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);

#endif /* CFG_FULL_LOW_POWER */

      /* Assign ourselves to the group addresses */

      APP_ZIGBEE_ConfigGroupAddr();

 

      /* Since we're using group addressing (broadcast), shorten the broadcast timeout */

      uint32_t bcast_timeout = 3;

      ZbNwkSet(zigbee_app_info.zb, ZB_NWK_NIB_ID_NetworkBroadcastDeliveryTime, &bcast_timeout, sizeof(bcast_timeout));

 

      APP_DBG("==> Start_ZB Task Toggle");

      /* Start First Toggle */

      APP_ZIGBEE_Process_OnOff_Toggle();

      /* Next toggle after TOGGLE_INTERVAL */

      HW_TS_Start(Timer_ToggleOnOff_Id, (uint32_t)TOGGLE_INTERVAL);

    }

  }

 

}

Test Results: The minimum current remained around 3 mA, indicating that it did not enter full low-power mode.

DL_Weng_3-1731059960201.png

 

 

Summary:

According to the test results, it appears that the Dynamic M0 firmware might require a Zigbee connection to achieve low-power operation. Is it possible to provide a version or configuration of the Dynamic M0 firmware that allows low-power operation with only Bluetooth connected and without requiring Zigbee?

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ouadi
ST Employee

Hi @DL_Weng,

The BLE_Zigbee_Dyn requires the initialization of both BLE and Zigbee stack, if you want to start only one of these two protocols I recommend to use the static concurrent mode => stm32wb5x_BLE_Zigbee_RFD_static_fw.bin

Best regards,

Ouadi

View solution in original post

1 REPLY 1
Ouadi
ST Employee

Hi @DL_Weng,

The BLE_Zigbee_Dyn requires the initialization of both BLE and Zigbee stack, if you want to start only one of these two protocols I recommend to use the static concurrent mode => stm32wb5x_BLE_Zigbee_RFD_static_fw.bin

Best regards,

Ouadi