digital input via PINB

Hey everyone,

I am trying to read from an encoder and I am afraid that the digitalRead method is too slow and I am missing data.

After reading about this a bit, I found some code to read the input on a digital port the direct way. However my code is not working.

Can anyone help me out with this:

void setup() {
  //Clear the bit for Pin 2
  DDRB &= ~_BV(DDB2);
  Serial.begin(9600);
}


void loop() {
  // read the value on Pin 2
  Serial.println(PINB & _BV(PB2));
  
}

The message I get is PB2 is not defined, anyone have any ideas?

(deleted)

I think PB2 is defined in Arduino.h. Try to include it. Else use a binary constant as in this tutorial:

use 0x04 for the bit pattern - bit 2 high, no need for symbolic names here,
bit 2 is bit 2.

void setup() {
  //Clear the bit for Pin 2
  DDRB &= ~0x04;    // not needed, all pins are INPUT at reset.
  Serial.begin(9600);
}


void loop() {
  // read the value on Pin 2
  Serial.println(PINB & 0x04);
  
}

If you do want to name the pin, give it a meaningful name like

#define  encoder_pin 2
#define encoder_mask 0x04

You can use binary constants, ie 0b00000100 instead of 0x04,
but try not to, they are usually sources of error since 5 zeroes looks the same as 6
zeroes really, hexadecimal is much more human friendly. You can also define
masks in terms of the bit number like (1<<2)

What's wrong with PORTB2 ?

AWOL:
What's wrong with PORTB2 ?

Nothing except that its just bit 2, no different from PORTC2, PORTD2, no need
to name bit 2 (except perhaps BIT2). Symbollic names are to convey meaning
where that is not obvious from context - here the context is obvious.

How remiss of Atmel to define it in their header files.

Everyone, thanks for chiming in and for your help.

I actually realized I am using digital pin 2, which if I believe is actually PIND, not PINB.

What I am confused about is why is bit 4 pin 2 and not bit 2?

I would think it should be this:

void setup() {
 
  Serial.begin(9600);
}

void loop() {
  // read the value on Pin 2
  Serial.println(PIND & 0x02);
  
}

Am I missing something with the Pin/Bit relationship?

And I definitely don't need to clear the bit to be read?

Thanks!

If you are on linux the cause of your problem (no Pxn stuff defined) is that the portpins.h (avrlibc) file in the linux tarball is broken. You can download the avrlibc source tarball and get a good copy from that.

If you are wanting to read from an encoder, perhaps you should consider using an interrupt.