6

Is there a way for me to read the pin mode for one of the digital pins on Arduino? In other words, can I determine whether a pin's been set to an input or output?

4

Yes, you can use the data direction registers (DDRB, DDRC, DDRD depending on which port) to check what mode a pin is in.

If a pin is in output mode then the corresponding bit in DDRx will be 1.

One complication is that the Arduino functions give each pin an "Arduino" pin number, and you have to look at a pin map to figure out which DDR register and bit corresponds to the pin you want to check. You can find a pin map for Arduinos based on the ATMEGA168/ATMEGA328 (including Uno) here...

https://www.arduino.cc/en/Hacking/Atmega168Hardware

So, for example, if you want to check if Arduino digital pin #4 is set for output, you'd look at the map and see that corresponds to PD4. That means "port D" and "bit 4", so you could say...

if ( DDRD & _BV(4) ) {   // Check bit #4 of the data direction register for port D
    // If we get here, then Arduino digital pin #4 was in output mode
} else {
    // If we get here, then Arduino digital pin #4 was in input mode
}

If you want to check Arduino digital pin #14, then you would use DDRB & _BV(5).

(_BV(x) is a macro that shifts 1 x bits to the right.)

5

There are functions which can get you the registers and bit numbers from a pin number built into the Arduino API.

uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg = portModeRegister(port);

if (*reg & bit) {
    // It's an output
} else {
    // It's an input
}
  • This answer is also right and I will be using these functions in the future. Thanks for pointing them out! – John Jul 5 '15 at 19:44
3

Seems like the Arduino core is missing a function to read the pinMode(). Here is a possible implementation:

int pinMode(uint8_t pin)
{
  if (pin >= NUM_DIGITAL_PINS) return (-1);

  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *reg = portModeRegister(port);
  if (*reg & bit) return (OUTPUT);

  volatile uint8_t *out = portOutputRegister(port);
  return ((*out & bit) ? INPUT_PULLUP : INPUT);
}

It handles illegal pin numbers (return -1), and all pin modes; OUTPUT, INPUT and INPUT_PULLUP.

Cheers!

BW: I have added this as an issue on the Arduino github repository.

  • Nice solution. They should add it to the standard. – Sod Almighty Feb 4 '18 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.