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

Slow Wake-Up and Timer Start from Power Off

Hello,

I am trying to set the nRF52 to power off and wake up on a momentary button push (scope measures momentary push logic low around 50ms-100ms). However, I am struggling to have my debounce timer start up fast enough to detect the button being still pressed. If I hold the button down for a longer press, 200ms+, then I am able to read the button pin as registering a press in my debounce timer. The nRF52 tOFF2ON is stated as 16.5us, so I am thinking the timer is not starting fast enough or the button pin is not setup quick enough? Any direction would be very helpful!

First I set up my button input and debounce timer:

int
main (void)
{
  uint32_t err_code;
  uint32_t time_ticks;
  uint32_t time_ms = 1; //Time(in miliseconds) between consecutive compare

  //Initialize.
  err_code = NRF_LOG_INIT(NULL);
  APP_ERROR_CHECK(err_code);

  /*********** Manual Input Config ******************/
  err_code = nrf_drv_gpiote_init ();
  APP_ERROR_CHECK(err_code);
  //nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
  in_config.pull = NRF_GPIO_PIN_PULLUP;
  err_code = nrf_drv_gpiote_in_init (BUTTON_1, &in_config, in_pin_handler);
  APP_ERROR_CHECK(err_code);
  nrf_drv_gpiote_in_event_enable (BUTTON_1, true);

  // Check initial button state
  if (button1_is_pressed())
    {
      btnpressed = 1;
    }

  /*********************************************/

  /*********** Timer Config ******************/
  nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
  err_code = nrf_drv_timer_init (&TIMER_LED, &timer_cfg,
				 timer_callback_handler);
  APP_ERROR_CHECK(err_code);
  time_ticks = nrf_drv_timer_ms_to_ticks (&TIMER_LED, time_ms);
  nrf_drv_timer_extended_compare (&TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks,
				  NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
  nrf_drv_timer_enable (&TIMER_LED);
  /*****************************/

Here is my code to setup power off:

void
sleep_mode_enter (void)
{

  //uint32_t err_code;

  nrf_drv_gpiote_out_set (LED_1);

  //err_code = bsp_wakeup_button_enable(0);

  //err_code = nrf_gpio_cfg_sense_set( BUTTON_1, BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH :NRF_GPIO_PIN_SENSE_LOW );
  nrf_gpio_cfg_sense_set ( BUTTON_1, NRF_GPIO_PIN_SENSE_LOW);

  // Go to system-off mode (this function will not return; wakeup will cause a reset).
  nrf_drv_timer_compare_int_disable(&TIMER_LED,NRF_TIMER_CC_CHANNEL0);
  nrf_drv_timer_disable (&TIMER_LED);
  sd_power_system_off ();
//  err_code = sd_power_system_off ();
//  APP_ERROR_CHECK(err_code);
  while (1)
    ;
}

Here is my button debounce timer handler, after a short momentary push from wake-up, the system is seeing "state" as false, if I hold the button down for a long press it measures true.

void timer_callback_handler (nrf_timer_event_t event_type, void* p_context)
{
  static uint32_t button_debounce = 0;

  bool state;
  switch (event_type)
    {
    case NRF_TIMER_EVENT_COMPARE0:
      total_ticks++;
      state = button1_is_pressed();
      if (state && btnpressed) // Still held down
	{
  • @LukeC

    OK. I see what you are doing.

    But I'm not sure how the logic of this is going to work..

    Assuming it takes 50mS to start up from cold, and your button takes 200mS to settle down,

    Then you won't know for 200mS whether its a long or a short press (or perhaps 200mS is the time for a long press - not that makes any difference to this)

    So how is it possible to "blast out" an advertising packet and go back to sleep in under the time taken for a long press.

    Or would you immediately blast out an advert (takes about 5mS) and then wait for 200mS and recheck the button, and if so treat it as a long press and change the advert.

    Why are you using Power Off? To extend your battery life on a very small battery? I'm surprised that just turning off advertising would not be low enough power Or are you running from harvested energy?

  • Assuming it takes 50mS to start up from cold, and your button takes 200mS to settle down, Then you won't know for 200mS whether its a long or a short press (or perhaps 200mS is the time for a long press - not that makes any difference to this)

    Well, my hope is that is does not take 50 ms to start up from cold. If it does then i have no option but to assume a wake up without the button pushed continually is a short press.

    Why are you using Power Off? To extend your battery life on a very small battery? I'm surprised that just turning off advertising would not be low enough power Or are you running from harvested energy?

    I am running off a coin cell, i think those usually have a leakage of about a 1uA. Perhaps I should do some tests on sleep current in other modes. The power is just so nice in the off mode it would make this thing rock solid in the battery life department

  • When I did some research into batteries, many claimed "long shelf life" and there are articles saying that some coin cells can have 10 years of operation / shelf life

    However when I read the spec's from both Sony etc, they mostly omit exact figures for shelf life e.g. www.sony.net/.../cr2032.pdf

    Panasonic imply longer shelf / usable life but don't seem to explicitly say what it is.

    Some manufacturers will warrant their batteries for 1 year, but I've not personally seen any warranty beyond that.

    I'm not a battery expert, but most batteries I have experienced seem to have some form of chemical degradation after a few years and often leakage.

  • You can do a quick test of the wake-up time, just toggle a pin at the start of your code and measure the distance between the falling edge that woke up your chip and the pin toggle. Doing this I got around 300us which is reasonable and much less than 50ms.

    It seems to me that you are doing things in a hard way here. You know that the pin woke you up or a reset did it (see here). If you have multiple pins you can wake up from you can read them at startup to find out which one it was. Then you can start a timer to check the pin at a later point in time if the button/pin is still pushed. I would recommend using RTC instead of the TIMER as it draws a lot less current (1uA versus couple of 100uA). The app_timer module is easy to use for this purpose. If you have not used it before you can checkout this tutorial.

  • Ole - Excellent comment, this worked. I am still a bit baffled as to why the app timer starts so much faster than a standard timer. I am able to go to full power down, press a button and catch the button pressed with a few debounce timer increments. Boosting a 200-300na off current with enthrall my client. Thanks!

Related