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

app_time and nrf_delay_ms

Hi

I would like to read values from three AD channels where I use different sampling frequencies and different number of samples are captured at each sampling frequency. To be clear I will explain my problem in the case of one channel. Every 10s I would like to capture five values from the actual channel and subsequently the averaging is performed. The time between each sample should be around 10ms. At this stage I do not know what is the best programming solution for my problem to be the sofware as efficient as possible. Here is my current code, where I used nrf_delay_ms(10) function for waiting between two samples. I know that this is not the most efficient way because of that I will appreciate for any advice how I can improve my code.

Best regards

Samo

static void adc_lpg_timer_handler(void * p_context) // timer executed every 10s
{ 	
	
	int i;
	nrf_adc_value_t adc_value;
	uint8_t err_code;
	uint16_t ave_adc = 0;
	
	nrf_gpio_pin_toggle(LPG_PIN);	
	
	for(i=0; i < 5; i++)
	{
		nrf_delay_ms(10);
		while(nrf_drv_adc_is_busy())
		{
		}	
		err_code = nrf_drv_adc_sample_convert(&adc_lpg,&adc_value);
		APP_ERROR_CHECK(err_code);
	
	  ave_adc = ave_adc + adc_value;
  }
	 ave_adc = ave_adc/5;
	 ave_adc = 1200*ave_adc/1023;	 	 	
	 err_code = ble_adcs_2_update(&m_adcs,ave_adc);	 
	 APP_ERROR_CHECK(err_code);
	 ave_adc = 0;	   		
	 
	 nrf_gpio_pin_toggle(LPG_PIN);	
}
  • Hi,

    Have a look at the application timer tutorial. It describes how to set up energy efficient timers and interrupts in which you can perform your measurements. For example you can use one timer instance to trigger interrupts every 10 s and then every 10 ms after that. The reason you do not want to use nrf_delay_ms is that it implements waiting by calling a sequence of NOP__ to the processor core, keeping it active and thus drawing current.

    Best regards,

    Øyvind

  • Hi Øyvind,

    thanks for fast reply. Do you have in mind the following idea? What is better solution to using one timer (such as presented in my code) or two timers, where the first timer which is triggered every 10s enables the second timers which has frequency 1/10ms. The latter one is executed 5 times to get 5 samples from ADC.

    Thanks for answer in advance.

    Best regards

    Samo

    static void experimental_timer_handler(void * p_context)
    {	
    	uint8_t err_code;
    	
    	static int counter = 0;
    	
    	counter++;	
    	
    	if(counter == 1)
    	{
    	app_timer_stop(m_experimental_timer_id);	
    	err_code = app_timer_start(m_experimental_timer_id, APP_TIMER_TICKS(10, APP_TIMER_PRESCALER),NULL);
    	}	
    	else if (counter > 1 && counter <= 6)
    	{
    	 // ad sampling five times
    	}
    	else // counter > 6
    	{
    		app_timer_stop(m_experimental_timer_id);	
    	  err_code = app_timer_start(m_experimental_timer_id, APP_TIMER_TICKS(10000, APP_TIMER_PRESCALER),NULL);
    		counter = 0;
    	}
    }
    
  • Hi,

    I think this should work fine, for an even more energy efficient solution you could try triggering your measurement using PPI. When using PPI you can connect the compare event from a timer to different tasks, this way you don't need to wake up the CPU to do many of the tasks you want to do.

    Since timers are using the same clock resource you will not see a tremendous increase in power consumption with multiple timers.

    Best regards,

    Øyvind

  • Hi,

    Thanks for answers. If I know correctly it is not possible to connect app_timer with any tasks by PPI. If I would like to apply PPI I have to make own TIMER seperately which uses high-frequency clock source. Is my assumption correct?

  • The events generated by the capture compare (CC) register in the real time counter (RTC) module, which uses the low frequency clock, will allow you to trigger tasks via PPI.

Related