ADC question

Gilbert
Posts: 17
Joined: Wed Sep 16, 2020 2:58 pm

ADC question

Postby Gilbert » Fri Nov 20, 2020 4:03 pm

I'm using ESP32 DEVKIT.
ADC1 produces expected results, but ADC2 always produces the maximum value, even when I connect the pins to GND.
I know that ADC2 can't be used when WiFi is active, but I'm not using WiFi, only Bluetooth (Classic). Maybe it is turned on by default?

becorey
Posts: 22
Joined: Sat Mar 28, 2020 4:18 pm

Re: ADC question

Postby becorey » Sat Nov 21, 2020 6:10 am

Can you share your code and schematic?

Create a wifi ap station and confirm it is disabled, sounds like you're just guessing if it's on or off.

Are the adc2 pins set as inputs similar to adc1 pins?

Gilbert
Posts: 17
Joined: Wed Sep 16, 2020 2:58 pm

Re: ADC question

Postby Gilbert » Sat Nov 21, 2020 12:44 pm

I recreated the code and this time paid attention to setup all pins correctly. Nevertheless, the result is the same.
There is no schematic. The ESP board is plugged in on a breadboard. All ADC pins are connected to a common rail which is in turn connected to 3.3V, 1.6V or GND for testing purposes. See picture https://drive.google.com/file/d/1QMMHKw ... sp=sharing.
The purple wires are all ADC1, the orange wires are all ADC2.

Setup code:

Code: Select all

analogSetWidth(9);
  analogReadResolution(9);                                                    // set the ADC resolution
  analogSetCycles(8);                                                         // successive ADC conversions to reduce noise impact
  analogSetAttenuation(ADC_11db);                                             // Global ADC setting: ADC range 0 - 3.3 V
  
  pinMode(GPIO_NUM_36, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_36, ADC_11db);                             // ADC setting pin ADC1_CH0
  
  pinMode(GPIO_NUM_39, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_39, ADC_11db);                             // ADC setting pin ADC1_CH3
  
  pinMode(GPIO_NUM_34, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_34, ADC_11db);                             // ADC setting pin ADC1_CH6
  
  pinMode(GPIO_NUM_35, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_35, ADC_11db);                             // ADC setting pin ADC1_CH7
  
  pinMode(GPIO_NUM_32, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_32, ADC_11db);                             // ADC setting pin ADC1_CH4
  
  pinMode(GPIO_NUM_33, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_33, ADC_11db);                             // ADC setting pin ADC1_CH5
  
  pinMode(GPIO_NUM_25, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_25, ADC_11db);                             // ADC setting pin ADC2_CH8
  
  pinMode(GPIO_NUM_26, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_26, ADC_11db);                             // ADC setting pin ADC2_CH9
  
  pinMode(GPIO_NUM_27, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_27, ADC_11db);                             // ADC setting pin ADC2_CH7
  
  pinMode(GPIO_NUM_14, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_14, ADC_11db);                             // ADC setting pin ADC2_CH6
  
  pinMode(GPIO_NUM_12, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_12, ADC_11db);                             // ADC setting pin ADC2_CH5
  
  pinMode(GPIO_NUM_13, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_13, ADC_11db);                             // ADC setting pin ADC2_CH4

  pinMode(GPIO_NUM_2, INPUT);                                                 // set input mode
  analogSetPinAttenuation(GPIO_NUM_2, ADC_11db);                              // ADC setting pin ADC2_CH2

  pinMode(GPIO_NUM_4, INPUT);                                                 // set input mode
  analogSetPinAttenuation(GPIO_NUM_4, ADC_11db);                              // ADC setting pin ADC2_CH0

test code:

