Hi everyone,
I want to sample eight analog sensors connected on P0.30 through a multiplexer. I created an app_timer that expires every 10ms. When the timer expires I start sampling in non-blocking mode calling the nrf_drv_saadc_sample() in a for loop. The problem is that the event handler (saadc_callback() in my case) I assigned during the SAADC initialization is called just once, during the first iteration of the loop, meaning that just one of the eight sensors is sampled.
// Create SAADC timer. err_code = app_timer_create(&m_SAADC_timer_id, APP_TIMER_MODE_REPEATED, pressure_sensors_read); APP_ERROR_CHECK(err_code); void pressure_sensors_read(struct s_sampling *sampling) { ret_code_t err_code; for (uint8_t i = 0; i < NUM_FLEXIFORCE_SENSORS; i++) { err_code = nrf_drv_saadc_sample(); APP_ERROR_CHECK(err_code); } sampling->index = 0; }
SAADC initialization
- I configured the ADC converter to default settings by just reconfiguring the resolution
- I used the default channel configuration settings by reconfiguring the gain and the reference voltage
void saadc_init(void) { ret_code_t err_code; uint8_t saadc_input; nrfx_saadc_config_t adc_config = NRFX_SAADC_DEFAULT_CONFIG; // set default settings adc_config.resolution = NRF_SAADC_RESOLUTION_12BIT; // configure the resolution // GPIO assignments - https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpin.html // By default the aquitition time is 10us. You can change the aquitition time from NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE at nrfx_saadc.h // Configure the SAADC input based on the EVB version if (evb == EVB_V2) { saadc_input = NRF_SAADC_INPUT_AIN1; // This is the analog input (P0.03) used for EVB.v2 } else if (evb == EVB_V3) { saadc_input = NRF_SAADC_INPUT_AIN6; // This is the analog input (P0.30) used for EVB.v3 } // Configure the channel nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(saadc_input); // use default configuration settings channel_config.gain = NRF_SAADC_GAIN1_4; // configure the gain channel_config.reference = NRF_SAADC_REFERENCE_VDD4; // configure the reference voltage // adc initialize with custom configuratiom err_code = nrf_drv_saadc_init(&adc_config, saadc_callback); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &channel_config); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER); // na - designating the buffer in which to fill the samples produces by nrf_drv_saadc_sample or NRF_SAADC_TASK_SAMPLE. APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code); }
Event handler
void saadc_callback(nrf_drv_saadc_evt_t const *p_event) { 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); sampling.flexi_force[sampling.index++] = p_event->data.done.p_buffer[0]; // na - Buffer the ADC values from flexi force (8 x sensors) selectMuxPin(sampling.index); // na - change MUX channel to read the next sensor } }
sdk_config.h configuration
// <e> SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver - legacy layer //========================================================== #ifndef SAADC_ENABLED #define SAADC_ENABLED 1 #endif // <o> SAADC_CONFIG_RESOLUTION - Resolution // <0=> 8 bit // <1=> 10 bit // <2=> 12 bit // <3=> 14 bit #ifndef SAADC_CONFIG_RESOLUTION #define SAADC_CONFIG_RESOLUTION 1 #endif // <o> SAADC_CONFIG_OVERSAMPLE - Sample period // <0=> Disabled // <1=> 2x // <2=> 4x // <3=> 8x // <4=> 16x // <5=> 32x // <6=> 64x // <7=> 128x // <8=> 256x #ifndef SAADC_CONFIG_OVERSAMPLE #define SAADC_CONFIG_OVERSAMPLE 0 #endif // <q> SAADC_CONFIG_LP_MODE - Enabling low power mode #ifndef SAADC_CONFIG_LP_MODE #define SAADC_CONFIG_LP_MODE 0 #endif // <o> SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice // <0=> 0 (highest) // <1=> 1 // <2=> 2 // <3=> 3 // <4=> 4 // <5=> 5 // <6=> 6 // <7=> 7 #ifndef SAADC_CONFIG_IRQ_PRIORITY #define SAADC_CONFIG_IRQ_PRIORITY 6 #endif
What I am I doing wrong? Should I avoid placing the nrf_drv_saadc_sample() inside the for loop? Or should I tweak the configurations?
Thanks, Nick