Understanding LSB, MSB and shift operator!

Hello, I have basic questions here, I hope that you can help me. I have a sensor (BOSCH BMI160) that is linked to a developer board. Among other things, this sensor the acceleration as well as the orientation on (in x, y and z directions). Using an Arduino script, the values ​​are transferred from the sensor to the board and then to the PC. A total of 12 registers (Page 51 of datasheet) are read out, one "MSB" (Bit or Byte?) and one "LSB" value for each coordinate. Now I have been told that in the end you have to perform the following operation to link the values:

msblsb = (int16_t)(msb << 8 | lsb);
  1. I have read, that "Shift the value in MSB left by 8 bits and OR with the 8-bits of LSB".
    I imagine this as follows: The sensor measures the acceleration e.g. in the X direction, let's say it is 5 m / s². Now this value is encoded (in binary?) And divided into LSB and MSB and stored in a register (why the split?). If only the MSB and LSB are saved, will the information be lost (the values ​​between the MSB and LSB)? If I now have these values ​​on the PC and want to convert them into values ​​(m / s²) that are meaningful for humans, this shift operator is apparently required. Can someone give me a concrete example of how this is calculated exactly?

My task is to convert these data from the registers into meanigful data, I am not a Computer Scientist or an Engineer, so i need verybasic help. Thank you!

2 Likes

in this case MSB/LSB refer to 8-bit bytes. The datasheet indicates 7:0 LSB or bit 7-bit 0 is Least significant byte.

the following is correct to combine 2 bytes into a 16-bit value

msblsb = (int16_t)(msb << 8 | lsb);

so if the LSB is 0x12 and the MSB 0x34, the 16-it value is 0x3412

1 byte is a value in 8 bits. Maximum combinations = 256 (0 through 255).
Sensors transfer stuff in bytes, to store or transfer data with values over 255 you need more bytes.
A 16 bit value (int in Arduino) has a least significant byte (LSB) and most significant byte (MSB).
The LSB stores the remainder after dividing by 256, and the MSB stores the quotient.
Put the two 8 bit bytes together and you have the original 16 bit value.
The way you do that in C code is...

 value = (int16_t)(msb << 8 | lsb);

msb << 8 is a shift left by 8 binary places. Just like shifting digits left by 1 digit in decimal multiplies by 10, shifting left by 1 digit in binary multiplies by 2. Therefore shifting by 8 binary digits multiples by 2 eight times, or 256 in total.

So you should see the above puts the two bytes of the number (the results of dividing by 256) back together again to give the original value.

pcbbc:
The LSB stores the remainder after dividing by 256, and the MSB stores the quotient.

Thank you very much, but can you explain this? Assuming, the Sensor measured a x-Value of 5. Because the sensor integrate 16 bit - the decimal 5 is in binary 0000000000000101, right?
Now the sensor divides this 16 bit in a Most Significant Byte (the left most 8 bits) - so 00000000 and a Least Siginificant Byte 00000101. Are my considerations correct so far?

Now after reading the MSB and LSB from the register, I want to combine them again to a 16-bit value to be able to transform then to a meanigfull m/s² value - therefore this luittle peace of code mentioned above does this for me. What this code actually does is taking the LSB and just hangs it on the MSB at the back (right side), correct?

So why does the sensor divides the 16bit value into 2 8 Bit values, stored in 2 different registers? Would it not be easier to sotren the whole 2 bytes in one register, so that we do not have to make this shift thingy?

because the hardware may only have an 8-bit data bus

If "msb" and "lsb" are bytes, that line of code will not even work right. It SHOULD be:

msblsb = ((int16_t)msb << 8) | lsb;

Regards,
Ray L.

Spacetoon you have it exactly right.
Most likely the device sits at the end of the I2C or SPI bus. That only allows you to transfer bytes each way. If you want bigger values you have to split them up into separate registers.

RayLivingston:
If "msb" and "lsb" are bytes, that line of code will not even work right. It SHOULD be:

msblsb = ((int16_t)msb << 8) | lsb;

Regards,
Ray L.

No, integer promotion ensures it works correctly as is. At least I’m assuming Arduino follows the standards...

Integer Promotions
Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int. Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators.