# Accelerometer sample code

Just to illustrate my work here, I found a tutorial on how to code an accelerometer, I wanted to understand how does it work, literally get how it works, and not simply using the code without understanding it.

In the beginning of the program,there's a char variable declared as :

`char values;`

then later on the code, there was couple lines of getting the information stored in this variable, I'll give this as as example :

`x = ((int)values<<8)|(int)values;`

we want X to receive `values` and `values` , that's what that line does up there.

My question is : can someone explain to me how does that line work, and why can't we simply write it as `x = ((int)values)|(int)values;` ?

• `char values` is actually declaring an array of 10 `chars` - but none of them are assigned values (presumably the values get set when reading data from the sensor). Those array values are accessed using `values ..to.. values`. So when it uses `(int)values` it is referring to the second `char` in the array (and casting it to an `int`). – KennetRunner Sep 14 '16 at 13:33

To understand this you have to start thinking in binary.

The `|` operator is "Perform a binary OR on these two values".

The `<<8` is "Shift this value 8 bits to the left".

If you have two 8-bit values, say (in hex) 0x37 and 0x42, and you OR them together you get:

``````0x37 = 00110111
0x42 = 01000010
--------------- |
0x77 = 01110111
``````

In each column where there is a 1 in either value you get a 1 in the result.

Now if you shift the first number 8 bits to the left, you end up with:

``````0x3700 = 0011011100000000
0x0042 =         01000010
------------------------- |
0x3742 = 0011011101000010
``````

You do this when a 16-bit value has been split into two 8-bit values and you want to join them back together again into the original 16-bit value.

up in the beginning of the program, there's a char variable declared as: `char values;`

This is not a “char variable”, it's an “array of 10 chars”.

`((int)values<<8)|(int)values`

Majenko's answer perfectly explains the intent of the author of the tutorial, but that is not necessarily what the code actually does. As it stands, this piece of code is buggy. Or, to say the least, it has a serious portability problem: it will probably work fine on ARM-based boards, but it will fail on AVR-based boards, and on x86.

The reason is that, in C and C++, the type `char` can be either signed or unsigned, depending on the platform. On most platforms, including AVR, it is signed. This implies that, when a `char` is converted to `int`, it undergoes sign extension instead of being just zero padded. To put it graphically, let's assume the sign bit (most significant bit) of `values` is `s`, then:

``````values      =         sxxxxxxx
(int)values = sssssssssxxxxxxx
``````

Here I am assuming an AVR (16-bit ints). If the sign bit happens to be zero, this will work as intended. This is the case in Majenko's example. But if we replace 0x42 with 0xa2, we will have:

``````values         =   0x37 =         00110111
(int)values    = 0x0037 = 0000000000110111
(int)values<<8 = 0x3700 = 0011011100000000
values         =   0xa2 =         10100010
(int)values    = 0xffa2 = 1111111110100010
``````

Then, the bitwise OR gives

``````0x3700 = 0011011100000000
0xffa2 = 1111111110100010
------------------------- |
0xffa2 = 1111111110100010
``````

and the data in `values` is lost.

Conclusion: `values` should be declared as an array of unsigned chars, as this will enforce zero-padding instead of sign extension. Always use unsigned types when doing bit manipulations. And you probably should find a better tutorial to learn this kind of stuff.