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

jhmluna
Posts: 5
Joined: Wed Aug 26, 2020 1:39 pm

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

Postby jhmluna » Mon Aug 31, 2020 4:56 pm

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:
  1.  // Routing ADC reference voltage to GPIO, so it can be manually measured (for Default Vref):
  2.     esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
  3.     if (status == ESP_OK)
  4.     {
  5.         printf("v_ref routed to GPIO25\n");
  6.     }
  7.     else
  8.     {
  9.         printf("failed to route v_ref\n");
  10.     }
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.
  1. #include <Arduino.h>
  2. #include <esp_adc_cal.h>
  3. #include <esp_efuse.h>
  4.  
  5. #define DEFAULT_VREF 1100 // Use adc2_vref_to_gpio() to obtain a better estimate
  6. #define NO_OF_SAMPLES 1  // Multisampling
  7.  
  8.  
  9. static esp_adc_cal_characteristics_t *adc_chars;
  10. static const adc1_channel_t channel = ADC1_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2
  11. static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
  12. static const adc_atten_t atten = ADC_ATTEN_DB_11;
  13. static const adc_unit_t unit = ADC_UNIT_1;
  14.  
  15. static void check_efuse(void)
  16. {
  17.     //Check if TP is burned into eFuse
  18.     if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK)
  19.     {
  20.         printf("eFuse Two Point: Supported\n");
  21.     }
  22.     else
  23.     {
  24.         printf("eFuse Two Point: NOT supported\n");
  25.     }
  26.     //Check Vref is burned into eFuse
  27.     if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK)
  28.     {
  29.         printf("eFuse Vref: Supported\n");
  30.     }
  31.     else
  32.     {
  33.         printf("eFuse Vref: NOT supported\n");
  34.     }
  35.  
  36.     uint8_t chip_ver = esp_efuse_get_chip_ver();
  37.     printf("Chip version is: %d\n", chip_ver);
  38.  
  39. }
  40.  
  41. static void print_char_val_type(esp_adc_cal_value_t val_type)
  42. {
  43.     if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP)
  44.     {
  45.         printf("Characterized using Two Point Value\n");
  46.     }
  47.     else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF)
  48.     {
  49.         printf("Characterized using eFuse Vref\n");
  50.     }
  51.     else
  52.     {
  53.         printf("Characterized using Default Vref\n");
  54.     }
  55. }
  56.  
  57. void setup()
  58. {  
  59.     Serial.begin(115200);
  60.  
  61.     // Set GPIO High in order to measure HIGH value voltage.
  62.     pinMode(GPIO_NUM_17, OUTPUT);
  63.     digitalWrite(GPIO_NUM_17, HIGH);
  64.  
  65.     //Check if Two Point or Vref are burned into eFuse
  66.     check_efuse();
  67.  
  68.     //Characterize ADC at particular atten
  69.     adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
  70.     esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
  71.     print_char_val_type(val_type);
  72.  
  73.     // Routing ADC reference voltage to GPIO, so it can be manually measured (for Default Vref):
  74.     esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
  75.     if (status == ESP_OK)
  76.     {
  77.         printf("v_ref routed to GPIO25\n");
  78.     }
  79.     else
  80.     {
  81.         printf("failed to route v_ref\n");
  82.     }
  83.  
  84. }
  85.  
  86. void loop()
  87. {
  88.     uint32_t adc_reading = 0;
  89.     static int16_t dac_counter = 0;
  90.     uint32_t voltage = 0;
  91.     int Buffer = 0;  // Serial buffer
  92.  
  93.  
  94.     // Read serial input to update DAC value
  95.     if(Serial.available() > 0)
  96.     {
  97.         Buffer =  Serial.parseInt();
  98.         if ((Buffer < 0) || (Buffer > 255)){
  99.             Serial.println("Input number is invalid.");
  100.         }
  101.         else{
  102.             Serial.print("Number is: ");
  103.             Serial.println(Buffer);
  104.             dac_counter = Buffer;
  105.         }
  106.     }
  107.  
  108.     // write dac value
  109.     dacWrite(GPIO_NUM_26, dac_counter);
  110.  
  111.    
  112.     // Reading ADC value
  113.     unsigned long adc_conv_time = micros();
  114.     for (int i = 0; i < NO_OF_SAMPLES; i++)
  115.         {
  116.             adc_reading += analogRead(GPIO_NUM_34);
  117.         }
  118.     // Calcualate mean value
  119.     unsigned long adc_conv_time1 = micros() - adc_conv_time;
  120.     adc_reading /= NO_OF_SAMPLES;
  121.     voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
  122.     unsigned long adc_conv_time2 = micros() - adc_conv_time;
  123.    
  124.     // Print values
  125.     Serial.print("DAC: ");
  126.     Serial.print(dac_counter);
  127.     Serial.print("  Raw voltage: ");
  128.     Serial.print(adc_reading);
  129.     Serial.print("  Voltage: ");
  130.     Serial.print(voltage);
  131.     Serial.print("  Time adc: ");
  132.     Serial.print(adc_conv_time1);
  133.     Serial.print("  Time calculus: ");
  134.     Serial.println(adc_conv_time2);
  135.    
  136.     delay(1000);
  137.  
  138. }

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

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

Postby lbernstone » Tue Sep 01, 2020 1:52 am

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() {}

jhmluna
Posts: 5
Joined: Wed Aug 26, 2020 1:39 pm

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

Postby jhmluna » Tue Sep 01, 2020 1:07 pm

lbernstone wrote: 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...

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

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

Postby lbernstone » Tue Sep 01, 2020 2:59 pm

If you want a consistent voltage on the pin, calibrate during setup with the vref, then use the dac to recreate that signal.

jhmluna
Posts: 5
Joined: Wed Aug 26, 2020 1:39 pm

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

Postby jhmluna » Tue Sep 01, 2020 3:40 pm

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.

bikerbill
Posts: 1
Joined: Mon Jan 25, 2021 4:26 pm

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

Postby bikerbill » Mon Jan 25, 2021 4:34 pm

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.

Who is online

Users browsing this forum: No registered users and 72 guests