Hi,
I know you can read the state of ports with PINx, where x is the port register. However i am unsure how to manipulate this to read a single port.
What I wish to do is read digital 3 with the PINB (or is it PIND?) command, and then compare whether it does not equal a boolean value. How can this be done, since other pins will be high, and might interfere?
Thanks
Reading ports via PIN Commands

 Freetronics Staff
 Posts:853
 Joined:Tue Apr 09, 2013 11:19 pm
 Location:Melbourne, Australia
 Contact:
Re: Reading ports via PIN Commands
Hi avrdude,
The short answer is, this is essentially what digitalRead() is doing already. But I'm guessing you want lower overhead/higher performance.
Another thing you can try is using a library like digitalWriteFast or this one called digitalIOPerformance that I put together last year (not Freetronicsrelated):
https://github.com/projectgus/digitalIOPerformance
However, to answer your actual question  you need to use bitwise operators to see the actual value.
On Eleven/Uno, we can see that digital pin 3 is PD3 (Port D bit 3.) There are lots of ways to figure this out, I looked at the Eleven PDF https://github.com/freetronics/Eleven/b ... evenR3.pdf but there are other diagrams out there.
So if we read PIND:
We get all 8 input values from port D as a byte. We want to look to see whether bit 3 is set. Bit 3 is value 8 (We count bits from zero and they double each time  so values are 1,2,4,8.) You can also show this as "1 left shifted 3 times", or 1 << 3 in C, which is convenient to read because that "3" matches exactly to the 3 in "PD3". Some explanation can be found here.
So we can do a bitwise AND to expose just that value:
or
Suppose the whole PIND value (all 8 pins) looks like this in binary
The bit we want is bit 3, the value of 8:
(Just to confuse you here we're counting bits from the right hand end here not the left hand end, because the rightmost digit in a number has the lowest value! So rightmost is 1, next left is 2, next left is 4, next left is 8.)
So if we bitwise AND the pin value with the bit for the pin we can are about, we get this in binary
Which equals 00001000 (8) if the pin is high and the bit is set as shown above, or it would equal 00000000 if the pin was low and the bit was not set. Generally you can test for x != 0 to determine if the pin was high or not.
Hopefully that makes some sense. If you're looking for more insight into how to understand this, "bitwise operations" are the thing to read up on.
 Angus
The short answer is, this is essentially what digitalRead() is doing already. But I'm guessing you want lower overhead/higher performance.
Another thing you can try is using a library like digitalWriteFast or this one called digitalIOPerformance that I put together last year (not Freetronicsrelated):
https://github.com/projectgus/digitalIOPerformance
However, to answer your actual question  you need to use bitwise operators to see the actual value.
On Eleven/Uno, we can see that digital pin 3 is PD3 (Port D bit 3.) There are lots of ways to figure this out, I looked at the Eleven PDF https://github.com/freetronics/Eleven/b ... evenR3.pdf but there are other diagrams out there.
So if we read PIND:
Code: Select all
int x = PIND;
So we can do a bitwise AND to expose just that value:
Code: Select all
int x = PIND & 8;
Code: Select all
int x = PIND & (1 << 3)
Code: Select all
01011010
Code: Select all
01011010
^
this one
So if we bitwise AND the pin value with the bit for the pin we can are about, we get this in binary
Code: Select all
01011010 &
00001000
Hopefully that makes some sense. If you're looking for more insight into how to understand this, "bitwise operations" are the thing to read up on.
 Angus
Re: Reading ports via PIN Commands
Thanks for the reply, I am familiar with both the binary system and with bitshift, but your information was nonetheless very good. So if we do
if( (PIND << 3) & 00001000)
We can check if pin three is high.
However, what would be the equivalent of
if ( digitalRead(3) != prevClock)
Where prevClock is a Boolean of value either high or low (obviously, but the point is that it will change).
So how can we check this? I have experimented with some of the bitwise operators, but I am yet to find out how to do it.
Thanks
if( (PIND << 3) & 00001000)
We can check if pin three is high.
However, what would be the equivalent of
if ( digitalRead(3) != prevClock)
Where prevClock is a Boolean of value either high or low (obviously, but the point is that it will change).
So how can we check this? I have experimented with some of the bitwise operators, but I am yet to find out how to do it.
Thanks

 Freetronics Staff
 Posts:853
 Joined:Tue Apr 09, 2013 11:19 pm
 Location:Melbourne, Australia
 Contact:
Re: Reading ports via PIN Commands
Hi avrdude,
Sorry for the slow reply.
Probably the easiest thing you can do is just store the value as a number in both places:
This works because you can also use numbers as boolean values (nonzero meaning true, zero meaning false.)
The other thing you can do is cast the number to a bool value:
 Angus
Sorry for the slow reply.
Probably the easiest thing you can do is just store the value as a number in both places:
Code: Select all
byte last_value;
void loop() {
byte current_value = PIND & (1<<3); // is pin 3 set?
if(current_value != last_value) {
// something has changed
if(current_value) {
Serial.println("Pin is high!");
} else {
Serial.println("Pin is low!");
}
last_value = current_value;
}
}
The other thing you can do is cast the number to a bool value:
Code: Select all
bool last_value;
void loop() {
byte current_value = PIND & (1<<3); // is pin 3 set?
if((bool)current_value != last_value) {
// something has changed
if(current_value) {
Serial.println("Pin is high!");
} else {
Serial.println("Pin is low!");
}
last_value = current_value;
}
}
Re: Reading ports via PIN Commands
Thanks angusgr, I'll probably use the bool example so I can easily manipulate the value with the ! operator.