What happens on these lines in C++?

Asked

Viewed 125 times

4

This is an Encoder reading routine that detects which direction of Encoder rotation. The references are left and right pins appreciated as MSB and LSB bits. The Code works perfectly, but I do not understand what exactly happens in the excerpt:

int encoded = (MSB << 1) | LSB;

int sum = (lastEncoded << 2) | encoded;

Would anyone like to explain to me what happens and how these operators of the above lines work? Follows the full function...

void updateEncoder() {
t = micros();
MSB = digitalRead(encoderPin1); //MSB = most significant bit
LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
t = micros() - t;
}

Grateful.

1 answer

4

This is a reading routine similar to the "old mouse" "ball", and also used on machines that were common in "arcade", usually racing cars, where a round bulkhead with small cuts or holes was placed in front of 2 optical sensors for steering wheel reading. It could very well be used on a mat, with white and black squares providing optical reading, or mechanical contacts.

The sensors are positioned in a "quadrature" configuration, where their sequence accurately determines whether the movement is clockwise or clockwise, according to the sequence of "zeros and ones".

Mathematically, it is important to understand operators << and >>, which have already been discussed on other issues.

What are the operators for | & << >>?

How the bit offset in C/C works++?


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;
  1. Assuming that MSB is 01, the operator << effectively shifts the value to the left, and the result is 10

  2. Once done, the operator | (or binary) "merges" the LSB with the MSB. Assuming that the LSB is 1, the final result will be 11

  3. Similarly, in the next line:

    int sum = (lastEncoded << 2) | encoded;
    

    we’re taking the 11 previous, and moving two houses to the left, ie transforming the value into 1100.

  4. Finally, we took the data from the previous reading (obtained in the same way as steps 1 and 2) and merged 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 decreased.


About the "mechanics" of reading

The secret of the reading is 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 bulkhead (light does not pass and sensor indicates 0)
  • BB is opening (light passes and sensor indicates 1)

Starting from a hypothetical initial position:

AABBAABBAABBAABB 
12                    Leitura: 00

Let’s say I turn the wheel slightly to the right:

ABBAABBAABBAABBA
12                    Leitura  01

Turning a little more to the right:

BBAABBAABBAABBAA
12                    Leitura  11

And a little more:

BAABBAABBAABBAAB
12                    Leitura  10

Next time, we’re back 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’m in position 00, I know the next step can only be 01 (right), or 10 (left);

  • if I’m in position 01, I know the next step can only be 11 (right), or 00 (left);

  • if I’m in position 11, I know the next step can only be 10 (right), or 01 (left);

  • finally, if I’m in position 10, I know the next step can only be 00 (right), or 11 (left);

What the author of the above code did was to take these rules and simplify a "tabelinha", to know when to increment or when to decrement the variable.


Of curiosity, you can notice that, according to the explanations given, there is no variation in the table of the original code from 00 to 11, nor from 10 to 01 or vice versa, because obligatorily, by the mechanical arrangement of the sensor, a pair in an equal state 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.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.