emguy
emguy

Reputation: 11

Reading a pin on Arduino Uno does not work, need help on avr-gcc

I am trying to control three LEDs on an Arduino Uno board. These LEDs are connected to the pin 3,4,5 of the port D as the outputs.

The pin 2 of the port D is connected to a push button, and it is configured as the input.

The whole circuit has bee tested with the default Arduino code and was fully functional. However, with the code given below (without arduino libraries), the input pin (pin 2 on port D) always reads HIGH, regardless the state of the push button.

Any help will be greatly appreciated.

#include <avr/io.h>
#include <util/delay.h>

#define IS_LOW(reg, pin)  ((reg) & (1 << (pin)) == 0)
#define SET_BIT(reg, pin) do{(reg) |= 1 << (pin);} while(0)
#define CLEAR_BIT(reg, pin) do{(reg) &= ~(1 << (pin));} while(0)

int main (void)
{
    DDRD &= ~(1 << DDD2); //pin 2 on port D as INPUT
    DDRD |= 1 << DDD3;    //pin 3 on port D as OUTPUT
    DDRD |= 1 << DDD4;    //pin 4 on port D as OUTPUT
    DDRD |= 1 << DDD5;    //pin 5 on port D as OUTPUT

   while(1) 
   {
       if (IS_LOW(PIND, PD2))
       {
           SET_BIT(PORTD, PD3);
           CLEAR_BIT(PORTD, PD4);
           CLEAR_BIT(PORTD, PD5);
       }
       else
       {
           CLEAR_BIT(PORTD, PD3);
           CLEAR_BIT(PORTD, PD4);
           SET_BIT(PORTD, PD5);

           _delay_ms(250);

           SET_BIT(PORTD, PD4);
           CLEAR_BIT(PORTD, PD5);

           _delay_ms(250);
       }
    }
}

Upvotes: 1

Views: 476

Answers (1)

MikeCAT
MikeCAT

Reputation: 75062

Unfortunately, the priority of & operator is lower than one of == operator.

You should define the IS_LOW macro like this:

#define IS_LOW(reg, pin) (((reg) & (1 << (pin))) == 0)

Upvotes: 4

Related Questions