When to use Arduino’s pinMode() (and why)

All Arduino boards have a bunch of I/O pins, with some having analog (or “analog”) capability.  How you use the pins depends on your code.  Although Arduino’s pinMode() does setup some pins, it isn’t always necessary and may not always work the way you expect.

Scope for pinMode()

This post is focused on the 8-bit AVR Arduino boards such as the Uno, Mega, and Leonardo boards which are based on the ATmega328, ATmega2560, and ATmega32u4 in that order.  It may apply to the other Arduino boards based on non 8-bit AVR microcontrollers.  If you have some experience with other boards, leave a comment below.

Startup State

On power-up, all pins are initialized to be a digital INPUT.  An INPUT, the pins are left in a high-impedance state.  This means they have a very high resistance, so it won’t cause any shorts.

Pin 13, is an exception.  When an Arduino board is first powered on, the main chip runs a program called a bootloader.  The primary purpose of the bootloader is to listen on the serial pins to see if there is new code to load into PROGMEM.

The bootloader flashes the LED connected to Arduino Pin 13.  In order to do this, the pin must be temporarily configured as an OUTPUT.  Once the bootloader is done, Pin 13 is returned to the INPUT state.  Normally this isn’t a concern and you could probably continue to use Pin 13 as a regular I/O pin. Can it tolerate Pin 13 temporarily becoming an OUTPUT then toggling between HIGH and LOW? If you plan to connect Pin 13 directly to Power or Ground, you may want to include a 1k current limiting resistor, just in case.

Analog Input

Analog Input pins are used to measure a voltage. Sometimes I see people use Arduino’s pinMode() to configure it as an INPUT. However, this is not necessary, for two reasons.

  1. pinMode() configures a pin for use as a digital input, not analog input.
  2. When analogRead() is called, it always reconfigures the Analog Pin for “input”.
Analog Input pins are special because they are connected to an analog multiplexer which is connected to a single analog-to-digital (A/D) converter.  So in order for analogRead() to work, the multiplexer has to be configured first.  This eliminates the need to call pinMode() on Analog Pins. Even though, I still tend to use pinMode() in my setup() function anyway. This way when glance at the code, I know which pins I’m using.

Analog Output (PWM)

Unlike digitalRead() which can be used on both INPUT and OUTPUT, analogWrite() only works for OUTPUT.  (Read this article if you didn’t know digitalRead() could be used on digital OUTPUTs.)  analogWrite() works on pins which support Pulse-Width Modulation (PWM), so it only makes sense to use it as an OUTPUT.  That being the case, like analogRead(), analogWrite() automatically sets the pin to OUTPUT when called.

Pull-Up Resistors

With the release of the Arduino IDE 1.0.1, a new mode was added to pinMode() called INPUT_PULLUP.   This is important because while this very useful state was added, the default behavior of pinMode()’s INPUT also changed.  In case you are porting code or still using an older version of the Arduino Library, here is how the behavior works (and changed).

Pre-1.0.1

Before 1.0.1, when pinMode() is called with INPUT the current state of the PORTx is used to determine whether the pull-up resistor would be enabled or not.

1.0.1 and Later

Starting with 1.0.1,  if pinMode() is called with INPUT the internal pull-up resistor is explicitly disabled.  However, when pinMode() is called with INPUT_PULLUP, the pull-up will be enabled.  You can still override the state of the pin after pinMode() has been called by using digitalWrite(), like in pre-1.0.1.

Conclusion

So when it comes down to it, when do you use Arduino’s pinMode()?  The only time you MUST call pinMode() is to setup a pin for use as a digital OUTPUT.  As a best practice, if you plan to use a pin as a digital INPUT or analog OUTPUT (PWM), you should call pinMode() in setup(), even though it is optional.  That way when you read your code, you can quickly see what pins are being used.

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

One thought on “When to use Arduino’s pinMode() (and why)

  1. Thanks for the clear explanation. I’m just starting out with Arduino and was wondering why one snippet of code I had used the pinMode() function and the other didn’t, even thought they were functionally equivalent. Since they were using analogWrite(), OUTPUT mode is implied.