I have recently followed the instructions in the answer to this question: Reading several rotary encoders posted by maximilian-gerhardt

I've wired everything up, and am using the interrupts example that can be found here: https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/tree/master/examples/Interrupt

Everything seems to work as expected, except that my assumption was that since this was an interrupt-based solution, that I wouldn't be missing any steps of any of the encoders. There are a total of 5 that will move at the same time, and it is clear that while it almost works, there are many steps that are missed.

I'm guessing that is because while one interrupt is being handled, all other interrupts are disabled?

Is there any way where I can ensure that every single motion (step CW or CCW) is registered on all 5 encoders?

Thanks! Brian

  • Interrupts are no garant for missing no steps. The steps need to happen only as fast, as the interrupts need to execute. The reading of the MCP over I2C alone would take 100us min (assuming 1 byte of data. With 2 bytes you would have 150us min). And then the executing time of the logic how fast are your steps coming in?
    – chrisl
    Apr 24, 2021 at 10:24

2 Answers 2


I would use a different approach. Consider setting a flag when an interrupt occurs, a different flag for each interrupt then processing that in the main loop rather then the ISR (Interrupt Service Routine). Connecting with the SPI in the 1.7 MHz mode will allow you to get in check the interrupt set the flag and leave the ISR. This will be a bit difficult to write but I think it would work very well. Taking a quick scan of the data sheet the MCP23917 should be the correct part to accomplish this. Also do the debouncing externally, will save a lot of code and speed up the process.


Interrupts don't mean that you can do lots of things at the same time. All they mean is that something can be responded to rapidly, as long as nothing else is being responded to of an equal or higher priority.

And coupling that with an IO expander which will inevitably slow things down means that you really can't do what you are trying to do.

If you want to respond instantly to every single pulse of every single encoder then each encoder has to be attached to something that can itself respond to those pulses.

I would be inclined to have a small microcontroller attached to each individual encoder (or maybe two encoders if you have enough interrupt pins) and deal with each separately - that way one encoder cannot interfere with any other. The small MCU can then keep track of position or count (depending on what it is you are trying to do) and you communicate that to a "master" controller (the Arduino for example) over some other bus, asynchronously to the encoder's pulses.

If you want more rapid response to the encoder movements then it could be possible to implement your own interrupt signal from the small MCU to the Arduino to say "My encoder has been moved", at which point the Arduino can collect the data. It won't matter how long that takes to happen as the small MCU will be keeping track of any other changes. The ATTiny85 using Pin Change Interrupts could be a good low-cost choice for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.