0

I'm reading values from an accelerometer and saving them in a buffer called 'values'. Each accelerometer reading is 10 bits long, but the values are read in as bytes, so eah accelerometer reading is actually two bytes or two values in the 'values' buffer. This is sample code on how to combine those two bytes to get the one value:

x = ((int)values[1]<<8)|(int)values[0];

I get that I'm combining values[1] and values[2] and I'm pretty sure the (int) part is type casting those parts as integers (although I'm not sure why). The parts that have me really confused are <<8 and the vertical bar |. What are these two parts doing?

Thanks for any explanation and help you can give!

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190

5 Answers5

3

It's a bitmask.

You are left shifting (<<) the value in values[1] by 8 bit-positions. and then ORing (|) it to the value in values[0].

Please take some values and try to work through them. You will understand it better.

Here's a link for more reading and bit-manipulation examples.

Prince
  • 20,353
  • 6
  • 39
  • 59
2

This line of code combines two char into a int in a way that first char is moved 8 bits.

For example, value[0] = 5, value[1] = 1, then the read in value should be, 128 + 5 = 133. Because the high byte 1 means 128. Another way to look at it is:

x = ((int)values[1]<<8) + (int)values[0];

Replace or with +, it will be more readable. Hope this helps.

m. c.
  • 867
  • 5
  • 12
0

The << operator shifts the bits in the second byte left by 8 bits so for example 0000000011111111 becomes 1111111100000000. The | is the binary "or" operator that combines the two bits in every position making it 1 if either bit or both bits are 1.

Roxxorfreak
  • 380
  • 2
  • 10
0

Take for example a 10-bit reading of 0101010111 in binary.

The lower 8 bits go to values[0] = 01010111 in binary (= 87 decimal).

The higher 2 bits go to values[1] = 01.

To recover the original 10-bit number from values:

(int)values[1] << 8   -->   01 << 8   -->   0100000000

values[1] is converted to a int (typically 32 bits) and then shifted left << 8 bits.

((int)values[1]<<8) | (int)values[0]   -->   0100000000 | 01010111

or in vertical notation to express a bitwise-or:

   0100000000
 |   01010111
 ------------
   0101010111

QED

Matt
  • 20,108
  • 1
  • 57
  • 70
0

You have 2 bytes (1 byte = 8 bits) and you are trying to read in a 10 bit value, which is why you need 2 bytes instead of just using 1. When you are reading in the value you need to cast the 2 bytes to int so you can treat them like and integer value, but there is an issue, if value[1] is 3 (00000011) and the next byte value[0] is 227 (11100011) you can get a proper reading if you add them so you need to bit shift value[1] left by 8.

When you bit shift a unsigned char/char/byte by 8 you end up with 0, so you need to cast both value[1] and value[0] to an int so when you do the bit shift you end up with 768 (00000011 00000000) now you | that with value [0] and you end up with

(00000011 00000000 | 00000000 11100011) = (00000011 11100011) = 995

note I am only using 16bit ints so the example isn't full of a bunch of 0s.

If you have access to a programming calculator it can help you understand why you need to cast these byte values to ints, it can also just help you with casting in general. I would sugest playing around with the windows Calculator app for a bit if you have access to it. In order to get it into the programmer view go to view->programmer.

109
  • 137
  • 1
  • 10