BLE mesh device entering sleep / low power mode in nRF Connect SDK

Hi.

I am working on a low power BLE mesh device, based on the nRF52832, that uses vendor models. By default it consumes about 7mA.

Aside from that, I have been able to get the power consumption down to 3uA in a low power mode, in another (non BLE) project.

struct pm_state_info info =
{
    .exit_latency_us  = 0,
    .min_residency_us = 0,
    .state            = PM_STATE_SUSPEND_TO_RAM,
    .substate_id      = 0,
};
pm_state_force(CPU_ID, &info);

const struct device *cons = device_get_binding(CONSOLE_LABEL); // get UART binding
int rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); // disable UART
k_sleep(K_SECONDS(5));                                         // sleep for 5 seconds
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME);      // enable UART again

However, when I try to use the same code to get the BLE mesh device to sleep, it makes next to no difference, the power draw reduces from 7mA to 6.8 mA.

I also used mesh suspend, mesh resume, and BT disable commands. 

bt_mesh_suspend();
bt_disable();

k_sleep(K_SECONDS(5)); // sleep for 5 seconds

bt_mesh_resume();

That didn't make any difference either.

Is there a proper way to turn off BLE and BLE mesh, before putting the chip into sleep mode? Most of the references and examples I find here are for nRF5 SDK for Mesh but I am using nRF Connect

Any help would be greatly appreciated. Thanks in advance Slight smile

Parents Reply Children
  • You can have a time based wake-up or a GPIO based wake-up. There can be more but these two are the only ones I have tested.

    To setup the controller for sleep, you can have something like this

    void set_pm_state()
    {
        struct pm_state_info info =
        {
            .exit_latency_us  = 0,
            .min_residency_us = 0,
            .state            = PM_STATE_SUSPEND_TO_RAM,
            .substate_id      = 0,
        };
        pm_state_force(CPU_ID, &info);
    }

    Then whenever you have to put it to sleep, you can have this code in a function

    void pre_sleep()
    {
        const struct device *cons = device_get_binding(CONSOLE_LABEL); // get UART device
        pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);          // turn off UART
        bt_mesh_prov_disable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);    // disabling provisioning bearer
        bt_mesh_suspend();                                             // turn off mesh
    }

    For sleep, use

    k_sleep(milliseconds) // for specified time
    k_sleep(K_FOREVER)    // for sleeping without a timeout

    And then after waking up

    void post_sleep()
    {
        bt_mesh_resume();                                              // turn on mesh
        bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);     // enabling provisioning bearer
        const struct device *cons = device_get_binding(CONSOLE_LABEL); // get UART device
        pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME);           // turn off UART
    }

    Hope this helps. Slight smile

Related