Page 1 of 1

Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Mon Aug 31, 2020 4:56 pm
by jhmluna
Hello.
I am testing some ESP32 modules using VSCode + PlatformIO in Arduino framework.
My experiment involves putting some values in the output of DAC2 (GPIO26) and reading that value with ADC1_CHANNEL_6 (GPIO34).
My output values on DAC2 are updated via serial, transmitting values between 0 and 255.
The part that is puzzling me is related to the adc2_vref_to_gpio () function;
I'm using it this way:

Code: Untitled.cpp Select all


 // Routing ADC reference voltage to GPIO, so it can be manually measured (for Default Vref):
esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
if (status == ESP_OK)
{
printf("v_ref routed to GPIO25\n");
}
else
{
printf("failed to route v_ref\n");
}
I have already programmed three ESP32 modules using GPIO_NUM_26 and GPIO_NUM_27 as a parameter of the adc2_vref_to_gpio () function and in neither case did it work.
My question is whether I need to do anything else for the adc2_vref_to_gpio function to work.
I already tested it with an example of the ESP-IDF framework and it worked, I can read the reference voltage on the pin for the GPIO25, but if I use this function in the Arduino Framework, no GPIO produces the reference voltage.
Can someone help me?

The complete code is below.

Code: Untitled.cpp Select all


#include <Arduino.h>
#include <esp_adc_cal.h>
#include <esp_efuse.h>

#define DEFAULT_VREF 1100 // Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES 1 // Multisampling


static esp_adc_cal_characteristics_t *adc_chars;
static const adc1_channel_t channel = ADC1_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
static const 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)
{
printf("eFuse Two Point: Supported\n");
}
else
{
printf("eFuse Two Point: NOT supported\n");
}
//Check Vref is burned into eFuse
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK)
{
printf("eFuse Vref: Supported\n");
}
else
{
printf("eFuse Vref: NOT supported\n");
}

uint8_t chip_ver = esp_efuse_get_chip_ver();
printf("Chip version is: %d\n", chip_ver);

}

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

void setup()
{
Serial.begin(115200);

// Set GPIO High in order to measure HIGH value voltage.
pinMode(GPIO_NUM_17, OUTPUT);
digitalWrite(GPIO_NUM_17, HIGH);

//Check if Two Point or Vref are burned into eFuse
check_efuse();

//Characterize ADC at particular atten
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);

// Routing ADC reference voltage to GPIO, so it can be manually measured (for Default Vref):
esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
if (status == ESP_OK)
{
printf("v_ref routed to GPIO25\n");
}
else
{
printf("failed to route v_ref\n");
}

}

void loop()
{
uint32_t adc_reading = 0;
static int16_t dac_counter = 0;
uint32_t voltage = 0;
int Buffer = 0; // Serial buffer


// Read serial input to update DAC value
if(Serial.available() > 0)
{
Buffer = Serial.parseInt();
if ((Buffer < 0) || (Buffer > 255)){
Serial.println("Input number is invalid.");
}
else{
Serial.print("Number is: ");
Serial.println(Buffer);
dac_counter = Buffer;
}
}

// write dac value
dacWrite(GPIO_NUM_26, dac_counter);


// Reading ADC value
unsigned long adc_conv_time = micros();
for (int i = 0; i < NO_OF_SAMPLES; i++)
{
adc_reading += analogRead(GPIO_NUM_34);
}
// Calcualate mean value
unsigned long adc_conv_time1 = micros() - adc_conv_time;
adc_reading /= NO_OF_SAMPLES;
voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
unsigned long adc_conv_time2 = micros() - adc_conv_time;

// Print values
Serial.print("DAC: ");
Serial.print(dac_counter);
Serial.print(" Raw voltage: ");
Serial.print(adc_reading);
Serial.print(" Voltage: ");
Serial.print(voltage);
Serial.print(" Time adc: ");
Serial.print(adc_conv_time1);
Serial.print(" Time calculus: ");
Serial.println(adc_conv_time2);

delay(1000);

}

Re: Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Tue Sep 01, 2020 1:52 am
by lbernstone
This code works for me, and gives me a pretty consistent reading at 1113mV.

Code: Select all

#include <driver/adc.h>
gpio_num_t ref_pin = (gpio_num_t) 25;
void setup() {adc2_vref_to_gpio(ref_pin);}
void loop() {}

Re: Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Tue Sep 01, 2020 1:07 pm
by jhmluna
This code works for me, and gives me a pretty consistent reading at 1113mV.

Code: Select all

#include <driver/adc.h>
gpio_num_t ref_pin = (gpio_num_t) 25;
void setup() {adc2_vref_to_gpio(ref_pin);}
void loop() {}
Hello.
It is basically the same code I used.
If I write only your code it works, but if I use the adc2_vref_to_gpio() function in the same way in my code, it will stop working.
So, I think there is some incompatibility between the adc2_vref_to_gpio() function and some of the resources that I am using. Perhaps ADC1 or DAC2. I dont know...

Re: Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Tue Sep 01, 2020 2:59 pm
by lbernstone
If you want a consistent voltage on the pin, calibrate during setup with the vref, then use the dac to recreate that signal.

Re: Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Tue Sep 01, 2020 3:40 pm
by jhmluna
Hello @lbernstone
Thank you for your attention.
As for my application, I was able to get around this problem, so it is no longer a problem for me.
However, I decided to post because I think this is a bug in the Arduino framework.
I hope someone from the Espressif development takes a look at the post and gives an opinion.

Re: Is there anything to do to make the adc2_vref_to_gpio () function work?

Posted: Mon Jan 25, 2021 4:34 pm
by bikerbill
Hi, i was testing this too and i was able to run your code (thanks for posting, it helped educate me). I don't think this is a bug, if you add a 10sec delay after esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25) before you do anything else with the ADC2 then it works fine. i read my Vref as 1.115v. as you said, something later on in your code seems to be disturbing this setup but the function itself appears to work ok.
regards bikerbill.