Hi. In our application we are reading the voltage on 3 Analog input pins via saadc. System is also a BLE central and UBD CDC device so lots going on.
Quite often the 3 analog results are shifted so if they were in the order A,B,C normally they could randomly become B,A,C or C,B,A etc.
I have seen a few threads on the forum about this but no clear answers.
I am trying to avoid adding a separate ADC to SPI IC on the board, but the SAADC on the nRF52840 is not up to the job which is a shame since.
Here are some code snippets. Maybe I could re-initialise the saadc after every sample? I only need to read them every second or so.
nrf_drv_saadc_sample(); Is triggered every few seconds from timer interrupt.
Thanks
void saadc_init(void) { ret_code_t err_code; nrf_saadc_channel_config_t channel_config6 = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6); //P0.30 = AN6 = Regulated voltage nrf_saadc_channel_config_t channel_config4 = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4); //P0.28 = AN4 = Current sense input nrf_saadc_channel_config_t channel_config5 = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5); //P0.29 = AN5 = Voltage In err_code = nrf_drv_saadc_init(NULL, saadc_callback); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &channel_config6); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(1, &channel_config4); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(2, &channel_config5); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(m_buffer, SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code); } void saadc_callback(nrf_drv_saadc_evt_t const * p_event) { if (p_event->type == NRF_DRV_SAADC_EVT_DONE) { ret_code_t err_code; err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code); output[0] = p_event->data.done.p_buffer[0]; output[1] = p_event->data.done.p_buffer[1]; output[2] = p_event->data.done.p_buffer[2]; if(output[0] > 50000) output[0] = 0; //We don't want 65535 etc negative about 0 to get into average if(output[1] > 50000) output[1] = 0; if(output[2] > 50000) output[2] = 0; voltage_reg_ave = ((output[0] - voltage_reg_ave) / mov_ave_divisor) + voltage_reg_ave; voltage_in_ave = ((output[2] - voltage_in_ave) / mov_ave_divisor) + voltage_in_ave; current_sense_ave = ((output[1] - current_sense_ave) / mov_ave_divisor) + current_sense_ave; } }