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.
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 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.
- pinMode() configures a pin for use as a digital input, not analog input.
- When analogRead() is called, it always reconfigures the Analog Pin for “input”.
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.
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).
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.
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.