# What is PIND?

I have a code that reads the value of a sensor and because it needs to be very fast it does not use digitalRead but a strange form of reading. In the top of the code it shows:

#define IRSENSOR PIND
int irpin = 2;
I have no idea why this PIND referes to my arduino pin 2, but it only work if my sensor is in pin 2. If I want to change to pin 9 and only change the irpin varialbe it does not work. Why?

To read the sensor I use this code:

while (IRSENSOR & (1 << irpin )) {
Have no idea why this work. Does anyone know this kind of programming with arduino?

That's called direct port manipulation and is used to achieve much higher speed in operating the digital inputs/outputs. The drawback is that it's very processor dependent and changing the pins is not easy for the casual Arduino programmer.

PIND is the input register of port D (pins 0 to 7 on the UNO). That means you can use pins 2 to 7 on the UNO for your IR sensor, otherwise you have to change the port.

To use pin 9, change PIND to PINB and irpin to 1.

PORTD is a memory-mapped port, so it can't be a byte. It isn't surprising it doesn't work.

I'm not sure I understand what you want.
PIND is a macro which dereferences a pointer.
It cannot be a constant.

while (irport & (1 << irpin )) {
IS
while (PORTD & (1 << 1 )) {
IS
while (PORTD & 0b00000010) {

// PIND
// D0=0x01 D1=0x02 D2=0x04 D3=0x08 D4=0x10 D5=0x20 D6=0x40 D7=0x80

This is a more easily maintained way to do it. The macros do the work of converting pin number to port register and mask. So you can change the pin without worrying about the rest of the code.

``````int irPin = 1;

volatile uint8_t *irPort = portInputRegister(digitalPinToPort(irPin));

}
``````

gilperon:
One final question: why

PORTD & 0b00000010

will be true when pin is HIGH and will be false when pin is LOW? Is 0b00000010 considered high by arduino?

Anything that isn't zero is considered to be "true". You're no longer talking about HIGH and LOW, you left those when you did away with digitalRead. You're looking at true and false. When the pin is HIGH that expression will evaluate to true and when it is LOW it will evaluate to false.

What do you get when you try this?

``````void setup()
{
Serial.begin(9600);
pinMode(2,INPUT_PULLUP);
}

void loop()
{
byte x= PIND & 0b00000100;  //read D2
Serial.print( "PIND = " );
Serial.println( x );
delay(100);
}
``````

LarryD:
What do you get when you try this?

``````void setup()
``````

{
Serial.begin(9600);
pinMode(2,INPUT_PULLUP);
}

void loop()
{
byte x= PIND & 0b00000100;  //read D2
Serial.print( "PIND = " );
Serial.println( x );
delay(100);
}

Well, that would print 4 if the pin was HIGH and 0 if it were low. But we never use pin reads that way do we? No, we say things like if(PIND & 0b00000100) { and in that case the 4 evaluates to true every time.

Try this one:

``````void setup()
{
Serial.begin(9600);
pinMode(2,INPUT_PULLUP);
}

void loop()
{
byte x= PIND & 0b00000100;  //read D2
if( x == HIGH){
Serial.print( "PIND == HIGH " );
Serial.println( x );
delay(100);
} else {
Serial.print( "PIND == LOW " );
Serial.println( x );
delay(100);
}
}
``````

and it will print PIND == LOW every time because 4 != 1.

However, treating it as a boolean and changing the if line to :

``````if( x ){
``````

will cause it to print PIND == HIGH when the pin is HIGH and PIND == LOW when the pin is LOW.

Well, that would print 4 if the pin was HIGH and 0 if it were low.
YES

However, treating it as a boolean and changing the if line to :

if( x ){

will cause it to print PIND == HIGH when the pin is HIGH and PIND == LOW when the pin is LOW.

It would

You could obviously use:

if( x == 4){ //a bit cryptic though

However, true/false is the norm

I was just showing gilperon what was actually happening.

while (PINB & (1 << B00100000)
No

while (PINB & (1 << B00100000)) //B00100000 = 32 decimal

try

while (PINB & (1 << 5))

or try

while (PINB & B00100000))

``````//               DDDDDD
//               111100
//               321098
while (PINB & B00100000))
``````

Re attach the sketch that you have.

This is what I get

Is you serial monitor set to 9600?
Is you switch/ultrasonic wired properly?

``````void setup() {
Serial.begin(9600);
//         DDDDDD
//         111100
//         321098
DDRB  = B00010000; //0=input 1=output
PORTB = B00000000;
}

void loop() {
//         DDDDDD
//         111100
//         321098
PORTB = B00010000;  //12 HIGH
delayMicroseconds(10);
PORTB = B00000000;  //12 LOW
long start_time = micros();
//               DDDDDD
//               111100
//               321098
while (PINB & B00100000)
{
Serial.println("sh_t show up");
}

Serial.println(micros() - start_time);
delay(1000);

}
``````

1<<5
says
Shift the 1 to the left 5 places resulting in B00100000

1<<B00100000 note B00100000 is a binary number which is 32 decimal
says
Shift the 1 to the left 32 places resulting in ? ? ? ?, cannot do more than 7 shifts on a byte

EDIT: