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

Parents
  • 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

  • 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.

  • I've read our internal documents, this is within our max Gain error temperature coefficient  of +/-0.05 %/C.

    30C * +/-0.05 %/C = +/- 1.5%.

    2370/2400 = 0.9875 = -1.25%

  • Ok, thanks for your return.

    So, what we seen is sadly normal...

    Do you have any recommandations to improve the measure?

    What the precision of the internal temparature you use for calibration?

Reply Children
No Data
Related