Code: Select all

  Serial.print("Value pin 36 (ADC1_CH0) = ");
  Serial.println(analogRead(GPIO_NUM_36), DEC);
  
  Serial.print("Value pin 39 (ADC1_CH3) = ");
  Serial.println(analogRead(GPIO_NUM_39), DEC);
  
  Serial.print("Value pin 34 (ADC1_CH6) = ");
  Serial.println(analogRead(GPIO_NUM_34), DEC);
  
  Serial.print("Value pin 35 (ADC1_CH7) = ");
  Serial.println(analogRead(GPIO_NUM_35), DEC);
  
  Serial.print("Value pin 32 (ADC1_CH4) = ");
  Serial.println(analogRead(GPIO_NUM_32), DEC);
  
  Serial.print("Value pin 33 (ADC1_CH5) = ");
  Serial.println(analogRead(GPIO_NUM_33), DEC);
  
  Serial.print("Value pin 25 (ADC2_CH8) = ");
  Serial.println(analogRead(GPIO_NUM_25), DEC);
  
  Serial.print("Value pin 26 (ADC2_CH9) = ");
  Serial.println(analogRead(GPIO_NUM_26), DEC);
  
  Serial.print("Value pin 27 (ADC2_CH7) = ");
  Serial.println(analogRead(GPIO_NUM_27), DEC);
  
  Serial.print("Value pin 14 (ADC2_CH6) = ");
  Serial.println(analogRead(GPIO_NUM_14), DEC);
  
  Serial.print("Value pin 12 (ADC2_CH5) = ");
  Serial.println(analogRead(GPIO_NUM_12), DEC);
  
  Serial.print("Value pin 13 (ADC2_CH4) = ");
  Serial.println(analogRead(GPIO_NUM_13), DEC);
  
  Serial.print("Value pin 2 (ADC2_CH2) = ");
  Serial.println(analogRead(GPIO_NUM_2), DEC);
  
  Serial.print("Value pin 4 (ADC2_CH0) = ");
  Serial.println(analogRead(GPIO_NUM_4), DEC);
Output to serial:

13:13:29.986 -> Value pin 36 (ADC1_CH0) = 0
13:13:29.986 -> Value pin 39 (ADC1_CH3) = 0
13:13:29.986 -> Value pin 34 (ADC1_CH6) = 0
13:13:29.986 -> Value pin 35 (ADC1_CH7) = 0
13:13:29.986 -> Value pin 32 (ADC1_CH4) = 0
13:13:29.986 -> Value pin 33 (ADC1_CH5) = 0
13:13:29.986 -> Value pin 25 (ADC2_CH8) = 511
13:13:29.986 -> Value pin 26 (ADC2_CH9) = 511
13:13:29.986 -> Value pin 27 (ADC2_CH7) = 511
13:13:29.986 -> Value pin 14 (ADC2_CH6) = 511
13:13:30.033 -> Value pin 12 (ADC2_CH5) = 511
13:13:30.033 -> Value pin 13 (ADC2_CH4) = 511
13:13:30.033 -> Value pin 2 (ADC2_CH2) = 511
13:13:30.033 -> Value pin 4 (ADC2_CH0) = 511
When I repeat the test with the common ADC rail connected to 1.6 V:
13:34:31.848 -> Value pin 36 (ADC1_CH0) = 216
13:34:31.895 -> Value pin 39 (ADC1_CH3) = 216
13:34:31.895 -> Value pin 34 (ADC1_CH6) = 216
13:34:31.895 -> Value pin 35 (ADC1_CH7) = 216
13:34:31.895 -> Value pin 32 (ADC1_CH4) = 216
13:34:31.895 -> Value pin 33 (ADC1_CH5) = 216
13:34:31.895 -> Value pin 25 (ADC2_CH8) = 511
13:34:31.895 -> Value pin 26 (ADC2_CH9) = 511
13:34:31.895 -> Value pin 27 (ADC2_CH7) = 511
13:34:31.895 -> Value pin 14 (ADC2_CH6) = 511
13:34:31.895 -> Value pin 12 (ADC2_CH5) = 511
13:34:31.895 -> Value pin 13 (ADC2_CH4) = 511
13:34:31.895 -> Value pin 2 (ADC2_CH2) = 511
13:34:31.895 -> Value pin 4 (ADC2_CH0) = 511
All connected to GND:
13:35:12.882 -> Value pin 36 (ADC1_CH0) = 0
13:35:12.882 -> Value pin 39 (ADC1_CH3) = 0
13:35:12.882 -> Value pin 34 (ADC1_CH6) = 0
13:35:12.882 -> Value pin 35 (ADC1_CH7) = 0
13:35:12.882 -> Value pin 32 (ADC1_CH4) = 0
13:35:12.882 -> Value pin 33 (ADC1_CH5) = 0
13:35:12.882 -> Value pin 25 (ADC2_CH8) = 511
13:35:12.882 -> Value pin 26 (ADC2_CH9) = 511
13:35:12.882 -> Value pin 27 (ADC2_CH7) = 511
13:35:12.882 -> Value pin 14 (ADC2_CH6) = 511
13:35:12.882 -> Value pin 12 (ADC2_CH5) = 511
13:35:12.882 -> Value pin 13 (ADC2_CH4) = 511
13:35:12.882 -> Value pin 2 (ADC2_CH2) = 511
13:35:12.882 -> Value pin 4 (ADC2_CH0) = 511
Concerning WiFi: my understanding about using WiFi is that the code must contain at least
#include "WiFi.h"
and
WiFi.begin(ssid, password);

