How to use Arduino’s Internal Pull-Ups


When hooking up switches or buttons to an Arduino I/O pin, sometimes the results might appear completely random. Sometimes it will appear as though there is a delay from when the button is pressed until the state of the pin actually changes. Other times the pin’s value will seem to randomly fluctuate from HIGH to LOW. Even more maddening might be as your finger gets closer to the switch, the pin’s state changes!

The fix to these problems is simple: use pull-up resistors. Here’s how they can fix this problem and how you can use them with an Arduino board.

Detailed explanation…

Why doesn’t my button work!?

Consider the following circuit, which is a simple normally-open push-button on a breadboard. It has been wired so that one side is tied to +5V and the other side is connected to Pin 12 of an Arduino Uno. (Make you check with a multimeter to determine which pins are connected together and which are not.)

Floating Push Button Example

Picture 1: Floating Pushbutton on Breadboard

The code for this switch is very simple. The LED on Pin 13 should light up when Pin 12 is HIGH and be off when Pin 12 is LOW. The expected behavior is that the LED will be OFF whenever the button is not pushed and ON when the button is pushed.

Test code to show what happens when a pin is floating (or not floating).

void setup() {
  pinMode(13, OUTPUT); // Use Built-In LED for Indication
  pinMode(12, INPUT);   // Push-Button On Bread Board

void loop() {
  bool buttonState = digitalRead(12);  // store current state of pin 12
  digitalWrite(13, buttonState);

Take a look at this video to see what happens as the button is pushed. The LED’s behavior is not at all predictable! Sometimes it lights up, sometimes it stays on, sometimes it changes just when a finger gets close to it!

The pin is “Floating.” This schematic shows how the button is wired on the breadboard. What is PIN 12 connected to, when the button is unpressed? Nothing!

Floating Pin Schematic Version

Schematic 1: Schematic of Floating Pin

This means that any signals in the air, such as from nearby electronics, can cause the pin to “float” to either a HIGH or LOW. For example, this waveform from an oscilloscope shows what the pin is doing when nothing is connected.

Floating Pin Oscilloscope Screenshot

Picture 2: Oscilloscope Screenshot of Floating Pin

This video is the same breadboard circuit but with the oscilloscope waveform visible. As a human finger comes close to the pin, the waveform changes. 60Hz noise from the environment is being coupled into the circuit through the finger, which is what causes the “random” behavior of the input pin.

Great! Now that we understand why the pin randomly changes, how does it get fixed? Easy! Just make your Arduino do exercises… pull-ups in fact!

Using Pull-Ups to fix Floating

The fix for floating pins is to “pull them up” to a known value when the switch is unpressed. This is done with a Pull-Up resistor, as illustrated in the following schematic:

Pull-Up Resistor of an I/O Pin

Schematic 2: Pull-Up Resistor of an I/O Pin

Now when nothing is connected, current cannot flow through the resistor. So the Voltage on both legs will be the same. This means the same point where the resistor connects to the switch and Pin 12 will be forced to sit at 5V.

When the button is pressed, that same point will drop to 0V as current starts flowing through the resistor (ohm’s law). Since the resistor is there, you don’t have to worry about a short circuit. In this case, 10Kohms was picked as a relatively large value. The exact value of the resistor does not matter. You want something big enough to limit the amount of current wasted when the button is pressed, but not so big (like 10Mohm that you start having noise problems again.)

A really cool feature of the ATmega chips used by the Arduino platform is that they have these resistors already built into them! All that needs to be done is turn the resistor on and you get the previous schematic, for free! Here is the new breadboard circuit. Notice that the red jumper wire has changed to yellow. Also, it is no longer connected to 5V but now is connected to GND. That’s the [i]only[/i] difference in the hardware.

Button Wired with Internal Pull-Up

Picture 3: Button Wired with Internal Pull-Up (Blue wire connects to Pin 12 of the Arduino)

It only takes a single line of code to turn on these incredibly useful internal pull-up resistors. When a Pin has been configured for INPUT with pinMode(), simply use digitalWrite() to write a HIGH to that pin. Here is the same code with a single line added:


Test code to show what happens when a pin is floating (or not floating).

void setup() {
  pinMode(13, OUTPUT);    // Use Built-In LED for Indication
  pinMode(12, INPUT);      // Push-Button On Bread Board
  /* this next line is the new one */
  digitalWrite(12, HIGH);  // Turn on internal Pull-Up Resistor

void loop() {
  bool buttonState = digitalRead(12);  // store current state of pin 12
  digitalWrite(13, buttonState);

The combined video of the button working by using the internal pull-up and along with the waveforms on the oscilloscope is shown here.


When using any kind of “open” inputs with an Arduino such as switches, push buttons, reed relays, and some sensors a pull-up resistor is needed for reliable operation. These resistors hold the I/O pin at a known value until the switch forces the I/O pin to a different known value. The Arduino has these resistors built-in, they just need to be turned on in the sketch, usually in setup().

Feel free to contact me by leaving comments below.


Your questions, comments, and even corrections are encouraged and very much appreciated! However. I have zero-tolerance for inappropriate or harassing comments. I try to reply to everyone... -James

Leave a comment

10 thoughts on “How to use Arduino’s Internal Pull-Ups

  1. I had a similar issue that needed a pull-up resistor. Learned the hard way. The system now works great, but one problem. After about one to two hours the pin suddenly drops to low, triggering the event programmed into the arduino. I have not been able to identify the issue. The line for the switch is 30 ft long. Do you think this long of a line could be a reason for this unexpected tripping?

  2. Great video, very understandable. The oscilloscope(?) was a helpful addition to see what was going on.

    One question though: is pinMode(2, HIGH) and pinMode(2, INPUT_PULLUP) the same thing? I was a little confused reading through the stuff as they kept saying to use a pull up resister but the code only showed pinMode(…, HIGH)


    • Hi Derek, yes they are the same. INPUT_PULLUP was introduced in 1.0.3, which was long after I made the videos. One correction, you use digitialWrite() to send the HIGH, not pinMode(). Many tutorials (even on’s site) will mention the digitalWrite() method.

  3. Thanks very much for your help, and for clearing up the confusion about pin13.

    The Leonardo arrived yesterday. I love it!

  4. Very useful info, thanks.

    One quick question, if you don’t mind – I’m going to use the Leonardo for a project of mine. Using the internal pullup resistors as you described above, how many buttons could I attach, and which pins can I attach them to? I want to avoid frying the board, if I can! :-)

    I presume each of the buttons would be connected between the pin and 5v, although I understand that pin 13 would need an extra resistor as it’s also connected to the LED.

    Thanks for any advice,

    (another) James

    • You can use any of the digital or analog pins for a button. Just remember if you are using an analog pin, to refer to it as A0 or A1 in your code. As far as connections go, you want one side of the button to your pin and the other to ground. You DO NOT need to do anything special for Pin 13. The board is decided to reduce the impedance effects of having the LED there.

  5. The polarity of the pin is VCC with this ?
    What is the default polarity in the Input pin mode ?
    Nice tuto, thx

    • Polarity isn’t the right word. 5V and 0V are not polarities, they are voltages. The value of a pin is whatever voltage is applied to it. The default for the pin is to be floating. That’s the whole point of using the pull-up resistor, to force it to a known voltage / state.

    • Yes. INPUT_PULLUP was added in the 1.x branch, after I made these videos. Probably won’t go back to fix them. I’ve converted over to just using INPUT_PULLUP. Less typing. 😉