How to read pinMode for digital pin?

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
}

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.


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.)

Tags:

Pins