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

nRF52840 saadc results are in the wrong order

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;
    }
}

Parents Reply Children
Related