Assume c is 1001 0010 in binary. The first pass through the for-loop...
i =7
((c >> i) & 1 | '0') --> The zero character ('0') can also be interpreted as the byte value 0x30 or a bit value of 00110000. I'll use the bit value until the end.
((10010010 >> 7) & 1 | 00110000) --> The double greater-than is a bit shift to the right. The bits in c are shifted 7 bits to the right. We're left with the left-most bit...
((00000001) & 1 | 00110000) --> The ampersand is a bitwise-and. If both bits are one the result is one otherwise the result is zero...
(00000001 | 00110000) --> The bar is a bitwise-or. If either bit is a one the result is one otherwise the result is zero...
00110001 --> Which is also 0x31. Which is also '1'. The character '1' is sent to the serial port.
i = 6
((c >> i) & 1 | '0')
((10010010 >> 6) & 1 | 00110000)
((00000010) & 1 | 00110000)
(00000000 | 00110000)
00110000 --> Which is also 0x30. Which is also '0'. The character '0' is sent to the serial port.
i = 0
((c >> i) & 1 | '0')
((10010010 >> 0) & 1 | 00110000) --> Shifting by zero bits results in the same value...
((10010010) & 1 | 00110000)
(00000000 | 00110000)
00110000 --> Which is also 0x30. Which is also '0'. The character '0' is sent to the serial port.
Sure - I'm going to make more variables to make it easy to follow:
unsigned char a = c >> i; // moves the bit of interest into the rightmost position
unsigned char b = a & 1; // resets all bits except the rightmost
unsigned char d = b | '0'; // converts the value (0 or 1) to a character '0' or '1'
Serial.write(d); // writes the character to the Serial connection
Nick's way of writing this avoids the need for the intermediate variables.
The AND operation (&) result one only when both operands are 1, and zero otherwise:
XXXXXXXM
& 00000001
--------
0000000M
so that whatever M is (0 or 1) in the first operand, it will appear in the same position in the result, and all other bits of the result will be zeros.
Sorry for not getting this but what is the second operand?
I get one of them is 00000001 that we got from the bitwise right shift, but what are we comparing this too for the AND. Why is the other side of the AND a 1, im expecting that to be another byte.
There is no compairing going on, these are digital logical operations on the bit level. You are ANDing the value on the right with the result of what has been evaluated to the left of it.
How can we do an AND without comparing two bit patterns
We do not compair the bit patterns we perform a function with them. You do not say a subtraction is a result of compairing two bit patterns.
In computing terms a compair is an operation that involves subtracting two values and doing nothing with the result but leaving the status register bit flags to reflect the result.
In C this is done by the == operation
That gives decimal 119 a binary value of 0111 0111.
To isolate the two right-most bits I would AND with decimal 3 which has a binary value of 0000 0011