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

How to implement a simple non-blocking delay on nRF51822 with SoftDevice

Using nrf_delay_ms() can be energy consuming and indeterministic. I am trying to use application timers (from "app_timer.h") in nRF SDK 8.0. The way I did could be partially described as follows:

#define LED_DURATION_IN_MS    400   
#define LED_DURATION_TICKS      APP_TIMER_TICKS(LED_DURATION_IN_MS, APP_TIMER_PRESCALER)

static app_timer_id_t m_lazy_wait_timer;
static volatile uint8_t lazy_wait_flag = 0;

static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}

void lazy_wait_handler(void * p_context)
{ 
	// Clear the wait flag 
	lazy_wait_flag = 0;
}

static void timers_init(void)
{
  APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
  err_code = app_timer_create(&m_lazy_wait_timer, APP_TIMER_MODE_SINGLE_SHOT, lazy_wait_handler);
  APP_ERROR_CHECK(err_code);
}
	
void main()
{
    ...
    ...

    timers_init();
    nrf_gpio_cfg_output(1);
    nrf_gpio_pin_set(1);
    uint32_t err_code = app_timer_start(m_lazy_wait_timer, LED_DURATION_TICKS, NULL);
    APP_ERROR_CHECK(err_code);
    lazy_wait_flag = 1;
    while(lazy_wait_flag) {
        power_manage();
    }
    nrf_gpio_pin_clear(1);

    for (;;)
    {
        app_sched_execute();
        power_manage();
    }
}

However, the code doesn't work as expected. It seems the "lazy_wait_flag" is not cleared and the code is stuck in the while loop. What is the correct way of doing it?

Parents
  • Hello. Your last parameter in APP_TIMER_APPSH_INIT is "True", which means that you intend to use the scheduler. However, the scheduler is not run in your while loop. Try setting the last parameter to "False", or run app_sched_execute() in the while loop.

    Edit: About using the app_scheduler:

    The main reason to use this module, is to execute some procedure from main context (low priority) instead of the interrupt context (higher priority). If your procedure is short and have real time timing requirements, you should execute it directly in the interrupt handler and not use the scheduler. If your procedure takes some time, and timing is not critical, the scheduler is a good way to ensure that you procedure does not interfere with more important tasks.

    The documentation of the app_scheduler can be found here.

Reply
  • Hello. Your last parameter in APP_TIMER_APPSH_INIT is "True", which means that you intend to use the scheduler. However, the scheduler is not run in your while loop. Try setting the last parameter to "False", or run app_sched_execute() in the while loop.

    Edit: About using the app_scheduler:

    The main reason to use this module, is to execute some procedure from main context (low priority) instead of the interrupt context (higher priority). If your procedure is short and have real time timing requirements, you should execute it directly in the interrupt handler and not use the scheduler. If your procedure takes some time, and timing is not critical, the scheduler is a good way to ensure that you procedure does not interfere with more important tasks.

    The documentation of the app_scheduler can be found here.

Children
No Data
Related