ADC: Reading above Vref on an ESP32-S2 with ATTEN_12

kevinevans
Posts: 24
Joined: Thu Aug 25, 2022 10:34 pm

ADC: Reading above Vref on an ESP32-S2 with ATTEN_12

Postby kevinevans » Fri Apr 25, 2025 5:54 pm

I'm having some trouble reading above Vref on an ESP32-S2 in continuous mode. I should be able to read above Vref with ATTEN_12, right?

I'm using a line fitting calibration scheme that's initialized like:

Code: Select all

      adc_cali_line_fitting_config_t cali_config = {
          .unit_id = ADC_UNIT_1,
          .atten = ADC_ATTEN_DB_12,
          .bitwidth = ADC_BITWIDTH_12,
      };
      ret = adc_cali_create_scheme_line_fitting(&cali_config, out_handle); // returns ESP_OK
and I'm initializing the continuous handle/config like:

Code: Select all

  adc_continuous_handle_cfg_t adc_config = {
      .max_store_buf_size = 1024,                                // in bytes
      .conv_frame_size = 256 * SOC_ADC_DIGI_DATA_BYTES_PER_CONV, // in bytes
  };

  ESP_RETURN_ON_ERROR(
      adc_continuous_new_handle(&adc_config, &s_adc_cont_handle), TAG,
      "adc_continuous_new_handle failed");

  adc_continuous_config_t cont_config = {
      .pattern_num = 1,
      .adc_pattern =
          (adc_digi_pattern_config_t[1]){
              (adc_digi_pattern_config_t){
                  .unit = ADC_UNIT_1,
                  .channel = ADC_CHANNEL_0,
                  .atten = ADC_ATTEN_DB_12,
                  .bit_width = ADC_BITWIDTH_12,

              },
          },
      .sample_freq_hz = 1000,
      .conv_mode = ADC_CONV_SINGLE_UNIT_1,
      .format = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
  };

  ESP_RETURN_ON_ERROR(adc_continuous_config(s_adc_cont_handle, &cont_config),
                      TAG, "failed to cont config");

In the interrupt handler, I'm reading the results like:

Code: Select all

    esp_err_t err =
        adc_continuous_read(s_adc_cont_handle, res, size, &size, 1);
        
    // [...]
    
      
      for (int i = 0; i < size; i += SOC_ADC_DIGI_RESULT_BYTES) {
        adc_digi_output_data_t *data = (adc_digi_output_data_t *)&res[i];
        
        // int raw_value = data->type2.data;
        int raw_value = data->type1.data;
        // ESP_LOGI(TAG, "raw = %d", raw_value);
        if (adc_cali_raw_to_voltage(s_adc_cali_handle, raw_value, &voltage) ==
            ESP_OK) {
            // HERE, raw_value was like 4096, but voltage is reading 1280 mV... why?
        }
      }
I'm currently passing in 3v3, so the raw value of 4096 is correct. But when I call `adc_cali_raw_to_voltage`, I would expect voltage to be 2500 mV with DB11/DB12 atten, but it returns 1280 mV.

Do I need to use `adc_cali_scheme_line_fitting_check_efuse` here? Or am I misconfiguring or misunderstanding something here?

kevinevans
Posts: 24
Joined: Thu Aug 25, 2022 10:34 pm

Re: ADC: Reading above Vref on an ESP32-S2 with ATTEN_12

Postby kevinevans » Mon Apr 28, 2025 9:16 pm

Do I need to additionally scale the value returned from `adc_cali_raw_to_voltage`? It appears to read 0.5x the actual value. If I feed in 1V, adc_cali_raw_to_voltage returns 0.5 V. If I use 2V, I'm reading 1V. I feel like there's something else that I am missing here. Anyone have pointers?

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ADC: Reading above Vref on an ESP32-S2 with ATTEN_12

Postby MicroController » Tue Apr 29, 2025 6:46 am

It appears to read 0.5x the actual value. If I feed in 1V, adc_cali_raw_to_voltage returns 0.5 V. If I use 2V, I'm reading 1V.
Sounds like this may be a bug in the IDF.

kevinevans
Posts: 24
Joined: Thu Aug 25, 2022 10:34 pm

Re: ADC: Reading above Vref on an ESP32-S2 with ATTEN_12

Postby kevinevans » Tue Apr 29, 2025 5:45 pm

Yeah, I'm thinking so, since it can be isolated to just calls to adc_cali_create_scheme_line_fitting & adc_cali_raw_to_voltage

Opened a report here: https://github.com/espressif/esp-idf/issues/15876

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], Google [Bot] and 2 guests