Language: EN


Digital Inputs in Arduino

One of the most interesting functions (if not the most) of Arduino and in general of all automatons is its capacity to interact with the physical world. For example, we can take voltage measurements, obtain readings from a wide variety of sensors, turn on devices, or control motors and actuators. This interaction is largely carried out through the use of both digital and analog inputs and outputs.

In the following posts in the Arduino tutorials section, we will learn how to use these functions, which are a fundamental part of most projects. We will start in this post with digital inputs because they are the simplest, although we will see that the other functions are not much more complicated.

Although we are using Arduino as the platform, it is important to note that most concepts are applicable to any general automaton. At the end, we will see the code and setup in Arduino, but first we will briefly look at some general theory.

What is a digital input?

A digital signal is a voltage variation between -Vcc and +Vcc without passing through the intermediate values. Therefore, a digital signal has only two states. The lower voltage value -Vcc is associated with a logical LOW or ‘0’, while the higher value +Vcc is associated with HIGH or ‘1’ logical.

However, in the physical world, voltage references are actually continuous. The digital reading process is a process of discretizing an analog signal, the voltage value, into a digital value represented by two states, LOW and HIGH.

In reality, a digital input performs a comparison of the measurement with a threshold voltage value. If the measured value is higher than the threshold voltage, it returns HIGH, and if it is lower, LOW. The threshold voltage value varies from one automaton to another, and may not even remain constant over time.

In general, it is reasonable to assume that the threshold voltage is close to the midpoint between -Vcc and +Vcc. However, we should avoid measuring voltages near the threshold voltage because they can cause incorrect measurements.

Connection of digital inputs in Arduino

In Arduino, digital inputs and outputs share a pin, which is why they are called digital I/O. This means that the same pin can perform both input and output functions, although not simultaneously, of course. It is necessary to configure a pin I/O as input or output in the code.

Arduino has a different number of digital I/O based on the model, as we saw in the post What is Arduino? What model to buy?. For example, Arduino UNO has 16 digital I/O and Arduino MEGA has 54.

In Arduino, the usual power values are 0V and 5V. In this case, the threshold voltage will be very close to 2.5V. Therefore, if we measure a voltage with an intermediate value between 0 to 2.5V, Arduino will return a LOW reading, and if we measure a value between 2.5V and 5V, it will return HIGH.

Never introduce a voltage outside the range 0V to 5V into a digital or analog input or we may damage the corresponding pin and permanently render it unusable.

Suppose we want to use Arduino to connect it with a sensor, or any other device, that has an uninterrupted voltage output between 0V to 5V. At the moment, we do not consider the possibility of the digital input being completely disconnected, something we will address in the next post “Reading a button with Arduino”.

We can read the voltage value in the sensor with a setup like the following.


The reading will give a “HIGH” value if the measured voltage value is higher than a threshold voltage, and “LOW” if the voltage value is lower.

Code in Arduino

The code to perform the reading is really simple. We just have to configure a digital I/O as input with pinMode() and perform the reading with digitalRead().

int pin = 2;
int value = 0;

void setup() {
  Serial.begin(9600);   //start serial port
  pinMode(pin, INPUT);  //define pin as input

void loop(){
  value = digitalRead(pin);  //digital pin reading

  //send message to serial port based on the value read
  if (value == HIGH) {
  else {

Try it online

The pins configured as inputs are in a high-impedance state, meaning they behave as resistors with a very high value (of the order of 100 megaohms). Therefore, negligible current flows through them.

In reality, the Arduino pins (Atmega) are initialized by default as inputs, so it would not be strictly necessary to configure them as inputs, although it is a convenient practice.

Reading values greater than 5V

We have mentioned that under no circumstances should we introduce a voltage outside the range of 0 to 5V into an Arduino pin or we risk permanently damaging it. If we want to measure a voltage level higher than the power limits, the most convenient way is to use a simple voltage divider.

For example, to read a digital signal between 0 to 12V, we can use a setup like the following.


Do not use this system to read voltages higher than 35V, or for AC devices without being very sure of what you are doing. It is very likely that the resistors will not hold up.

With this setup, the digital pin of Arduino will receive a voltage that varies between 0 to 3.84V, enough to trigger the threshold voltage, and below the power limit.

The values of the resistors to be used depend on the voltage we want to read, and the impedance of the sensor. In general, they must meet the following conditions:

  • They must provide a voltage higher than the threshold voltage
  • They must be much higher than the equivalent impedance of the device being measured.
  • They must be negligible compared to the impedance of the Arduino input.
  • They must limit the current flowing through them to minimize losses.
  • They must be able to dissipate the power they will support.

You can use the voltage divider calculator to calculate resistance values that meet these requirements.

In the next post, we will see how to use the digital input to read the state of a button.

Download the code

All the code from this post is available for download on Github. github-full