-2
uint8_t payload[] = { 0, 0 };
pin5 = analogRead(A0);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;

This is code from the XBee library published by andrewrapp on GitHub. I was wondering how the bitwise operation worked. so suppose pin 5 gets an analog value of 256 which as I am using a particle photon board comes in a 12bit format text as 000100000000. so does payload[0] get the last eight bits ie 00000000, or does it get value after shifting ie, 00000001? Also then what becomes the value in payload[1]?

I want to add a 4-bit code of my on using a bitmask to the first four bits in the array followed by the data bits. Can I & payload[1] with a 0X1 to payload[1] for this?

ecain
  • 1,282
  • 5
  • 23
  • 54
  • 1
    What is the type of `pin5` and what is the return type of `analogRead` function? Please edit your question to provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Akira Jul 25 '17 at 10:55
  • `payload[0] == 1, [1] == 0` - just as the bits are written in text – Joop Eggen Jul 25 '17 at 10:56
  • There are plenty of guides about bitwise operations available. You have given no information about what `pin5` is so, at best, people will have to guess about what the result of using bitwise operations on it is. – Peter Jul 25 '17 at 10:56

2 Answers2

0

The code in your example reverser the content of pin5's two bytes into payload array: the most significant byte is placed into payload[0] and the least significant byte is placed into payload[1].

If, for example, pin5 is 0x0A63, then payload would contain 0x63, 0x0A.

If pin5 has a 12-bit value, you can use its four most significant bits to store a four-bit value of your own. To make sure the upper bits are zeroed out, use 0x0F mask instead of 0xFF:

payload[0] = pin5 >> 8 & 0x0f;
//                         ^

Now you can move your data into the upper four bits with | operator:

payload[0] |= myFourBits << 4;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

So you want to understand what the stated operations do. Let's have a look if we can clarify this, by examining the pin5 variable and subdividing it into 2 parts:

pin5              000100000000
                  MMMMLLLLLLLL

M = 4 Most significant bits, L = 8 Least significant bits

payload[0] takes the result of some operations on pin5:

pin5              000100000000
>> 8              000000000001  Shifts all bits 8 positions to the right
                  00000000MMMM  and fills the left part with zeroes

so you have the originally leading 4 bits right-aligned now, on which an additional operation is performed:

                  000000000001
& 0xFF            000011111111  Anding with FF
                  000000000001

Right-shifting a 12-bits variable by 8 positions leaves 4 significant positions; the leading 8 bits will always be 0. 0xFF is binary 11111111, i.e., represents 8 set bits. So what is done here is Anding the 4 least significant bits with 8 least significant bits in order to make sure, that the 4 most significant bits get erased.

                  00000000xxxx  Potentially set bits (you have 0001)
                  000011111111  & 0xFF
                  00000000xxxx  Result
                      0000xxxx  Storing in 8-bits variable
payload[0] =          00000001  in your case

In this case, the Anding operation is not useful and a complete waste of time, because Anding any variable with 0xFF does never change its 8 least significant bits in any way, and since the 4 most significant bits are never set anyway, there simply is no point in this operation.

(Technically, because the source is a 12-bits variable (presumably it is a 16 bits variable though, with only 12 significant (relevant) binary digits), 0x0F would have sufficed for the Anding mask. Can you see why? But even this would simply be a wasted CPU cycle.)

payload[1] also takes the result of an operation on pin5:

pin5              MMMMLLLLLLLL  potentially set bits
& 0xFF            000011111111  mask to keep LLLLLLLL only
                  0000LLLLLLLL  result (you have 00000000)
                      xxxxxxxx  Storing in 8-bits variable
payload[1] =          00000000  in your case

In this case, Anding with 11111111 makes perfect sense, because it discards MMMM, which in your case is 0001.

So, all in all, your value

pin5              000100000000
                  MMMMLLLLLLLL

is split such, that payload[0] contains MMMM (0001 = decimal 1), and payload[1] contains LLLLLLLL (00000000 = decimal 0).

If the input was

pin5              101110010001
                  MMMMLLLLLLLL

instead, you would find in payload[0]: 1011 (decimal 8+2+1 = 11), and in payload[1]: 10010001 (decimal 128+16+1 = 145).

You would interpret this result as decimal 11 * 256 + 145 = 2961, the same result you obtain when converting the original 101110010001 from binary into decimal, for instance using calc.exe in Programmer mode (Alt+3), if you are using Windows.

Likewise, your original data is being interpreted as 1 * 256 + 0 = 256, as expected.