This one is about the wire, not the chip. Nothing below changes with the board you picked, which is why the chip and language switches are not on it. They come back on the ESP32 pages this one sits underneath.
Digital in and digital out
A pin does exactly two things. As an output it is a switch you close from code, to 3.3 V or to ground. As an input it is a comparator that answers one question — is this above the line or below it. Every protocol in this chapter is built out of those two behaviours and nothing else.
Flip the direction, then drag the voltage. There is no third mode.
An output is a switch, not a supply
digitalWrite(pin, HIGH) closes an internal switch between the pin and the
3.3 V rail. LOW closes the other one, to ground. That is the whole
mechanism, and two useful facts fall straight out of it.
The first: LOW is connected, not "off". Wire an LED between the pin and 3V3 and it lights when you write LOW, because the pin is now the ground end of the circuit. Half the "my LED is inverted" questions are this.
The second: a switch has a rating. An ESP32 pin will pass about 20 mA comfortably and 40 mA at absolute maximum. An LED with its resistor asks for 6. A relay coil asks for 70, a small motor for 200, and neither of them goes on a pin — they go on a transistor that the pin controls.
An input is a comparator
An input does not measure. It compares against two fixed thresholds — a quarter and three quarters of the supply on an ESP32, so 0.83 V and 2.48 V — and reports which side you are on. Between them the datasheet promises nothing, and you will get one answer on your board and the other on the next one off the reel.
If you want the number, that is a different pin and a different function:
analogRead() on an ADC-capable pin.
The three modes you will actually type
#define LED 2
#define BUTTON 4
void setup() {
pinMode(LED, OUTPUT); // I drive this wire
pinMode(BUTTON, INPUT_PULLUP); // I read it, held high when idle
}
void loop() {
bool pressed = !digitalRead(BUTTON); // pull-up inverts it
digitalWrite(LED, pressed);
}INPUT_PULLUP connects a resistor inside the chip from the pin up to 3.3 V, so
the pin idles high and the button pulls it down. No external part, one word of
code, and it is the right default for every button you will ever wire.
Why this is the baseline
One pin, one device, and the protocol is "high means on". Nothing to configure and nothing to go wrong. What it costs you is pins: eight LEDs is eight pins, and a board has about thirty.
Everything else in this chapter is a way of buying devices with time instead of pins — sending a sequence on one wire rather than a level on many. That trade starts on the next page, where a single pin carries forty bits by holding itself high for different lengths of time.
The same two behaviours on a real board: which pins are already busy at boot, and a button and an LED in both languages.
Digital I/O →Edit this page — content/esp32/digital-in-and-digital-out.mdx
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.