I want to understand how the paper feed mechanism works in a Canon Pixma MX340 multi-function inkjet, starting with positions reported by its rotational quadrature encoder. Round 1 looked at raw position data polled every 10ms. This approach quickly ran into limitations, but it informed what I want to accomplish for round 2.

Seeing several moves of 1800 encoder count increments hinted this system acts as a position-based system ("Go to position X") like a servo motor. This doesn't necessarily exclude the possibility of occasionally acting as a velocity based system ("turn at this speed") but I can start by focusing on the positioning aspect.

All of my observations show an acceleration to a target speed, and kept spinning at that speed until it was time to decelerate to stop at a target position. If there are any velocity-based operating modes, I haven't seen any sign the velocity changes in response to any system behavior. I observed several different target speeds for different moves, but the speed seems to stay constant within a single move.

Given these observations, my goal for round 2 is to process encoder position to generate a list of timestamped relative positioning. A secondary goal is to also include peak velocity. I can calculate average velocity from timestamp and position. I expect average will be somewhat lower than peak due to the accelerate/decelerate stages. If there is significant deviation, I know either something went wrong in my code, or the rotational velocity varied during the move.

Here's an example to illustrate my goal:

An excerpt from the power-up sequence, this was the first three movements. It was preceded by a long series of zeros before anything moved. Then there was a move of ~1800 counts over ~140 milliseconds. Then a short period of no motion. Then another move of ~2700 counts over ~240 milliseconds, immediately followed by a reversal of -1800 counts over 140 milliseconds before another period of stillness.

Round 1 gave me a long list of positions every 10 milliseconds. I want round 2 to give me something like:

millis,change,v-max-10ms
5151,0,0
140,1798,237
230,0,0
240,2700,148
140,-1800,-239
100,0,0

These numbers were not precisely calculated, merely to show the desired format. I want a much more concise description of motion than the position-every-10ms raw dump of round 1. This means putting more data processing logic in the Arduino. I tried the easy thing first and it did not go well, but I learned a lot from the failure.


This teardown ran far longer than I originally thought it would. Click here to rewind back to where this adventure started.

Captured CSV and Excel worksheets are included in the companion GitHub repository.