Hex numbers indicates, of course, the address of each register. However, I can't get how, if the first instruction only requests from the MPU_addr (constant), it changes to the consecutive registers. Is it that <<8| makes something like a sum or a logic OR to switch the register to read?

One important thing to note though is that the use of Wire.read() inside the shifting and ORing like that is not good. There is no guarantee that the Wire.read() functions will be called in the right order. You should read into variables first then work with those variables. en.cppreference.com/w/cpp/language/eval_order
– Majenko♦Mar 27 '17 at 20:52

I see, it's a point I'll have to considerate with my own design. Though, actually, I prefer to work with variables instead of functions. Thanks for the advice!
– JulioMar 27 '17 at 21:04

1

In practice it is usually ok, but there is no guarantees. And what works in one version of the compiler may stop in another. Also Arduino playground isn't the most reliable of sources for good quality code.
– Majenko♦Mar 27 '17 at 21:23

2 Answers
2

The expression Wire.read() << 8 takes the value returned by
Wire.read(), which is an int, and shifts it 8 bits to the left,
which is equivalent to multiplying by 256. If you are using a 32-bit
microcontroller (e.g. an Arduino Due), this is safe. However, most
Arduinos are based on an 8-bit AVR chip. On them, an int is 16-bits
and can only hold values up to 32767. If the initial value is larger
than 127, then the bit shift causes a signed integer overflow, which in
C and C++ is undefined behavior (read: “illegal operation”). It is
likely that everything runs fine and you get the expected result, but
it is unwise to ever rely on undefined behavior in C or C++.

The proper way to do the shift is to cast the initial value to an
unsigned data type, which is always safe v.s. overflows, and then do the
shift, like in

((uint16_t) Wire.read()) << 8

You may omit the outer parentheses if you know your operator priorities.

The second point is about the already mentioned fact that the order of
the reads is not specified. The simplest fix is to do one read per
statement, as in:

It is worth noting that the first statement has an implicit cast from
uint16_t (the result of the shift) to int16_t (the type of AcX).
This can also overflow if the shifted value is larger than 32767.
However, an overflow happening during a conversion in not undefined,
but rather implementation defined behavior. This means that the
authors of the compiler must decide and document what happens. Arduino
code is usually compiled by gcc, and the gcc docs document this
behavior as

• The result of, or the signal raised by, converting an integer to a
signed integer type when the value cannot be represented in an object
of that type (C90 6.2.1.2, C99 and C11 6.3.1.3).

For conversion to a type of width N, the value is reduced modulo 2^N
to be within range of the type; no signal is raised.

This is exactly what we want here, and since it is the most efficient
choice on a two’s complement architecture, it seems unlikely that
another compiler would make a different choice.

1 << 3 means the value 1 shifted 3 times to the left. So 1 in binary is 0000001, shifted left 3 places is 00001000. And 0001101 << 3 will be 1101000.

The | command is a logic or (where bits will be 1 if one of the bits is 1, e.g. 001100 | 001001 = 001101.

Probably every Wire.read() gives the next byte.
For the first line: Acx = Wire.read() << 8 | wire.read() means one (mostly the first byte) is read, it is shifted to the left one byte and the other (mostly next byte) read is placed in the right. So it results in the first two read bytes to be positioned in AcX. It is semantically the same as Wire.read() * 256 + Wire.read(), but normally a bit shift is easier for a computer, same as | and the + operator.

I got it, it seems as you said that it composes a word with those two bytes, because item's datasheet indicates that in each pair, one register has the high bits and the other one the low bits. Thank you.
– JulioMar 27 '17 at 21:15

You are welcome, and yes, the high 8 bits go into the first part of the pair, and the next (low) 8 bits go in the second part.
– Michel KeijzersMar 27 '17 at 21:47

3

“For the first line: Acx = Wire.read() << 8 | wire.read() means the first byte is read, it is shifted to the left one byte and the next byte read is placed in the right” is incorrect. It should instead say, “For the first line: Acx = wire.read() << 8 | wire.read() means that two bytes are read, one of them is used as MSB, and the other as LSB”. That is, according to the C standard N1570 §6.5.2, without parenthesization it is undefined which wire.read() is first and which is second. Of course it often is the case they are used in the order you mentioned, but it's undefined here.
– James Waldby - jwpat7Mar 27 '17 at 22:27

@jwpat7 yes you are right ... I will update the answer
– Michel KeijzersMar 27 '17 at 23:33