Any more sophisticated byte exchange can be done with binary operators.
Extracting information
You'll need some constants like
MASK SHIFT
0xFF000000 24 (first byte, most significant)
0x00FF0000 16 (second byte)
0x0000FF00 8 (third byte)
0x000000FF 0 (last byte, least significant)
You would binary AND the original value with MASK
0x12345678
AND 0x00FF0000
= 0x00340000
and then bit shift it left, e.g.
0x00340000
>> 16
= 0x00000034
So from the original value 0x12345678 you have gotten 0x34.
Setting information
The opposite direction is also possible with the same constants but opposite operators and in opposite order:
0x00000034
<< 16
= 0x00340000
and then
0x12005678
OR 0x00340000
= 0x12345678
Note that the OR operation only works reliably if the corresponding positions are 0x00. That's fine with a starting value of 0x00000000.
If you don't know that or you want to process an arbitrary number, you can introduce a step in between
0x12??5678 (?? could be anything)
AND 0xFF00FFFF (which is the inverse of 0x00FF0000 and can be expressed as ~0x00FF0000)
= 0x12005678 (whatever ?? was, it'll be cleared out)
Actual Code
Tested on Arduino Uno. The long data type is 32 bits or 4 bytes.
The code here may not be the most efficient. Advanced developers would likely not use MASK and SHIFT as arrays like this. This answer focuses more on the educational point.
long MASK[] = {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF};
byte SHIFT[] = {24 , 16 , 8 , 0};
// Extracts a byte from a larger data type
// value: larger data type to extract a byte from
// position: 0 based number, 0 = MSB, 3 = LSB
byte getByteAt(long value, byte position)
{
long result = value & MASK[position]; // binary AND
result = result >> SHIFT[position]; // Shift right, moving all bits
byte resultAsByte = (byte) result; // Convert to an actual byte
return resultAsByte;
}
// Sets a byte in a larger data type
// value: larger data type where to set the byte
// position: 0 based number, 0 = MSB, 3 = LSB
// newPartialValue: the byte to be inserted
long setByteAt(long value, byte position, byte newPartialValue)
{
long result = value & ~MASK[position]; // clear the affected byte so that it is 0x00
long valueToSet = (long) newPartialValue << SHIFT[position]; // Shift left, moving all bits
result = result | valueToSet; // binary OR
return result;
}
void setup() {
Serial.begin(9600);
Serial.println(getByteAt(0x12345678, 1)); // Prints 52, which is 0x34
Serial.println(setByteAt(0x87654321, 1, 0xBB)); // Prints -2017770719 which is 0x87BB4321
}
void loop() {
}