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

Not sure on how to extend the saadc example to multiple analog input pins and cut out delay

Hi all,

I've gotten the saadc example working on my product, reading in values as I would expect. However, I have two problems. First, I want to be able to use multiple input pins after I first initialize the adc. Since the channel choice (`channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7)`) is at the very top of the init code, it seems like I'd have to run the init again with a different NRF_SAADC_INPUT chosen in order to use a different channel. Is this incorrect? If so, how do I simultaneously enable multiple channels.

Second, I've had to build a 5-second delay into my AdcRead function in order to give the ADC enough time to collect sample. If I shorten the delay or return a value immediately, I get an error saying that the ADC is busy. I've inserted my code below for clarity.

My init function looks like:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ret_code_t err_code;
nrf_saadc_channel_config_t channelConfig =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);
err_code = nrf_drv_saadc_init(NULL, saadcCB);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(0, &channelConfig);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(ADCBufferPool[0], SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(ADCBufferPool[1], SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And my AdcRead function looks like:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ret_code_t err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
APP_ERROR_CHECK(err_code);
// setup m_timer for compare event every 400ms
uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);
nrf_drv_timer_extended_compare(&m_timer,
NRF_TIMER_CC_CHANNEL0,
ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false);
nrf_drv_timer_enable(&m_timer);
uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
NRF_TIMER_CC_CHANNEL0);
uint32_t saadc_sample_task_addr = nrf_drv_saadc_sample_task_get();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

This is my callback event handler:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uint32_t adcValAccum = 0;
uint16_t i;
ret_code_t err_code;
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
for (i = 0; i < SAMPLES_IN_BUFFER; i++)
{
adcValAccum += p_event->data.done.p_buffer[i];
}
AdcRetVal = adcValAccum / 5;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX