Encoder algorithm

I’m writing some code to read a mouse encoder (ask if you want to know about hardware hack).

The code uses 2 interrupts/channels.

To decode the pulse train i use this code:

void interrupta()
{
counter = counter+((digitalRead(pinCha)^digitalRead(pinChb))^1)-(digitalRead(pinCha)^digitalRead(pinChb));
}

void interruptb()
{
counter = counter-((digitalRead(pinCha)^digitalRead(pinChb))^1)+(digitalRead(pinCha)^digitalRead(pinChb));
}

instead of use “if” statements i use xor gates

Do you think this code is faster than a “if” version?

“if” version:
.arduino.cc/playground/Main/RotaryEncoders (2 interrupts version)

Thanks

The if test is an order of magnitude faster than an digitalRead. You are looking in the wrong place for optimizing your code. Perhaps a peak a direct port manipulation would be useful: http://www.arduino.cc/en/Reference/PortManipulation

Do you think this code is faster than a “if” version?

Given the overhead of “digitalRead”, I don’t think it matters.

(BTW, that’s an XOR operation, not a “gate”)

arduino.cc version.

void doEncoderA(){

// look for a low-to-high on channel A if (digitalRead(encoder0PinA) == HIGH) {

// check channel B to see which way encoder is turning if (digitalRead(encoder0PinB) == LOW) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } }

else // must be a high-to-low edge on channel A { // check channel B to see which way encoder is turning if (digitalRead(encoder0PinB) == HIGH) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } } Serial.println (encoder0Pos, DEC); // use for debugging - remember to comment out

}

new version:

void interrupta() {counter = counter+((digitalRead(pinCha)^digitalRead(pinChb))^1)-(digitalRead(pinCha)^digitalRead(pinChb)); }

Yes, this new version always make 4 digitalRead VS 2 or 3 digitalRread in the classic version

Where is the best place to post this question?

Thanks for your fast reply.

Not sure two different "digitalRead"s for each pin is legitimate - best to use variables.

Please use the # button when posting code.

Something like:

void interrupta()
{
a = digitalRead(pinCha);
b = digitalRead(pinChb);
counter = counter+((a^b)^1)-(a^b);
}

Let's exaggerate the times. Suppose it takes 1 minute to do a digitalRead, and 1 second to perform an if test.

Does it make sense to optimize the if tests or the digitalRead?

If you eliminate 2 if's by adding 2 digitalReads, your code is going to take twice as long to execute.

OK. Then the previous code:

  • has the same digitalReads than the original code (2)
  • has no if sentences

now i think is good enough.

direct port io manipulation…? that will be the next step but i have not idea about assembler.

thanks

direct port io manipulation...? that will be the next step but i have not idea about assembler.

No need for assembler code to do direct port commands, see:

http://www.arduino.cc/en/Reference/PortManipulation

I played with a couple of optical encoders a year ago or so and converting to direct port I/O Vs digitalRead commands was the single best improvement in step reponse speed.

Lefty