My code contains no reference to WiFi whatsoever.

Thanks for assistance.

becorey
Posts: 22
Joined: Sat Mar 28, 2020 4:18 pm

Re: ADC question

Postby becorey » Tue Nov 24, 2020 9:41 pm

Can you check the ADC2 pins with a multimeter or oscilloscope? Check if they are actually at 3.3V when they're reading 511.

Could be worth taking them off a common rail, and just try the pins one by one. Maybe one of them has a pull-up resistor or something.

I think if you try the pins one by one, measure with a scope, and do analogRead to compare, you might find something.


Also I see your pin number variables like GPIO_NUM_4 but you didn't show where those are defined, double check those are correct with the proper physical pin number to GPIO number mapping.

Gilbert
Posts: 17
Joined: Wed Sep 16, 2020 2:58 pm

Re: ADC question

Postby Gilbert » Wed Nov 25, 2020 4:19 pm

Now it is working.
Well, sort of...
When I connect the pins to +3.3 V or GND I get full scale or zero for both ADCs.
But when I connect all pins to the same intermediate voltage, I get a big difference between both ADCs.
All pins belonging to the same ADC produce the same value.
Example: test voltage = 1.3 V (40% of Vcc obtained from 2 out of a series of 5 x 1 kohm).
Expected result: 511 * (1.3/3.3) = 201.

Results:
16:44:20.635 -> analogRead of pins...
16:44:20.635 -> Analog value pin 36 (ADC1_CH0) = 138
16:44:20.729 -> Analog value pin 39 (ADC1_CH3) = 138
16:44:20.822 -> Analog value pin 34 (ADC1_CH6) = 138
16:44:20.916 -> Analog value pin 35 (ADC1_CH7) = 138
16:44:21.010 -> Analog value pin 25 (ADC2_CH8) = 186
16:44:21.104 -> Analog value pin 26 (ADC2_CH9) = 186
16:44:21.197 -> Analog value pin 27 (ADC2_CH7) = 186
16:44:21.338 -> Analog value pin 14 (ADC2_CH6) = 186
I would expect a little bit of difference (ADC not calibrated), but that much?
The above values are obtained with 9 bits resolution, but the difference remains about the same if I increase the resolution to 10..11..12 bits. Concerning the timing: I put a short delay (100 ms) between each analogRead. It's just a bit easier on the eye. When I remove the delay, the results are the same.

