ESP32/Wires on the board/22. Digital in and digital out
No board required

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.

Wires on the board · 22 of 81

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.

/esp32/digital-in-and-digital-out · any board · 7 min read

Flip the direction, then drag the voltage. There is no third mode.

pinMode(pin, OUTPUT)
you drive the wire
Pin voltage
3.3 V
Current through the pin
5.9 mA
The pin is a closed switch to 3V3. Not a power supply — a switch. It can pass about 5.9 mA here without noticing, 20 mA all day, and 40 mA once. A motor asks for 200 mA, which is why a motor never goes on a pin.

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.

Where this goes next

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.

Browse ESP32 on the forum