This is a reading routine similar to the "old" mouse "ball", and also used on machines that were common in "arcades", usually racing cars, where a round bulkhead with small cuts or holes was put in front of 2 optical sensors for the steering wheel reading. It could very well be used on a treadmill, with black and white squares providing optical reading, or mechanical contacts.
The sensors are positioned in a "quadrature" configuration, where their sequence determines precisely whether the movement is time or counterclockwise, according to the sequence of "zeros and ones."
Mathematically, it is important to understand the <<
and >>
operators, which have already been discussed in other issues.
What are the operators for | & < < > >?
How does bit-shift work in C / C ++?
By taking the explanations of the above questions using binary representation , let's look at the first line of the question:
int encoded = (MSB << 1) | LSB;
Assuming that MSB is
01
, the
<<
operator effectively shifts the value to the left, and the result is
10
Once this is done, the |
( or binary) operator "merges" the LSB with the MSB. Assuming that the LSB is 1
, the final result will be 11
Similarly, in the following line:
int sum = (lastEncoded << 2) | encoded;
We are taking the 11
previous, and moving two houses to the left, that is, turning the value into 1100
.
Finally, we get the data from the previous reading (obtained in the same way as steps 1 and 2) and merge with the value of the current reading. Assuming the current reading is 01
and the previous 10
, we have the final value 0110
.
With this, just consult the quadrature table to know if the value should be incremented or decremented.
About the "mechanics" of reading
The secret of the reading lies in the arrangement of the sensors, arranged so that the hole and the closed parts, or electrical contacts occupy exactly the distance of the two sensors, so that the following happens:
- 1 and 2 are the sensors
- AA is the screen (the light does not pass and the sensor indicates 0)
- BB is aperture (light passes and sensor indicates 1)
Starting from a hypothetical starting position:
AABBAABBAABBAABB
12 Leitura: 00
Let's assume that I turn the wheel slightly to the right:
ABBAABBAABBAABBA
12 Leitura 01
Turning slightly to the right:
BBAABBAABBAABBAA
12 Leitura 11
And a little more:
BAABBAABBAABBAAB
12 Leitura 10
Next turn, we return to 00
.
In this case, any pair of the sequence 00
01
11
10
indicates a step to the right.
Assuming otherwise, the sequence would be 00
10
11
01
, and any combination of these pairs indicates a step to the left.
Going further:
-
If I am in the 00
position, I know that the next step can only be 01
(right), or 10
(left);
-
If I am in the 01
position, I know that the next step can only be 11
(right), or 00
(left);
-
If I am in the 11
position, I know that the next step can only be 10
(right), or 01
(left);
-
Finally, if I'm in the 10
position, I know that the next step can only be 00
(right), or 11
(left);
What the author of the above code did is take these rules and simplify them in a "table", to know when to increment or when to decrease the variable.
Of curiosity, you can notice that, depending on the explanations given, there is no variation in the original code table from 00 to 11, nor from 10 to 01 or vice versa, by the mechanical arrangement of the sensor, an equal pair is always replaced by a pair in a different state, and a different pair is always replaced by an equal pair if there is movement.