Skip to content

Pull resistors

In this tutorial we cover the following topics


Test 1


Description

Take the Arduino board and make the following test

  • Select one of digital pin, say pin number 2, and call it PIN_IN.
  • Read periodically it's state and if is HIGH turn on Arduino's built in LED and turn off if is LOW.
  • Reset or turn off and turn on Arduino and again observe LED state.
  • What can you say about LED?

Below tere is a code we can use to make this test.

Read an appropriate documentation if you don't know how function we used are working


Observations

What can you say about LED behaviour? Is it predictible and stady? Souldn't be. Our LED shoul be sometimes on but sometimes off. This means that sometimes we read HIGH state but other time oposit, LOW, state. Sometimes high, sometimes low is like a wave: sometimes up, sometimes down so we say that state of the pin is floating.


Sometimes it could be difficult to observe this behaviour. You can try with another board or repeat test another time.

Another solution to observe this is to use two wires: one connected to our PIN_IN and second to 5V.


Next connect both wires - logical state on PIN_IN should be HIGH and led turn on. Disconnect wires - logical state on PIN_IN should be LOW and led turn off.

In my case, whatever I do, led stays on.

Initila state
Wires connected - led is on
Wires disconnected - led is still on


Explanations

There are no any premises so we could say which state, HIGH or LOW, would be read on our pin PIN_IN. The input is "free" - that is, it doesn't have a solid connection to voltage or ground, and it will randomly return either HIGH or LOW. In this case situation is similar to the following piece of code

The input variable stays uninitialized so its value is random. Every time we run this program, results are different.


MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ gcc test_01.c
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ ./a.out
97525814
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ ./a.out
256753718
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ ./a.out
211959862
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ ./a.out
294740022
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$ ./a.out
224059446
MacBook-Air-Piotr:tutorials_electronics_pull_resistors fulmanp$

Sometimes, when we run it over and over again in short time interval results are the same but make a brake and run it after one hour or another day - results should be different.

Same with our digital pin - it stays uninitialized. The question is: How to initialize pins?


Pin initialization with pull resistors

To prevent this unpredictible behaviour, a pull-up or pull-down resistor are used to ensure that the pin is in either a HIGH or LOW state, while also using a low amount of current.

As you can see, our PIN_IN is connected with either 5V to get always HIGH state or with GND to get always LOW state. To limit a current a 10kOhms resistor is used (limiting current to 0.5mA) but any value in range 4.7kOhms-15kOhms will do in this case. Keep in mind that the larger the resistance for the pull, the slower the pin is to respond to voltage changes.

Let's try to fix our test case from Test 1 section.


Left image: pull-up active, led is on. Right image: PIN_IN is connected with GND and led is off.

Left image: pull-down active, led is off. Right image: PIN_IN is connected with 5V and led is on.

Of course we can replace bare wires with switches

Unfortunately switches becomes a source of a new problems.


Test 2


Description

Take a pull-down version from the previous section and write a program which changes led state every time you press the button.

Below there is a code we can use to make this test.


Observations

Again the led seems to behave unpredictably. Sometimes it changes its state, other time doesn't while another time blinks just for a fraction of a second. This effect might be difficult to notice but it exists. It is much more visible when we use interrupts. If you want, you may now jump for a while to an Interrupts section, complete a Test and than go back here.


Explanations

The problem is that

  • what for us (humans) is immediate for microcontrollers takes ages;
  • even such a simple "devices" like switch have its physical limits;
  • voltage characteristic of switch is far from ideal model.

We believe that voltage characteristiv of switch looks like

Unfortunately, because of physical limits and properties, real characteristic is like
Todo (id=no todo id): pull_resistors: use osciloscope to visualize this

Todo (id=no todo id): pull_resistors: improve images
So, when we press the button, there is a very short time interval (very short for us not for a microcontroller) when membrane of our switch oscillates (bounces) and thus we can observe a series of HIGH and LOW state. When our microcontroller tests digital pin it is highly possible that will test a signal during this unstable time interval - sometimes may hit HIGH state but other time LOW.

Making switch working correctly

One of the simplest solution for this, is to wait this unpredictable time interval just after we detect high state.

Delay of 20ms should be enough in most cases (see for example section 3.4 in D45H27B160.pdf datasheet from https://www.maritex.com.pl/product/attachment/34206/D45H27B160.pdf


Making switch working correctly

This approach is implemented in the following code


Microcontroller's built-in pull resistors

Since pull-up resistors are so commonly needed, many MCUs, have internal pull resistors that can be enabled and disabled. With this we don't have to manually add resistors and wires to implement pulls. To enable internal pull-ups on an Arduino (there are no pull-downs on an Arduino), we can use the following line of code in our setup() function