After fumbling around the edges for a while, I finally got a decent acceleration/deceleration plot of paper feed motor in a Canon Pixma MX340 multi-function inkjet. It was very informative not only in a "satisfy curiosity" way, but also in a "oh, my plan isn't going to work" way as well. Better I discover the flaw now rather than later!

The challenge is to recognize when one motion has ended and another has begun. My first effort was to sample encoder position as fast as possible and, when there's zero delta between two samples, declare that a point of delineation. This idea failed spectacularly. So I thought I could base my decision on acceleration: when the motor starts accelerating after a period of deceleration, declare that a point of delineation. But now that I've looked at the actual plot, I know that won't work either. Several changes in acceleration rates occur within a single motion during normal operation, so that is not a reliable indicator to use.

I could withhold decision until acceleration exceeds a certain threshold, but that means I have to track a longer history. Back to when the candidate delineation point existed, so I could output that data when the decision is made. I'd like to avoid adding such runtime data management complexity. On top of that, it would add a threshold setting problem into the mix.

If a threshold setting problem is inevitable, I might as well try it in the context of something simpler with less data to manage: dwell time. Defined as: how much time the system spends sitting at a particular encoder position. This is similar to the earlier "zero delta between two samples" approach, but now based on microsecond timestamp rather than an unpredictable "time elapsed between polls by loop()." Looking over the data I captured of system startup, I see "not quite there yet, need a little kick" dwell times of a little over 9000 microseconds. Given that, I'll start with a dwell time of 10000 microseconds (10 milliseconds).

I think it's better to have this threshold a little too low versus too high. When it is too low, it would falsely break up a single motion. For example, "Moved 1798" then "moved 2" instead of desired "moved 1800". This will add noise to the motion decode output, but I think it is the lesser evil. Setting it too high would falsely combine multiple motions into one: "Moved 900" instead of "Moved 2700" and "Moved -1800" and such mistakes would be more difficult for me to recognize when looking at motion decode output.


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.