Another thing I observed is that connecting GPIO12 (ADC2_CH5) to +3.3 V causes a boot error ("flash read err, 1000"). Didn't see that before, when I had all pins connected to the same rail - but maybe I didn't reboot with that setting and didn't run into that issue.
I found some posts on the espressif forum about this error (https://www.esp32.com/viewtopic.php?t=3452), but for another board (WROVER, mine is DEVKIT).

Not sure if I should be concerned about the big deviation of the results. ADC2 results are consistently below, but reasonably close to the calculated result, but ADC1 is really off the chart.

The other thing I noticed is that I can't switch between analogRead and digitalRead for the same pins. I wouldn't need that in practice (there may be some exceptional applications for this), but since I was messing with the ports, I tried this out of curiosity.

I controlled (or rather tried to) the choice between reading analog and digital by setting GPIO36 high or low while the software was running, but I only got it to readAnalog once imediately after rebooting, after that it would just stick to readDigital, regardless of what I did on GPIO36. And all ports would always read 0, even if I connected them to +3.3V (which also explains why it wouldn't respond to changing the input on GPIO36).

Code (some of the test settings are commented out):

Code: Select all

bool analog = true;
char text[50] = {'\0'};

// put your setup code here, to run once:

void setup() {

  analogSetWidth(9);
  analogReadResolution(9);                                                   // set the ADC resolution
  analogSetCycles(8);                                                         // successive ADC conversions to reduce noise impact
  analogSetAttenuation(ADC_11db);                                             // Global ADC setting: ADC range 0 - 3.3 V
  
  pinMode(GPIO_NUM_36, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_36, ADC_11db);                             // ADC setting pin ADC1_CH0
  
  pinMode(GPIO_NUM_39, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_39, ADC_11db);                             // ADC setting pin ADC1_CH3
  
  pinMode(GPIO_NUM_34, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_34, ADC_11db);                             // ADC setting pin ADC1_CH6
  
  pinMode(GPIO_NUM_35, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_35, ADC_11db);                             // ADC setting pin ADC1_CH7
  
  pinMode(GPIO_NUM_32, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_32, ADC_11db);                             // ADC setting pin ADC1_CH4
  
  pinMode(GPIO_NUM_33, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_33, ADC_11db);                             // ADC setting pin ADC1_CH5
  
  pinMode(GPIO_NUM_25, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_25, ADC_11db);                             // ADC setting pin ADC2_CH8
  
  pinMode(GPIO_NUM_26, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_26, ADC_11db);                             // ADC setting pin ADC2_CH9
  
  pinMode(GPIO_NUM_27, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_27, ADC_11db);                             // ADC setting pin ADC2_CH7
  
  pinMode(GPIO_NUM_14, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_14, ADC_11db);                             // ADC setting pin ADC2_CH6
  
  pinMode(GPIO_NUM_12, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_12, ADC_11db);                             // ADC setting pin ADC2_CH5
  
  pinMode(GPIO_NUM_13, INPUT);                                                // set input mode
  analogSetPinAttenuation(GPIO_NUM_13, ADC_11db);                             // ADC setting pin ADC2_CH4

  pinMode(GPIO_NUM_2, INPUT);                                                 // set input mode
  analogSetPinAttenuation(GPIO_NUM_2, ADC_11db);                              // ADC setting pin ADC2_CH2

  pinMode(GPIO_NUM_4, INPUT);                                                 // set input mode
  analogSetPinAttenuation(GPIO_NUM_4, ADC_11db);                              // ADC setting pin ADC2_CH0

  Serial.begin(115200);                                                       // Arduino serial port for debugging @ 115.2 kBaud
  while (!Serial) continue;                                                   // wait for serial port to connect. Needed for native USB

}

// put your main code here, to run repeatedly:

void loop() {

  // use GPIO_NUM_36 to control analog or digital read of the other ports
  // if input is GND, do digitalRead, else do analogRead of all other pins
  
//  analog = (bool)digitalRead(GPIO_NUM_36);
 
  Serial.println();
  if(analog)
    Serial.println("analog = true");
  else
    Serial.println("analog = false");
  Serial.println();

  
  if(analog) {
    Serial.println("analogRead of pins...");
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC1_CH0) = %u", GPIO_NUM_36, analogRead(GPIO_NUM_36));
    Serial.println(text);
    //delay(100);
  
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC1_CH3) = %u", GPIO_NUM_39, analogRead(GPIO_NUM_39));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC1_CH6) = %u", GPIO_NUM_34, analogRead(GPIO_NUM_34));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC1_CH7) = %u", GPIO_NUM_35, analogRead(GPIO_NUM_35));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC2_CH8) = %u", GPIO_NUM_25, analogRead(GPIO_NUM_25));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC2_CH9) = %u", GPIO_NUM_26, analogRead(GPIO_NUM_26));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC2_CH7) = %u", GPIO_NUM_27, analogRead(GPIO_NUM_27));
    Serial.println(text);
    //delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Analog value pin %u (ADC2_CH6) = %u", GPIO_NUM_14, analogRead(GPIO_NUM_14));
    Serial.println(text);
    //delay(100);


  }
  else {

    Serial.println("digitalRead of pins...");
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_36, digitalRead(GPIO_NUM_36));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_39, digitalRead(GPIO_NUM_39));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_34, digitalRead(GPIO_NUM_34));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_35, digitalRead(GPIO_NUM_35));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_32, digitalRead(GPIO_NUM_32));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_33, digitalRead(GPIO_NUM_33));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_25, digitalRead(GPIO_NUM_25));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_26, digitalRead(GPIO_NUM_26));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_27, digitalRead(GPIO_NUM_27));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_14, digitalRead(GPIO_NUM_14));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_12, digitalRead(GPIO_NUM_12));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_13, digitalRead(GPIO_NUM_13));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_2, digitalRead(GPIO_NUM_2));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_4, digitalRead(GPIO_NUM_4));
    Serial.println(text);
    delay(100);
  }

