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

ADC can only convert once

I have setup a timer interrupt whivh fires at about 10 seconds which I can follow on an RTT viewer the ISR demands two ADC's to convert the voltage levels on their pins,  I can follow from RTT viewer that every 10 seconds the timer ISR is visited but the ADC ISR is visited only once it seems that ADC's should be reset somewhere but I do not know where. I am also running the BLE advertising mode. Below is the excerpts of the code that I think are relevant to the problem. SDK v12.3 Keil 5.29

static void TimerInit()
{
uint32_t err_code;
// APP_TIMER_INIT(32767, OP_QUEUE_SIZE, NULL);
APP_TIMER_DEF(timer_0);
err_code = app_timer_create(&timer_0, APP_TIMER_MODE_REPEATED , timer0_handler);
app_timer_start(timer_0, 327680, NULL); // 10 second repeat rate
NRF_LOG_INFO("BLE YPT in Timer init\r\n");
}

static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
NRF_LOG_INFO("\t\t\t YPT in ADC event Handler\r\n");
if (p_event->type == NRF_DRV_ADC_EVT_DONE)
{
uint32_t i;
for (i = 0; i < p_event->data.done.size; i++)
{
NRF_LOG_INFO(" chan%d ADC value: %d\r\n",i, p_event->data.done.p_buffer[i]);
}
}
}

static void adc_config(void)
{
ret_code_t ret_code;
nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;

ret_code = nrf_drv_adc_init(&config, adc_event_handler);
APP_ERROR_CHECK(ret_code);
NRF_LOG_INFO("\t\t YPT in ADC config \r\n");
nrf_drv_adc_channel_enable(&chn0);
nrf_drv_adc_channel_enable(&chn1);
nrf_drv_adc_buffer_convert(adc_buffer,ADC_BUFFER_SIZE);
}

static void timer0_handler(void * p_context)
{

// Does nothing usefull just prints out the counter value
NRF_LOG_INFO("cnt = %d BLE YPT in Timer handler \r\n", counter++);
nrf_drv_adc_sample();
}

  • Hello,

    What is your ADC_BUFFER_SIZE?
    The DONE event will be triggered when the buffer is full - and then you will need to specify a new buffer for the ADC to start filling.
    From the code you have shared it seems that you only call buffer_convert() during adc_config.
    You will need to supply a new buffer every time a buffer is filled up, to continue sampling.

    For future reference, it is highly beneficial if you would use the "Insert->code" option when sharing code snippets, as it greatly increases readability.

    Best regards,
    Karl

  • Hi Karl,

    Thank you for your prompt response, as the buffer was declared static, I did not realize that I had to declare a new buffer every time DONE event occurred, so inserting nrf_drv_adc_buffer_convert(.....) at the end of the ADC ISR handler solved the problem.

    Best regards,

  • Hello again,

    I am happy that this resolved your issue!
    Yes, buffer_convert must be called in order to continue the sampling - to designate a new buffer for the SAADC to fill.

    If you are doing rapid sampling and are worried about loosing a sample between buffers, you might want to use the SAADC's double buffering feature.
    The feature is demonstrated in the SAADC peripheral example in the SDK.

    Please do not hesitate to open a new ticket if you should encounter any other issues or questions in the future.
    Good luck with your development! 

    Best regards,
    Karl

Related