In the tutorial digital inputs in Arduino we saw how to read a sensor that provides a digital signal with two voltage levels LOW
and HIGH
. We still need to take advantage of digital inputs to read the state of a switch or button with Arduino.
For this, we will need to correctly perform a specific setup and the help of two new friends the Pull Down and Pull Up resistors. Although both cases are very similar, the setup and the type of resistor to use will depend on whether we want to read a LOW
or HIGH
value when pressing the button or switch.
To understand the operation of both setups, we will present the logical reasoning for which we arrive at it, for which we will use two incorrect setups that will help us understand the role of each element in the final setup.
So, we start with the first attempt to read the state of the button.
Another more advanced way to read a button is to use interrupts and apply a debounce to filter the input, as we see in this entry
First attempt, direct connection
Our first idea to read a button could be to connect a digital PIN of Arduino directly to a reference voltage, whether it is 0V or 5V.
When the button is pressed, the voltage at the PIN would be the reference value (0V or 5V depending on the setup) and we could perform the reading as in any digital input.
What is the problem? Well, this will work when the switch is closed. But, what happens when the switch is open? In this case, we are leaving the PIN completely disconnected from any voltage (something we will call high impedance state).
What value does an automaton register if we measure in a high impedance state? Well, it depends on several factors, such as the internal construction of the automaton or the last state it was connected to.
In summary, the input is in an indeterminate state (that is, it can assume any value). Therefore, it is necessary to avoid this situation in our designs.
How can we resolve this state of indeterminacy? Well, this leads us directly to our second attempt. 👇
Improving our solution, dual connection
The next thing we might think of is connecting the PIN to two reference voltages, alternated depending on the state of the switch:
To measure a LOW value when pressing the switch
- We can connect the PIN fixed to 5V, and to 0V through the switch
- With the switch open, we would read
HIGH
- When closing the switch, 0V would be forced at the PIN, so we would read
LOW
To measure a HIGH value when pressing the switch
- We can connect the PIN fixed to 0V, and to 5V through the switch.
- With the switch open, we would read
LOW
- When closing the switch, 5V would be forced at the PIN, so we would read
HIGH
What is the problem with this setup? Well, when pressing the switch, we are directly connecting the values of 0V and 5V, which means that we are causing a short circuit.
This would cause a high current to flow and a rapid heating of components and conductors (death, destruction, dismissal…).
How can we avoid this short circuit? Well, we are close. We will see this next in the final setup.
Short circuits are dangerous failures. In addition to damaging some components, you could even cause a fire. Be careful.
The setup would also not work because we would be connecting the PIN simultaneously to 0V and 5V, so we would again have an indeterminacy, and the actual measurement would depend on the resistance of the conductors at both voltage levels.
Correct setup, Pull-Down or Pull-Up resistors
As we mentioned earlier, to solve the setup correctly we will need the presence of two new friends, the Pull Down and Pull Up resistors. These two resistors are a basic mechanism, very common in the world of electronics and automation.
Pull-Down and Pull-Up resistors are connected between the digital PIN and one of the reference voltages (0V or 5V) and “force” or “pull” (hence their name) the voltage value to LOW
or HIGH
, respectively.
The Pull-Up resistor:
- Forces
HIGH
when the button is open - When closed, the PIN goes to
LOW
, the current flowing is limited by this resistor
The Pull-Down resistor:
- Forces
LOW
when the button is open - When closed, the PIN goes to
HIGH
, and the current flowing is limited by this resistor
This is how the final setup would look in a schematic view (the connection can be made using any of the digital PINs).
And thus the wiring on a prototype board.
Finally, the reading of the PIN state is done normally, as we saw in the tutorial digital inputs in Arduino.
const int inputPin = 2;
int value = 0;
void setup() {
Serial.begin(9600);
pinMode(inputPin, INPUT);
}
void loop(){
value = digitalRead(inputPin); //digital reading of pin
//send message to serial port based on the value read
if (value == `HIGH`) {
Serial.println("On");
}
else {
Serial.println("Off");
}
delay(1000);
}
Arduino has internal Pull Up resistors of 30k but they are not usually used for two reasons.
- They have low authority (resistance value too high)
- If we configure it incorrectly from the program, we can generate a short circuit, so it is preferable to connect it physically to ensure we haven’t forgotten it.
What resistance value to choose?
The value of the resistor is conditioned by the current that flows when pressing the switch, and by a concept called the “authority of the Pull Down/up” which is related to noise in the measurement.
A very small resistor
- 👍 Will have a lot of authority
- 👎 But will allow a greater current to flow, which means higher consumption and greater heating
A very large resistor
- 👍 Will allow little current to flow
- 👎 But will have low authority, making it more susceptible to incorrect measurements due to noise
Download the code
All the code from this entry is available for download on Github.