Page 1 of 1

ESP32 adc calibration in windows

Posted: Mon May 02, 2022 9:18 am
by zazas321
Hello. I am trying to calibrate my ESP32 to achieve better accuracy. I have 1.25V on the adc pin but my ESP32 functions measure 1.21V hence 40mV error. I would like to minimize that if possible.

My ADC setup:

Code: Select all


#define DEFAULT_VREF    1114        //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES   64          //Multisampling

esp_adc_cal_characteristics_t *adc_chars;
static  adc_bits_width_t width = ADC_WIDTH_BIT_12;
static  adc_atten_t atten = ADC_ATTEN_DB_11;
static  adc_unit_t unit = ADC_UNIT_1;



static void check_efuse(void)
{
    //Check if TP is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
        ESP_LOGI(ADC_TAG,"eFuse Two Point: Supported");
    } else {
        ESP_LOGI(ADC_TAG,"eFuse Two Point: NOT supported");
    }
    //Check Vref is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
        ESP_LOGI(ADC_TAG,"eFuse Vref: Supported");
    } else {
        ESP_LOGI(ADC_TAG,"eFuse Vref: NOT supported");
    }

}


static void print_char_val_type(esp_adc_cal_value_t val_type)
{
    if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
        ESP_LOGI(ADC_TAG,"Characterized using Two Point Value");
    } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
        ESP_LOGI(ADC_TAG,"Characterized using eFuse Vref");
    } else {
        ESP_LOGI(ADC_TAG,"Characterized using Default Vref");
    }
}

void ADC_Init(void)
{
// ADC config


    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_DB_11); 
    adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_11);
    adc1_config_channel_atten(ADC1_CHANNEL_3,ADC_ATTEN_DB_11);
    adc1_config_channel_atten(ADC1_CHANNEL_6,ADC_ATTEN_DB_11);


    check_efuse();
    //Characterize ADC
    //adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));

    adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
    print_char_val_type(val_type);

    esp_err_t status = adc_vref_to_gpio(ADC_UNIT_1,GPIO_NUM_36);
    if (status == ESP_OK)
    {
        ESP_LOGI(ADC_TAG,"v_ref routed to GPIO25");
    }
    else
    {
        ESP_LOGI(ADC_TAG,"failed to route v_ref");
    }
    

    vTaskDelay(1000/portTICK_PERIOD_MS);
}
And then I simply read the voltages:

Code: Select all

		uint32_t voltage_reading =  adc1_get_raw(ADC1_CHANNEL_3); //adc in 3 // gpio 39
		uint32_t voltage = esp_adc_cal_raw_to_voltage(voltage_reading , adc_chars);
		ESP_LOGE(TEST_TAG,"VOLTAGE = %u",voltage );

In my code, after the ADC setup I get the following messages:

Code: Select all

[1B][0;32mI (1299) ADC: eFuse Two Point: NOT supported[1B][0m
[1B][0;32mI (1299) ADC: eFuse Vref: Supported[1B][0m
[1B][0;32mI (1299) ADC: Characterized using eFuse Vref[1B][0m
[1B][0;32mI (1309) ADC: failed to route v_ref[1B][0m
Is there any reason why its failing to route the v_ref? could that be my problem?

I have ran adc_info from espefuse.py and get the following adc calibration vref:

Code: Select all

Connecting....................
Detecting chip type... ESP32
espefuse.py v3.2-dev
ADC VRef calibration: 1086mV
I assume I need to select my own calibration value since the factory is not quite accurate but im not sure how can I do that

Re: ESP32 adc calibration in windows

Posted: Tue May 03, 2022 1:13 am
by mikemoy