# Arduino Uno reading a logic 0 signal as 1

I have a program on my Arduino Uno that needs to execute quickly, so I'm trying to carry it out by dealing directly with registers. I made a few recent changes to my code, which was originally working fine (unfortunately a change in some of the hardware that's going into this project means I can't revert to the earlier version).

Since the changes, the Uno has developed an issue that I've isolated to one specific problem: I am using an external device to write 0V to the Uno's pin D4 (pinout diagram linked at the bottom of this post), but Serial.print() tells me that pin is getting a 1. I've confirmed the voltage with a multimeter, so either the Arduino is broken or I'm missing something.

const uint8_t pinO = 4; // Register D
void setup() {
DDRD &= ~(1<<pinO); // sets pin as input
PORTD &= ~(1<<pinO); // I wasn't sure I needed this line. Is this what I'm doing wrong?
Serial.begin(9600);
}

void loop() {
Serial.print((PIND >> daqpinO) && 1);
}


There's more to the code, but this is everything that should be relevant to the issue. What I see is that writing 3.3V to a different pin on register D seems to be what's causes this pin to start reading high. That shouldn't be happening though, right? All the GPIO pins should be toggled independently?

• What is it daqpin0? Please put all code. – AltAir Apr 15 at 4:58

## 3 Answers

I think this issue might be with your bit math in the print statement. In the snippet below I've included a typical technique for doing this (see: https://stackoverflow.com/questions/9804866/return-a-specific-bit-as-boolean-from-a-byte-value).

Also, your second line clearing the bit in PORTD after having set it as an input by clearing DDRD will effectively disable the input pull-up resistor on that input. If the source driving your input can drive both high and low (push-pull) that shouldn't be an issue, but if you're just shorting the input to ground (i.e. with a switch or open collector output) you may have undefined behavior (floating input) when the input isn't actively driven. See Arduino's page on port manipulation for more info:

    const uint8_t pinO = 4; // Register D

void setup() {
// Clearing DDRD sets the pin to input mode
DDRD &= ~(1<<pinO);
// This is the equivalent of digitalWrite and will disable the input pull-up
PORTD &= ~(1<<pinO);

Serial.begin(9600);
}

void loop() {
//Serial.print((PIND >> daqpinO) && 1); <-- This looks like it could be your issue
//Proposed snippet for checking a bit using a bit-mask
Serial.print((PIND & (1<<pinO)) != 0);
}


## Edit 1

Added details on why precisely the original version is not working:

Your original statement: (PIND >> daqpinO) && 1 is inadvertently True when pin numbers above 4 are set. This is because && is a LOGICAL AND statement and not a BITWISE AND statement. As an example: let's say that pinO is written LOW and that pin 6 on PORTD is currently written HIGH. The port status would be PIND = 0b01000000. The result of your original statement would be:

    (PIND >> pinO) = 0b00000100
// Logical AND operation will return True because (PIND >> pinO) is non-zero
0b00000100 && 1 = True
// Bitwise AND operation would have returned the intended result
// because it would mask out more significant bits
0b00000100 & 1 = False


Use single & instead if && to fix it. You need a bitwise AND, not logical AND.

Your pin0 is set as an input. You cannot be writing to it. So your statement PORTD &=~(1<

• Writing to PORTD register controls the internal pull-up. So it is normal to write it. In this case it turns the pull-up off. – Justme Apr 15 at 5:11