0
\$\begingroup\$

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?

https://www.google.com/search?q=arduino+uno+pinout&client=firefox-b-1-d&tbm=isch&source=iu&ictx=1&fir=fbbDkYhiQfV2sM%252CFkhuyc9ufXPLnM%252C_&vet=1&usg=AI4_-kR696oFGr1iYjvDWQkqpvcdtaQOGg&sa=X&ved=2ahUKEwi13dL9oNHhAhWtIjQIHftuCXkQ_h0wFnoECAsQBA&biw=1536&bih=750#imgrc=fbbDkYhiQfV2sM:&vet=1

\$\endgroup\$
  • \$\begingroup\$ What is it daqpin0? Please put all code. \$\endgroup\$ – AltAir Apr 15 at 4:58
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
-1
\$\begingroup\$

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

\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Justme Apr 15 at 5:11

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.