I'm feeding a BCD diode matrix of switches with Vcc at 3.3 V and running the BCD outputs into GPIOs on the ESP32-C6. The plan is to set each GPIO input to internal pull-down so I can pull it up externally with the BCD switches.

Correct me if I'm wrong here, but I figured it would be a good idea to limit current flow into the GPIO pins as a precaution, so I need to know how strong I should pull it up (R1) to override the unknown value of the internal GPIO pull-down:


  • Is R1 necessary (or even a good idea)?
  • If so, how big should R1 be (how should it be calculated)?

More info below:

BCD diode matrix

The datasheet says the weak pull-up/down resistors are 45 kΩ:

ESP32-C5 DC Characteristics

The big reference manual says this is what the internal structure of the GPIO looks like just as it reaches the pad inside of the ESP32:



2 Answers 2


It might be a good idea, in case some accident happens and the IO pins are set as outputs and to low state.

The largest problem in calculating the value is that while the datasheet gives a typical value of pull-down resistance, it does not give a min/max limit for tolerance. A secondary issue is that it might not even be a true resistance, but a weak transistor, but it gives no detail on that too.

Based on some other MCUs, the tolerance could be 45k +/- 50%, so it could be maybe as low as 20k. But we can never know that unless you find a specification for that.

The next step is to calculate the minimum voltage on the pin to guarantee read as high. You don't say what your VCC is or does it have a range of tolerance, but whatever it is, the pin must have 0.75×Vdd, and it means the IO supply which may or may not be the same as other supplies on MCU.

Then there is up to 50nA of leakage current. Assume the leakage current direction is always in the worst case direction or agains the state you want to control the pin. You want to pull high so assume 50nA flows into the pin and you must have stronger pull up resistor to account for the extra 50nA to reach the minimum input threshold.

So making some assumptions here, you are using 3.3V supply, you want the pin to reach 2.475V, and the internal pull-down is 20k, you need about 124 microamps to drop 825mV. The 50nA is insignificant. So your pull resistor needs to be about 6.6k or less, when calculated without the diode.

The diode may start to be a problem. Diodes also have only typical characteristics, they are non-linear, and in addition to manufacturing tolerances, voltage drop depends on current and temperature. We can estimate that around 100-200uA range, and temperatures down to -30°C, the voltage drop should not exceed 0.7V.

So now the situation leaves only 125mV over resistor because 700mV could be left over the diode. 125mV at 123.75uA is approximately 1.01 kohms.

And given that resistors too have tolerances, you would need a resistor that never exceeds 1.01 kohms when it is within tolerance.

OK, so there was a lot of assumptions we can never prove, like can the ESP internal pull-down ever be 20k, and we did not consider what would happen if supply voltage has tolerance too, like if it is 3.2V or slightly less.

One problem is also that you need to drive two inputs so two times the current. So this halves the resistance.

The diode forward drop starts to become a real issue when supply voltage drops.

It might have been quicker to go to an approximate ballpark solution what is needed to protect the IO pin if it is a low output and someone pushes the button. The weakest output drive is 5mA and strongest 20mA.

Assuming 3.3V supply again, resistor must be higher than 660 ohms to limit current to 5mA.

680 ohms would be a standard E12 value that fits, or 820 should work too.

And these resistors should be on each IO pin, not a single resistor for the buttons globally.

Some problems could be avoided by using a diode with less voltage drop, but Schottky diodes with their reverse leakage currents can also be a problem, so that also needs some consideration.

As you can see, button matrixes with CMOS input thresholds and diodes are problematic. It would be simpler if the chip used e.g. TTL voltage thresholds, so the problem becomes much simpler the more you change the solution to e.g. include a TTL input level buffer IC or something else, which could be an I2C IO expander reading those buttons directly.

Or, if the MCU has free ADC pins, just use 5 buttons and 5 resistors to set 5 different voltages to ADC input, or if there are multiple ADC channels, use one for joystick left/right and another for up/down and digital IO for pushbutton.

  • \$\begingroup\$ "Schottky diodes with their reverse leakage currents can also be a problem": what might be considered a negligable leakage current? I was thinking of using BAT54A's or BAW56's which have reverse current of about 300nA and 20nA, respectively, at 3.3V. \$\endgroup\$
    – KJ7LNW
    Feb 1 at 21:25
  • \$\begingroup\$ @KJ7LNW Depends on tolerances and in what temperature range you want to work in. If the MCU has 90k pull-down, and voltage can rise up to 825mV, the leakage allowed is about 10uA. The BAT54 has 20uA leakage at 1V in reverse at 85°C, that is not going to work with internal pull resistors. Which is why it makes sense to use external pull resistors. \$\endgroup\$
    – Justme
    Feb 1 at 22:32

Strictly speaking, there is no need for R1; the input impedance of an input pin is very high. R1 will limit the initial gate current of the input, at the expense of slower switching, but is not necessary in your application.

It is cheap insurance though: when a GPIO pin is configured as output by accident, there is less chance of damage to the pin with a resistor there. For this you should put a resistor on each IO pin you use. If you do put resistors in, a value of 200 Ω will do; it will limit GPIO pin current to 17 mA when something goes wrong, which is within ESP32 maximum IO pin current spec, and easily override the weak internal pull-down (keep the voltage well above the minimum level for a "1").

Note that there are other microcontrollers, like the SAMD21 found on some Arduinos, that can only source/sink 10 or 5 mA per GPIO pin; they would need larger resistors for protection.

If you want the GPIO inputs pulled down at start-up, before the code runs, you need external pull-downs.

Note that the buttons will need debouncing, and I think (this is from memory; haven't checked) the ESP32 has a few GPIO pins that don't have internal pull-down resistors.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.