Print all bits in PIND

Is there an easy way to print the contents of PIND in binary?? I am trying
Serial.print(PIND,BIN) but it only prints 1, which I do not understand. I also tried Serial.print(DDRD,BIN) with identical lack of success. Thanks for any hints. AA

Leading zeroes are not printed

Try this


void setup()
{
    Serial.begin(115200);
    for (int bit = 7; bit >= 0; bit--)
    {
        Serial.print(bitRead(PIND, bit));
    }
    Serial.println();
}

void loop()
{
}

Only bit 0 is HIGH, the others (which would be on the left) are LOW.

This is my setup()

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  DDRD &=!B00100000; // Set pin/terminal D5 to INPUT, all other pins left as untouched
      // All bits except the 5th in DDRD left untouched as they were before this line of code)
    Serial.begin(9600);
    for (int bit = 7; bit >= 0; bit--)
    {
        Serial.print(bitRead(PIND, bit));
    }
    Serial.println();
    delay(3000);
}

That prints B00000001. Is this right?? I was expecting only bit 5 to be 1.

Why is that??

This works, but using PIND does NOT.

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  DDRD = B00100000; // Set pin/terminal D5 to INPUT, all other pins left as untouched
    // Same as DDRD = DDRD & !B00100000 = DDRD & B11011111 = B00000000 (if all bits in DDRD were 0,
    // also all bits except the 5th in DDRD left untouched as they were before this line of code)
    for (int bit = 7; bit >= 0; bit--) {
      Serial.print(bitRead(DDRD, bit));
      Serial.print(" ");
    }
    delay(10000);
}

Which begs the question what is PIND used for??

How do you know?

From https://docs.arduino.cc/retired/hacking/software/PortManipulation/

PIND - The Port D Input Pins Register - read only

Note the last two words

OK, read only. But why is it that this prints 00000001 instead of 00100000??

void setup() {
  Serial.begin(9600);
  DDRD = B00100000; 
  for (int bit = 7; bit >= 0; bit--) {
      Serial.print(bitRead(PIND, bit)); // Compute the
      Serial.print(" ");
    }
    delay(10000);
}

If DDRD id Read only then you cannot directly set its bits. What happens if you set the pinMode() of the pins instead ?

Let's find out


void setup()
{
    Serial.begin(115200);

    setMode(INPUT);
    printBin("INPUT\t");

    setMode(OUTPUT);
    printBin("OUTPUT\t");
}

void loop()
{
}

void setMode(byte mode)
{
    for (int pin = 2; pin < 8; pin++)
    {
        pinMode(pin, mode);
    }
}

void printBin(char* mode)
{
    Serial.print(mode);
    for (int bit = 7; bit >= 0; bit--)
    {
        Serial.print(bitRead(PIND, bit));
    }
    Serial.println();
}

A "read-only variable" is usually a variable whose value cannot be changed after it's been initialized, meaning it can only be read and not modified. So, if in your code I am indeed reading PIND using bitRead(PIND, bit), then what puzzles me is why it prints 00000001 instead of 00100000 after Serial.print(bitRead(PIND, bit)); . Can bitRead indeed read PIND??

PIND and DDRD are not variables, rather they are registers in the processor

NOTE - my sketch in reply #11 is reading the PIND register rather than the DDRD register that it should be. Change it to read the correct register

As the comment states, this sets the pin corresponding to bit 5 to input mode (this is D5 on an UNO). Don't overlook the '!' which inverts the binary value, the code is performing a logical AND of the current contents of the DDRD register with B11011111, setting bit 5 to 0 and leaving all other bits unchanged.

This reads the state of each pin in the PIND register (D0 - D7 on an UNO), and prints out that state. If the pin is in output mode, then it reads the state last written to the corresponding output register, if the pin is in input mode, it reads the state of the input (a HIGH logic voltage on the input will return a 1, a LOW logic voltage will read a 0, a floating pin will return random values).

Don't think its mentioned on that webpage, on some AVR processors writing a '1' bit to the PINx register will toggle the state of the corresponding bit in the PORTx register. Fast way of toggling an output pin on a UNO.

PIND has the values of the input pins, whether or not they are in "input mode", and whether or not they are connected to anything. Pin 0 is going to be a 1 because it's connected to the USB/Serial converter, which is "idle high."
pin 5 will only (reliably) show up as 1 if it's connected to a high logic signal (possibly including the internal pullup, which your code did not enable.)

Actually, it doesn't. "!" is a LOGICAL inversion, and !B00010000 is just 0, because any non-zero value is seen as "true", logical inverse of true is false, and false is 0.

For bitwise inversion, use "~", as in: DDRB &= ~0b00010000;

Right on.

void setup() {
  Serial.begin(9600);
  PIND |= ~B00100000; 
  for (int bit = 7; bit >= 0; bit--) {
      Serial.print(bitRead(PIND, bit)); 
      Serial.print(" ");
    }
  delay(10000);
}

Prints the "expected" B11011101, with pin 0 being 1 for the reason you mentioned. However, if PIND is truly read-only, why does it let me write/set PIND as per PIND |= ~B00100000; ??

If you are on a 328P then it’s not read only. It’s a shortcut in the documentation. In reality writing a 1 in a bit will toggle the associated pin.

Note that doing

The |= is redundant because PIND isn’t a regular register where bits must be preserved—it’s a toggle register, and only the 1 bits in a write operation matter.

But PIND is "writable" except for certain AVR's (mega8, IIRC).
Every set bit written to PIND toggles the matching bit of PORTD. It won't change PIND at all so that's not a real write? I dunno but I can code { PIND = value; } to get desired outcomes.

DDRD is read/write. But PIND bits are pin states which can be set or clear whether the direction is INPUT or OUTPUT.

Without knowing the wiring to the pins as well as DDRD and PORTD values, how can PIND results be predicted? IMO the discussion has to include all of that.

I only have the Arduino UNO connected to my computer, no other wires, if that is your question.