//  digitalRead(GPIO_NUM_36);
  delay(1000);                      // wait a second
}
Maybe my ESP32 is kaputt?

PS: the GPIO_NUM_xx values are #defined somewhere in the esp core source. See https://docs.espressif.com/projects/esp ... gpio_num_t.

becorey
Posts: 22
Joined: Sat Mar 28, 2020 4:18 pm

Re: ADC question

Postby becorey » Wed Nov 25, 2020 5:56 pm

GPIO 12 is a strapping pin, it sets the flash voltage to 1.8V or 3.3V. The flash is built in to the module, so if this is set wrong it will just cause a problem when trying to boot. Generally GPIO12 must be LOW during power-on / boot-up. Always keep in mind these strapping pins, I usually put a note on the schematic, or write it on paper near the breadboard.
https://www.esp32.com/viewtopic.php?t=5970
randomnerdtutorials.com/esp32-pinout-reference-gpios/

The each ADC has a calibrated VREF associated with it. If the calibration is off you could expect ADC1 and ADC2 to give slightly different results. You might need to run a calibration to fix the eFuse VREF values.
docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/adc.html#adc-calibration
https://www.esp32.com/viewtopic.php?t=4354
https://www.instructables.com/Do-You-Kn ... djustment/

Here's another post that asked about your same digitalRead question: esp32.com/viewtopic.php?f=19&t=2054
You might need a pull-up / down resistor on your GPIO36.
GPIO34 through 39 are input only, that's important to remember.


I would also suggest to clean up your code with loops. Instead of:

Code: Select all

    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_2, digitalRead(GPIO_NUM_2));
    Serial.println(text);
    delay(100);
    
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", GPIO_NUM_4, digitalRead(GPIO_NUM_4));
    Serial.println(text);
    delay(100);
    
    .....
it would be cleaner to loop like:

Code: Select all

pins = [GPIO_NUM_2, GPIO_NUM4, GPIO_NUM_13, .....]
for pin in pins:
    memset(text, '\0', 40);
    snprintf(text, 40, "Digital value pin %u = %u", pin, digitalRead(pin));
    Serial.println(text);
    delay(100);
That will save you a lot of copy-paste, and it's easier to debug your program.

Who is online

Users browsing this forum: No registered users and 14 guests