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

Application timers not working properly

Hello Everyone

I am using two application timers one of standard battery service and one i have made for adc sampling like this along with the code added for battery timers

timers_init()
{
....

err_code = app_timer_create(&m_adc_sampling_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                adc_sampling_timeout_handler);
}

application_timers_start()
{

...
 err_code = app_timer_start(m_adc_sampling_timer_id, ADC_SAMPLING_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
}

my ADC_SAMPLING_INTERVAL is set for 5 seconds and battery sampling is set for 2 seconds. whenever adc sampling timer is out ... it will trigger for adc sampling

void adc_sampling_timeout_handler(void * p_context)
{
   UNUSED_PARAMETER(p_context);
    uint32_t p_is_running = 0;
    sd_clock_hfclk_request();
    while(! p_is_running) 
    {  
        /** wait for the hfclk to be available */
        sd_clock_hfclk_is_running((&p_is_running));
    }               
    NRF_ADC->TASKS_START = 1;                   /** Start ADC sampling */ 
}

this will call ADC IRQ

void ADC_IRQHandler(void)
{
    static uint8_t adc_count = 0;
    /* Clear dataready event */
    NRF_ADC->EVENTS_END = 0;	

    battery_values[adc_count] = NRF_ADC->RESULT;
    if(adc_count > 4)
    {
        current_battery_value = (battery_values[0] + battery_values[1] + battery_values[2] + battery_values[3] + battery_values[4]) / MAX_ADC_SAMPLES;
        memset(battery_values,0,sizeof(battery_values));
        simple_uart_put(current_battery_value);
        adc_count = 0;
    }
    else
    {
        simple_uart_put(battery_values[adc_count]);    
        simple_uart_put(adc_count);
        adc_count++;
    }
    
    NRF_ADC->TASKS_STOP = 1;
    //Release the external crystal
    sd_clock_hfclk_release();
    
}	

As shown in the above code it will take 5 samples and average it. each samples shud be taken at the interval of 5 seconds . but in my case 1st sample is taken at the interval of 5 seconds, at another 5 seconds 2nd and 3rd sample are taken together then 4th sample at 5 seconds of interval then again 5th and final sample is taken together at the interval of 5 seconds. which is not what i want each sample shud be taken at the interval of 5 second. can anybody tell me what can be the problem.

Regards Asma

Parents
  • Hi asma

    Your code looks a lot like the code in this example. In the linked example, the ADC interrupt is set to NRF_APP_PRIORITY_LOW which you must do explicitly in your code. Try that, then let us know how it turns out.

  • Hi stefan i have already set the priority to low. here is my code for adc_init

    void ADC_Init(void)
    {	
        /* Enable interrupt on ADC sample ready event*/		
        NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
        sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
        sd_nvic_EnableIRQ(ADC_IRQn);
    
        NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos)               /** Bits 17..16 : ADC external reference pin selection. */
                | (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)					        /** < Use analog input 2 as analog input. */
                | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							    /** < Use internal 1.2V bandgap voltage as reference for conversion. */
                | (ADC_CONFIG_INPSEL_AnalogInputNoPrescaling << ADC_CONFIG_INPSEL_Pos)    /** < Analog input specified by PSEL with no prescaling used as input for the conversion. */
                | (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/** < 8bit ADC resolution. */ 
    
        /* Enable ADC */
        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
    }
    
Reply
  • Hi stefan i have already set the priority to low. here is my code for adc_init

    void ADC_Init(void)
    {	
        /* Enable interrupt on ADC sample ready event*/		
        NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
        sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
        sd_nvic_EnableIRQ(ADC_IRQn);
    
        NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos)               /** Bits 17..16 : ADC external reference pin selection. */
                | (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)					        /** < Use analog input 2 as analog input. */
                | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							    /** < Use internal 1.2V bandgap voltage as reference for conversion. */
                | (ADC_CONFIG_INPSEL_AnalogInputNoPrescaling << ADC_CONFIG_INPSEL_Pos)    /** < Analog input specified by PSEL with no prescaling used as input for the conversion. */
                | (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/** < 8bit ADC resolution. */ 
    
        /* Enable ADC */
        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
    }
    
Children
No Data
Related