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


