Page 1 of 1

Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Sun Sep 20, 2020 11:23 pm
by njneer
I'm programming a custom ESP32 board using Arduino where GPIO25 and GPIO32 are connected to pogo pins via <10mm traces and to nothing else. The goal is to poll for a short between them as part of an alignment procedure - pretty straightforward.

The issue is, pinMode(X, INPUT_PULLUP) does not actully turn on the pullup for either pin; the ADC readings are always floating. Whichever pin I'm using still successfully detects a short when intended, but because It is floating and never pulled high, it causes a lot of false flags. Code below:

Code: Select all

    int foo=9999;
    pinMode(25, OUTPUT);
    digitalWrite(25,HIGH);
    pinMode(32,INPUT_PULLUP);
    while(foo>0){
        foo=analogRead(32);
        Serial.println(foo);
        //do other stuff
    }
I'm using Node32S as my board with the latest IDF (1.0.4) and latest Arduino (1.8.13). So far, the best answer I've found is that EMI may be overcoming the internal resistors, but I find that hard to believe. Any help is greatly appreciated.

Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Mon Sep 21, 2020 2:25 pm
by mrburnette
Interesting.

Clearly, the Arduino syntax for pinMode() shows "INPUT_PULLUP" the Espressif syntax seems to suggest "INPUT" and "PULLUP" are two separate commands:

https://github.com/espressif/arduino-es ... hal-gpio.c

Of course, perhaps the call is front-ended by a function that performs two calls for the single INPUT_PULLUP

Code: Select all

    if(mode & INPUT) {
        if(pin < 32) {
            GPIO.enable_w1tc = ((uint32_t)1 << pin);
        } else {
            GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
        }
    } else if(mode & OUTPUT) {
        if(pin > 33){
            //unlock gpio
            return;//pins above 33 can be only inputs
        } else if(pin < 32) {
            GPIO.enable_w1ts = ((uint32_t)1 << pin);
        } else {
            GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
        }
    }
... and ...

Code: Select all

    if(mode & PULLUP) {
        pinFunction |= FUN_PU;
    } else if(mode & PULLDOWN) {
        pinFunction |= FUN_PD;
    }


Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Mon Sep 21, 2020 3:44 pm
by lbernstone
analogRead attaches the pin to ADC channel, which remaps it off the PU circuit. If you set the mode back to INPUT_PULLUP after the read, it should work as expected.

Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Mon Sep 21, 2020 4:28 pm
by njneer
I will give this a shot now and report back, thanks!

Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Mon Sep 21, 2020 10:20 pm
by njneer
lbernstone wrote:
Mon Sep 21, 2020 3:44 pm
analogRead attaches the pin to ADC channel, which remaps it off the PU circuit. If you set the mode back to INPUT_PULLUP after the read, it should work as expected.
This did the trick! Thanks @Ibernstone! Quick recap and some SEO terms for anyone googling this: if the INPUT_PULLUP or INPUT_PULLDOWN aren't working on ADC pins like GPIO25 or GPIO32, it's because analogRead disconnects the ADC from the pullup. Calling pinMode(X, INPUT_PULLUP) again after an ADC reading will fix the pin bias.

Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Sun Mar 21, 2021 2:23 pm
by cimba007
I would even go this far and say analogRead will disconnect the PULLUP from ALL ADC related pins. This is a major bummer for my project and I am now using a NON_ADC pin and connect it to my INPUT pin with INPUT_PULLUP enabled on this NON_ADC pin.

Code: Select all

void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
  
}

void loop() {
  pinMode(18,INPUT_PULLUP);
  delay(5);
  Serial.println(analogRead(32));

  delay(100);
}

Re: Internal Pull-ups don't work on GPIO25 or GPIO32

Posted: Sun Mar 21, 2021 8:02 pm
by lbernstone
Your code works fine for me. Pin 18 is always high. You should only need to set the pullup once if you aren't reading from that pin.