ADC error with calibration VS temperature

HI,

We use nrf52832 on a device with sdk 14.1.

Our product has to work at different temperature (between 20 and 70°C).

We did some measure and found this :

Temperature

AIN_6

AIN4

AIN_7

AIN_5

30°C

2400

2415

572

2293

50°C

2381

2396

566

2275

60°C

2370

2385

561

2266

Gain adc :

1/5

1/5

1/6

1/4

Following the temperature, adc variates even if we use 'nrf_drv_saadc_calibrate_offset'.

Do you have some ideas of what happened?

Best regards,

David

  • Hey David,

    I need to know what your sources are, channel configurations, etc.

    Cheers,

    Håkon.

  • Hi Håkon,

    I can't attach files (I don't know why). So, this is the channels configurations :


    #if defined(NB_ADC)
    static nrf_saadc_channel_config_t adc_channels[NB_ADC_0_CHANNEL] = {
        // 4-20 mA channel 1
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_5,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_20US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN6),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },
        // 4-20 mA channel 2
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_5,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_20US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN4),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },
        // Voltage channel 1
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_6,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_20US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN7),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },
        // Voltage channel 2
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_2,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_20US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN5),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },
        // Voltage Boost 16V
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_4,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_10US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN1),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },

        // Voltage used for calibration
        {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_6,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL, //0.6V référence
            .acq_time   = NRF_SAADC_ACQTIME_10US,
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_VDD),
            .pin_n      = NRF_SAADC_INPUT_DISABLED,
        },

    };

    static adc_nrf52_t adcs[NB_ADC]={
        {
            .config = {
                .resolution = NRF_SAADC_RESOLUTION_12BIT,   //Set SAADC resolution to 12-bit. This will make the SAADC output values from 0 (when input voltage is 0V) to 2^12=4096 (when input voltage is 3.6V for channel gain setting of 1/6).
                .oversample = NRF_SAADC_OVERSAMPLE_64X,      //Set oversample to 4x. This will make the SAADC output a single averaged value when the SAMPLE task is triggered 4 times.
                .interrupt_priority = APP_IRQ_PRIORITY_LOW, //Set SAADC interrupt to low priority.
                .low_power_mode = 0,
            },
            
            .nb_channels = NB_ADC_0_CHANNEL,
            .channels_config = &adc_channels[0],
        },
    };
    #endif //NB_ADC

  • What do you mean by you need to know what the sources are?

  • The configs looks normal. 
    DevZone was down for maintenance at 12.00 CET yesterday. We experienced some issue related to the update afterwords, this might be the reason why you could not attach any files. 

    What are the signals that you've sampled, are the signals themselves temperature dependent? 
    Did you calibrate the offset at each temperature interval?

    Have you considered using differential inputs?

  • For the measure I've done to get these results, I took an external generator with no temperature dependance.

    The calibration is done for each temperature interval.

Related