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

nrf52832 sleep mode from android app

I am currently looking at how to put the nrf52 development board to sleep (and wake up) by sending a command from an android application (with SDK v15.2).

I have been experimenting with the nrfBlinky app and wanted to know if anyone has some advice on how one would go about doing this.

I have searched the forums but couldn't find a similar question although there are posts about calling __WFE() to put the board in low power mode from the firmware (or calling an event like sd_app_evt_wait()). I did read there are two sleep mode for this board a SYSTEM ON and SYSTEM OFF mode. I am not certain which mode suits the use case best, although I assume we would want the SYSTEM ON mode as the app would need to send an event to wake it up. Although I wouldn't be against a SYSTEM OFF mode where the reset button would need to be pressed to wake it up (so just sending a "put to sleep" command from the app). 

Any advice would be much appreciated.

Parents
  • Have you taken a look at the examples in SDK 15.2? In most of the examples, the chip is in System ON sleep mode most of the time. The way it is done is by putting the sleep function in a for loop (as Ashish mentioned). Most of the functionality related to the nRF52 chip is event driven, and is perfectly compatible with this approach.

    E.g, in the SAADC example, the chip is put to System ON sleep in a while(1) loop through the function nrf_pwr_mgmt_run(), then if  ADC data is received, the chip breaks the sleeps mode, handles the ADC event, then continues on the line after nrf_pwr_mgmt_run(). Since the function is inside a while loop, it will loop around and go to sleep once again.  The BLE examples are also event driven, and works in the same manner as the ADC example. 

    This approach only works for System ON sleep mode, and event driven activity.

    However, please tell me if you are aware of this and have a reason for invoking sleep mode yourself. If you could explain your project in more details, I would be able to give you a more constructive answer.

    Best regards,

    Simon

  • Thank you for the reply Simon.

    So I am aware of the SDK samples, probably didn't fully understand what they were doing, so thank you (and Ashish) for clarifying.

    For the project that I am working on, I would like to send a sleep command to the BLE board from an Android device (untethered so not through uart), similar to the Blinky app where you press a switch control to turn a light on the board. I was unsure the correct steps to follow to simulate this event and how one would get the board to go to sleep.

    1. So for now what I would like to do is to create an LED type event structure for an Android app (e.g. sleep button) that could put the board into sleep mode (System OFF), essentially turn it off where a person would have to press the reset button on the board to wake it up (how do you put the board into System OFF sleep?).

    2. Then as a later goal to implement the System ON mode where an event from the Android app could put the board to sleep and then another event (say turning a switch control on/off) to wake it up.

    Any ideas?

  • Question 1

    There are many ways of doing this, but here I am presenting one approach. You could use the ble_app_uart peripheral example along with nRF Connect for Mobile as a starting point. Then you could put the board into System OFF sleep mode, if a specific message (e.g. 123) is received. In order to achieve this you have to modify the function nus_data_handler(), specifically you need to check if the received data is equal to the correct value (e.g. 123), and run sd_power_system_off() if that is the case.

    If you are developing your own mobile app, you could make a button that only sends out the specific message. 

    Question 2

    For putting the board into System ON, you could use the same approach as explained above, just with another value (e.g. 456). I would recommend you to take a look at the Button handling library, which will generate GPIOTE events when a button is pressed, and consecutively wake the device up from System ON sleep.

    Best regards,

    Simon

Reply
  • Question 1

    There are many ways of doing this, but here I am presenting one approach. You could use the ble_app_uart peripheral example along with nRF Connect for Mobile as a starting point. Then you could put the board into System OFF sleep mode, if a specific message (e.g. 123) is received. In order to achieve this you have to modify the function nus_data_handler(), specifically you need to check if the received data is equal to the correct value (e.g. 123), and run sd_power_system_off() if that is the case.

    If you are developing your own mobile app, you could make a button that only sends out the specific message. 

    Question 2

    For putting the board into System ON, you could use the same approach as explained above, just with another value (e.g. 456). I would recommend you to take a look at the Button handling library, which will generate GPIOTE events when a button is pressed, and consecutively wake the device up from System ON sleep.

    Best regards,

    Simon

Children
  • Thanks again for the reply and ideas on how to solve my questions.

    So just to make sure, if I use the SDK blinky app example, I believe it already implements System ON mode, as I can see that  nrf_pwr_mgmt_run() is run in a for(;;) loop. So what I tried was to add another button event handler in the SDK to say Button 2 of the dev board, that calls sd_power_system_off() to test if i can put the board in system OFF mode but that doesn't seem to work.

    Therefore based on your reply for Question 1, you mention looking at the ble_uart example which uses a softdevice which I don't believe I am using. Is this then the only way to get the device to sleep in a System OFF mode and why my test didn't work or have I missed something? 

  • mialo_5 said:
    Therefore based on your reply for Question 1, you mention looking at the ble_uart example which uses a softdevice which I don't believe I am using. Is this then the only way to get the device to sleep in a System OFF mode and why my test didn't work or have I missed something? 

    Why does it not work? Have you tried to debug and see what error messages you get?

    mialo_5 said:
    Therefore based on your reply for Question 1, you mention looking at the ble_uart example which uses a softdevice which I don't believe I am using. Is this then the only way to get the device to sleep in a System OFF mode and why my test didn't work or have I missed something? 

    If you want control your device from an android app you need a SoftDevice (which handles all low level BLE activity). The reason I recommended you the ble_app_uart example is because it is a quite simple example which uses the SoftDevice.

  • Thanks for your help although I don't believe I am getting to the answer I'm looking for.

    Maybe if I rephrase the question as follows:

    I am using the nrfBlinky Android app with an nrf52832. I would like to press a button on the dev board to put the board into a system off (sd_power_system_off() or nrf_pwr_mgmt._shutdown()) sleep mode where I can only recover by pressing RESET button on the board.

    If I create a static variable "m_is_sleep_mode" to store if BSP_BUTTON_1 is pressed and check that it is true in the main function (in the for(;;) loop I assume), see code snippet, the board seems to perform a reset (the connection drops and comes back up immediately) but has not gone into a power down mode.

    Thoughts this time?

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
        ret_code_t err_code;
    
        switch (pin_no)
        {
            case LEDBUTTON_BUTTON:
                NRF_LOG_INFO("Send button state change.");
                err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, button_action);
                if (err_code != NRF_SUCCESS &&
                    err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                    err_code != NRF_ERROR_INVALID_STATE &&
                    err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;
    
            case SLEEPBUTTON_BUTTON:
                m_is_sleep_mode = true;
                break;
    
            default:
                APP_ERROR_HANDLER(pin_no);
                break;
        }
    }

    static void buttons_init(void)
    {
        ret_code_t err_code;
    
        //The array must be static because a pointer to it will be saved in the button handler module.
        static app_button_cfg_t buttons[] =
        {
            {LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler},
            {SLEEPBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler}
        };
    
        err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
                                   BUTTON_DETECTION_DELAY);
        APP_ERROR_CHECK(err_code);
    }

    int main(void)
    {
        // Initialize.
        ....
    
        // Enter main loop.
        for (;;)
        {
            if (m_is_sleep_mode)
            {
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
            }
            else
            {
                idle_state_handle();        
            }
        }
    }
    
    

  • Have you taken a look at the nrf_pwr_mgmt example? That might give you a better understanding of the System OFF sleep mode.

Related