Skip to main content

Section 3.3 Input pins

While output pins are used to control external circuitry, input pins can be used to read the state of the circuitry attached to them. For example, an input pin could read the status of a switch or button, or even the output from another microcontroller.

On most microcontrollers, every output pin can also be used as an input pin; it just has to be configured differently in the code.

Subsection 3.3.1 Reading circuit inputs with MicroPython

Setting up an input pin in MicroPython is very similar to setting up an output pin:

from machine import Pin
inpin = Pin(0, Pin.IN)
inval = inpin.value()
print(f"The input value is {inval}")

Just like an output pin, we first import Pin from the machine library, and then call the Pin() constructor function. We specify the pin number and Pin.IN to configure it as an input.

Once the input pin is set up, we can call the value() function to get the current value of the pin. If the value is close to Vdd (aka "high"), then it will return a logic 1. If the value is close to ground, it will return a logic 0.

In this example, we save the result of value() in the variable inval. It's also possible to use it directly, such as:

print(f"The input value is {inpin.value()}")
if inpin.value() == 1:
    # Do stuff to respond to the input pin being high
    # Respond to the input pin being low

This is straightforward so far, but there are two complications.

First, remember that all of the pins can function as both inputs and outputs, and that an output always drives the pin either high or low. How do we prevent the output-pin circuit from interfering with the input part? This is where the "floating" state comes in. When you configure a pin as an input, the microcontroller completely disconnects it from Vdd and ground and lets it "float" however the external circuit drives it.

The second complication comes when we connect switches to input pins.

Subsection 3.3.2 Pull-up resistors

Switches are one of the most useful and simple circuit elements we can connect to a microcontroller. Simply connect one end of the switch to ground, and the other end of the switch to the input pin.

Figure 3.3.1. Pull-up resistor

Subsection 3.3.3 Using pull-up resistors in MicroPython

You can always manually wire a pull-up resistor onto your switches, but this is such a common trick that most microcontrollers include pull-ups as a built-in part of the input pin circuitry. To enable the built-in pull-up, include the extra parameter ``Pin.PULL_UP`` at the end of the ``Pin`` constructor:

Pin(2, Pin.IN, Pin.PULL_UP)

**Side note** How does adding ``Pin.PULL_UP`` cause a pull-up resistor to appear in the circuit? The resistor is always there, but it can be included or not using another electrically-controlled switch. When you specify ``Pin.PULL_UP``, the microcontroller closes this switch thereby connecting the pull-up resistor to the pin.

Figure 3.3.2. Internal pull-up resistor configuration

**ESP32-specific:** Unlike many microcontrollers, the ESP32 has pull-down resistors in addition to pull-ups. These are just like pull-ups, except that they go between the pin and ground while the switch connects to Vdd:

Pin(2, Pin.IN, Pin.PULL_DOWN)