> For the complete documentation index, see [llms.txt](https://monasheng.gitbook.io/zerotohero/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monasheng.gitbook.io/zerotohero/arduino-zero-to-hero/core-skills/input-output-pins/digital-pins/digitalread.md).

# digitalRead()

{% embed url="<https://youtu.be/xnXVy5hWl9s>" %}

MCU digital pins can also be used to read `HIGH` and `LOW` voltages in a circuit, acting like rudimentary, binary multimeters.

## Syntax

### `pinMode()`

To use a digital pin for measurement, you must first set it to `INPUT` mode.  This is typically achieved in the `setup()`  function, as it only needs to be done once per boot. The `pinMode()` function expects a pin number and mode as arguments:

```arduino
void setup() {
  // Set PIN 2 as an input.
  pinMode(2, INPUT);
  // Setup the Serial Monitor for later
  Serial.begin(9600);
}
```

{% embed url="<https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/>" %}

### `digitalRead()`

After the mode is set, the pin state (`HIGH` or `LOW`) can be read. The `digitalRead()` function expects a pin number as the only argument:

```arduino
void loop() {
  // Read the state of PIN 2, and print this to the serial monitor
  int pinTwoState = digitalRead(2);
  Serial.println(pinTwoState);
  // Wait for 0.5 seconds
  delay(500);
}
```

You can `digitalRead()` in the `setup()` function to query the initial/boot state of a pin, but this is usually done programmatically in the `loop()` function - often as a function of time/on a cycle.

{% embed url="<https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/>" %}

## Complete Sample Code

{% code overflow="wrap" %}

```arduino
void setup() {
  // Set PIN 2 as an input.
  pinMode(2, INPUT);
  // Setup the Serial Monitor for later
  Serial.begin(9600);
}

void loop() {
  // Read the state of PIN 2, and print this to the serial monitor
  int pinTwoState = digitalRead(2);
  Serial.println(pinTwoState);
  // Wait for 0.5 seconds
  delay(500);
}
```

{% endcode %}

<figure><img src="/files/ALnXexGawCeZC085ELWj" alt=""><figcaption></figcaption></figure>

## Practical Considerations

### Logic Level Definitions

On most MCUs, `HIGH` and `LOW` pin states are not tied to precisely to $$V\_\text{nom}$$ or $$0;\text{V}$$, but rather, and with some tolerance, *somewhere* *close* to these voltages. For Arduino-based MCUs, with $$V\_\text{nom}=5;\text{V}$$, the following is typical:

$$
\texttt{ ;;;LOW}: V\_\text{in} < 1.5 ; \text{V} \\
\texttt{HIGH}: V\_\text{in} > 3 ; \text{V} \\
$$

For $$1.5;\text{V}\<V\_\text{in}<3;\text{V}$$, the state of a digital pin is said to be *undefined*. In reality, it will likely linger around it's previous state until it crosses the upper or lower threshold, though relying on this hysteresis is dangerous.

For best results, you should target $$V\_\text{in}<1.5;\text{V}$$, (ideally $$V\_\text{in}=0;\text{V}$$) in your circuits for `LOW` signals,  and   $$V\_\text{in}>3;\text{V}$$, (ideally $$V\_\text{in}=5;\text{V}$$) for `HIGH` signals.

### High Impedance Inputs

MCU input pins are usually *high impedance*, meaning that they typically have large ($$M\Omega$$), built-in resistors in-line with their input stage.&#x20;

Consequently, when setup in `INPUT` mode, these pins cannot sink any substantial amount of current when performing their measurements, and are unlikely to affect the voltage of whatever they're measuring.

In short - MCU pins setup as inputs act just like multimeters - measuring voltages without impacting the circuit they are attached to.

### Noise

Electromagnetic noise/interference (EMI) can, in some cases, alter the value read on a digital pin.

In general, digital signals are less susceptible to interference than analog ones (as a large change in voltage is required to alter the [#logic-level-definitions](#logic-level-definitions "mention")).

That being said, you should consider the presence of EMI generators in the setup of your circuits. Motors, solenoids, and other inductive loads can be troublesome, and should either be shielded, or physically relocated away from measured circuits.

### Debounce

Because they are mechanical in nature, some spring-loaded buttons/switches can oscillate, or *bounce* very quickly before settling into a steady-state position. Modern MCUs are so fast that they can detect this bouncing if a `digitalRead()` is performed every loop iteration.&#x20;

This can be addressed in hardware (e.g. by adding a small capacitor to 'smooth' the button input), or software (by reading a pin state twice, with a small delay, before committing to updating it). For more information, see:

{% embed url="<https://makeabilitylab.github.io/physcomp/arduino/debouncing.html>" %}

### Floating Voltages

Particularly when using switches and buttons, it is possible to create a situation where the pin state is not well defined. This can cause unexpected behaviour in your circuits. See [Floating Voltages and Pull-Up/Pull-Down Resistors](/zerotohero/arduino-zero-to-hero/core-skills/input-output-pins/floating-voltages-and-pull-up-pull-down-resistors.md) for more information.
