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

  • Hi.

    I apologize that this was left unanswered.

    Do you still need assistance on this? Or did you find the answer to your questions?

    Br,
    Joakim

  • Hi  

    I actually did find the solution to this. I achieved it by first turning off the UART, then provisioning bearers, and then mesh.

    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

    And then turn it back on using the opposite statements to these. Works like a charm. 

  •  

    I required the device should be run in low power mode when there is no work to do. so I gone through the state.h and found that there are different states. So I choose  PM_STATE_RUNTIME_IDLE or PM_STATE_SUSPEND_TO_IDLE so just curious like if I select one of them then on some event how to wakeup the device to a normal state.

    Also is there any best state other than PM_STATE_SOFT_OFF which help my device to save more power without losing its context?


    Do I just need to disable/suspend the resources that are taking more power, this will save the power consumption of the battery. CPU will automatically go into sleep mode?

    Can you please enlighten why there are different modes and When to use them? like, PM_STATE_RUNTIME_IDLE, PM_STATE_SUSPEND_TO_IDLE, PM_STATE_STANDBY and 

    PM_STATE_SUSPEND_TO_RAM.
    Also how to use them?


    Do I need any power state to set other than PM_STATE_SOFT_OFF?
  • Can you please enlighten why there are different modes and When to use them? like, PM_STATE_RUNTIME_IDLE, PM_STATE_SUSPEND_TO_IDLE, PM_STATE_STANDBY and 

    I'm not really sure about the other states. From what I remember, PM_STATE_SUSPEND_TO_RAM, PM_STATE_SUSPEND_TO_DISK, and PM_STATE_SOFT_OFF had the same power consumption during sleep mode for the nRF52832. For other controllers I don't know. 

    Not to mention I measured these 9 months ago, so any updates in the SDK might have changed the power consumption or the three modes might not be the same anymore. 

    Also is there any best state other than PM_STATE_SOFT_OFF which help my device to save more power without losing its context?

    I don't think so. 

    Do I just need to disable/suspend the resources that are taking more power, this will save the power consumption of the battery. CPU will automatically go into sleep mode?

    Not a 100% sure about this either, but from what I noticed, if no active thread is running (or if every thread is performing `k_sleep(...)` and the appropriate power management mode is selected, the CPU will be in sleep mode. 

Related