This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to implement low-power devices using nrf52840

Hi all,

I am developing a low power product based on the nrf52840 module, using the openthread stack from NCS (v1.4.99). Since the device is powered by battery only and needs to save energy, it is usually better to let the device sleep and then it will only be woken up by interrupts.

I think setting the device to MTD seems to meet my needs, so i tried to turn off the transceiver with this official guide for the purpose of reducing sleep power consumption. I found that after pressing button2 on MTD_COAP_CLIENT, LED4 of COAP_SERVER will light up immediately regardless of whether the device state is switched to SED or MED. I think this example doesn't reflect the state of putting the transceiver to sleep.

I have also tried turning on the following option on NCS:

CONFIG_OPENTHREAD_MTD=y
CONFIG_OPENTHREAD_MTD_SED=y
CONFIG_OPENTHREAD_POLL_PERIOD=30000

I have set a program that will send a message out for 15S and then the POLL_PERIOD is 30000. I think in the POLL_PERIOD, no message should be sent out, but I can still catch the message every 15 seconds. So I think the method of setting MTD doesn't seem to meet my needs or current MTD example does not work as expected.

Therefore, I also want to ask how to call the function to put the CPU into hibernate state when needed? I didn't find a good example that works, please give me some advice. 

Thanks in advance.

Best,

Tao

Parents
  • Hi Tao,

    Keep these two principles in mind:

    1. A SED only starts to work on sleepy mode when the SED's radio is considered idle, which means it is not actively transmitting (sending data to Parent) or trying to receive via an IEEE 802.15.4 Data Request transmission. 

    2. CoAP is a kind of protocol that client sends the request to a server.

    You use a SED to send messages actively, so the message will transmit to the parent device directly. 

    If you use SED as CoAP server and FTD as CoAP client, you will experience a significant delay between pushing the button and light up. Please refer to this ticket for detail: How do I set up CoAP Server whit SED on Nrf Connect SDK v1.4.0

    Best regards,

    Charlie

  • Hi Charlie,

    Thanks for your suggestion.

    I'll experiment with this example you gave right away.

    But I still have a question, the SED feels like it just turns off the transceiver, so how do I put the CPU in a sleep state?

    Best regards,

    Tao

  • Yes, this is correct. More accurately it turns off the receiver. Transmitter only works when you seed a message but the receiver needs to wait for the message all the time when SED is not enabled.

    coap_client_utils.c
    static void toggle_minimal_sleepy_end_device(struct k_work *item)
    {
    	otError error;
    	struct otInstance *instance = openthread_get_default_instance();
    	otLinkModeConfig mode = otThreadGetLinkMode(instance);
    
    	mode.mRxOnWhenIdle = !mode.mRxOnWhenIdle;
    	error = otThreadSetLinkMode(instance, mode);
    	if (error != OT_ERROR_NONE) {
    		LOG_ERR("Failed to set MLE link mode configuration");
    	} else {
    		on_mtd_mode_toggle(mode.mRxOnWhenIdle);
    	}
    }
    
    thread.h
    typedef struct otLinkModeConfig
    {
        bool mRxOnWhenIdle : 1;       ///< 1, if the sender has its receiver on when not transmitting. 0, otherwise.
        ...
    } otLinkModeConfig;

    If you want to achieve a low power consumption state, you can only work on the platform layer like mentioned in the discussion on that link:

    1. Power management should be handled at the platform layer. For example, if there are no platform-specific events pending, the platform can go to sleep until the next event (e.g. alarm timer fire).

    That means the OpenThread stack maintains itself to wake up every period of time. For your own application codes, you can keep the peripherals IDEL and only work when the SED wakes up.

    Best regards,

    Charlie

  • Hi Charlie,

    Thank you for your suggestion.

    But I still have a question.

    How do I make this power management work? My understanding is that there should be a function that after calling it, the CPU goes to sleep and stops all activities. Then when the interrupt comes, the CPU is woken up again and continues to run the program context before the last sleep. Is there a ready-made example that tells me how to make the CPU go to sleep actively?

    Best regards,

    Tao

  • Hi Tao,

    I think you mean the system off mode supported by nRF52840. This is quite a low-level power saving mode which is not fit for Openthread based application.

    As you know, Opthenthread is developed by google and supports different kinds of MCU. It needs to keep the CPU running to maintain the Thread stack, it only supports limited general power-saving methods, like shutting down RX in SED. On your own application side, turn off the peripheral while waiting for the message.

    If you are quite sensitive to power consumption on your application, you have to think about other solutions like BLE.

    Best regards,

    Charlie

Reply
  • Hi Tao,

    I think you mean the system off mode supported by nRF52840. This is quite a low-level power saving mode which is not fit for Openthread based application.

    As you know, Opthenthread is developed by google and supports different kinds of MCU. It needs to keep the CPU running to maintain the Thread stack, it only supports limited general power-saving methods, like shutting down RX in SED. On your own application side, turn off the peripheral while waiting for the message.

    If you are quite sensitive to power consumption on your application, you have to think about other solutions like BLE.

    Best regards,

    Charlie

Children
No Data
Related