Encoder and stepper operation


stepper notes.pdf (282.7 KB)
The attached document contains some observations following a look at the stepper/encoder operations with a logic analyser. @roryaronson suggested I post this publicly for interest/archive/feedback. This was based on version 3.1.5 which will soon be updated. I’ve had a quick look at the good work @Tim has been doing on the Arduino software and I would expect the next release to be significantly better than the current operation :slight_smile:


Nice work with the analyzer!

The new version has a scan cycle of 64µs. Lots of stuff has been moved around to make room. It should cover most cases, although the 120µs pulses are a bit tight and the 50µs puls detection will be unreliably detected. From the tests I have done with the new version, it’s a lot better.

It was expected that there would be some vibrations/shuddering at start and stop. Stall detection allows for this. We added the more smooth start/stop because usually inertia messes up positioning a lot in moving systems.

It’s tricky to write something to see difference between start/stop movement, axis not moving perfectly, stalling and reaching home. Detecting that could be a nice application of a trained neural network instead of the math approach but that’s beyond me.


I am hoping you can help me with my understanding of encoders and motor ‘step’ detection. I thought I had a basic understanding, but when I looked at the waveforms in the stepper_notes provided by @Loveny I realized I did not.
How is a single step detected? From what I understand, we look at signals A and B (or following notation from the notes, X-encA and X-encB). When X-encB is high, and X-encA toggles it means a step was detected. However, I see that occurrence multiple times within each ‘step’.

I imagine I am missing something fundamental and I would appreciate your help.
As a reference, I looked through the GitHub repository, specifically StepperControlEncoder.cpp lines 155 - 165:

// Detect edges on the A channel when the B channel is high
if (curValChannelB == true && prvValChannelA == false && curValChannelA == true)
if (curValChannelB == true && prvValChannelA == true && curValChannelA == false)

I have implemented this code, and it increments the position multiple times during one ‘step’.

Again, I appreciate your help and clarification.


Are you wondering about the difference in resolution between the motor and encoder, the difference between encoder pulses and counts, or something else?

FarmBot motors have a resolution of 200 steps per revolution, with 360 pulse per revolution encoders. For each revolution of the encoder, 1440 edges can be read (counts per revolution).


I am trying to count/detect motor steps using the encoder (I have Farmbot motors with encoders).
I am programming in Python, and have both the motor and encoder connected to GPIO pins on a Raspberry Pi. What I am trying to accomplish is rotate the motor, and use the encoder to verify the number of steps the motor has rotated.
Does that make sense?


The motor has 200 steps a revolution, whereas the encoder has 360 ‘steps’ (using the above code). So you’d expect to get (360/200) = 1.8 encoder steps for each motor step. So 4 out of 5 motor steps you’ll get 2 encoder steps for each motor step, if that makes sense.


Yes, that makes sense. There is not way to detect 1.8 steps in software, so I would assume that every for 5 (or 10) motor steps, there would be a check to verify 9 (or 18) steps on the encoder.

I think what is confusing me is your data when starting the motor and slowing down. There are several encoder steps that occur during a single motor step. Is this issue solved? Or is the Farmbot software accurately tracking position using the encoders? If so, maybe you could help me locate the correct methods in the Github Repo that shows the process of commanding steps to the motor and reading back the encoder values to verify position tracking?

Thank you very much for your help.


If you’d like to learn more about how the FarmBot firmware works with encoders, reading the descriptions for some of the encoder settings in the documentation may be helpful, especially the encoder scale factor setting. The firmware applies the scale factor to the encoder readings to determine the current position for position reporting (and during movement calculations if use encoders for positioning is enabled).


A post was split to a new topic: Will leaving the stepper motors always powered damage then?