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.
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));
uint8_t irBitMask = digitalPinToBitMask(irPin);
while (*irPort & irBitMask) {
// your code here
}
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.
LarryD:
Prove your hypothesis
What do you get when you try this?
void setup()
{
Serial.begin(9600);
pinMode(2,INPUT_PULLUP);
}
void loop()
{
//mask off bit 2
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()
{
//mask off bit 2
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.
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:
Have you tried using a simple switch instead of your ultrasonic?