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

ble_app_hrs_c how to add 1 sec timer and goto sleep mode?

It's battery operation so I want to know how to setup 1sec timer and goto sleep_mode(power_down) after 1sec beacon scanning.

I'm using WDT to setup 60sec WDT reset so I want to scan only 1sec then goto sleep mode for 59sec to save battery lifetime.

Currently it works fine.

Power_on_reset

WDT setup to 60sec.

scanning for 60sec.

WDT_reset

scanning for 60sec.

WDT_reset

so on.....repeated

I want to know how to setup additional 1sec. timer and after 1sec. scanning, device goto sleep mode for 59sec.

I'm using S130 softdevice, ble_app_hrs_c and nRF51_SDK_9.0.0

Parents
  • Hi,

    This can be done easily and elegantly by using the Timer library (app_timer). You could do something like the following:

    1. After power on reset, configure everything including the WDT.
    2. Start scanning, start a single shot timer with a 1 second timeout and feed the watchdog.
    3. After one second, the app timer fires and the timeout handler runs. Here you stop scanning and start a new single shot timer with a 59 seconds timeout.
    4. After 59 seconds the timeout handler of the 59 second timer runs. Here you jump back to 2.

    PS: Remember to add a bit of room for overhead, so that the WDT will not reset the device when it should not (set it to something like 61 seconds instead).

  • I want to go to sleep mode after 1 sec. to save battery. Can I remain 60 sec. WDT to reset?

    It means I set 1 sec. app_timer and 60 sec. WDT and after 1 sec.app_timer  timeout, I put like this into timeout_handler;

    //System Power Down here
        while(1)
        {
            __SEV();
            __WFE();
            __WFE();
      }

    Then the device is into sleep mode and afte 60 sec. WDT reset and repeat same sequency.

    Am I right?

  • Almost. I did not explain that in detail, but the overall structure should be the same as most simple BLE examples in the SDK, which is purely event driven:

    1. Initialize everything.
    2. Eternal main loop does nothing other than going to sleep again (and possible handle deferred logging).

    Here, app timer and BLE events will wake up the system so that the event can be handled. When the interrupt is handled the main thread will run, and it will immediately put the system to sleep again. Note that when you use the SoftDevice you should not call __SEV() or __WFE() directly, but you should call either sd_app_evt_wait() or use the power management library and call nrf_pwr_mgmt_run().

    Your main function should have structure similar to this (pseudo code):

    main
    {
        init_softdevice
        init_wdt
        init_app_timer
    
        while(1)
        {
            sd_app_evt_wait
        }
    }

  • I told you it's battery operation so I have to turn off all power except WDT to get system_reset.

    You mean that __SEV() or __WFE() doesn't work in the code with softdevice?

  • Mike said:
    I told you it's battery operation so I have to turn off all power except WDT to get system_reset.

    I understand it is battery powered (most products using a nRF chip is anyway, so that is always the underlying assumption). There are a few misunderstandings I think we need to clarify:

    • Using the WDT to reset the system like you have suggested does not give you the lowest possible current consumption. Resetting the device every minutes means that you have to initialize everything every minute, which consumes more CPU time. Therefore, this is not a good idea.
    • You cannot keep only the WDT running, The WDT only works when the 32 kHz clock and LDO regulator etc. is running (it need a clock after all). Using your approach, you would have a sleep current of about 2.2 μA and the additional current consumption by constant reinitialization.
    • Using the app_timer as I suggested only adds 0.1 µA to the idle current, but will save you a lot of CPU time doing reinitialization. This is the most power efficient way.
    Mike said:
    You mean that __SEV() or __WFE() doesn't work in the code with softdevice?

    Not exactly, I just mean that you should not use it in the context you have described. The application could call __WFE() directly in some cases, bu in most often it does not make sense.

    If you refer to the BLE examples in the SDK you will see that all of them have a main loop which handle the idle state. This then calls sd_app_evt_wait() (either directly or for instance via nrf_pwr_mgmt_run()), which is the proper way to put the nRF to system ON low power mode. This calls __WFE() internally, which is why you do not need to call it directly. The system on low power mode keeps the 32 kHz clock and RTC active. This has very little current consumption overhead in your case, as you anyway need the 32 kHz oscillator running in order to keep the WDT running. Using the timer_library only adds 0.1 µA to the idle current (it uses an RTC instance), and this is negligible. The typical sleep current consumption in this setup with the WDT running is about 2.3 μA, all included. If you don't use the WDT you can reduce it to 2.0 μA.

  • Thanks a lot, now I understand all.

    I'm not very proffetional on the code, can you guide me how to add init_app_timer and app_timer_IRQhandler into ble_app_hrs_c source code?

    or is there any example code using S130 with app_timer?

    I tried to put app_timer_init() but have got lot of error.

    Your help is very much appreciated.

Reply Children
Related