Using Rotary Encoder to detect stepper motor stall

Hi all,

Project brief (simplified):
I am building a project that uses a stepper motor to drive a wheel clockwise (CW), counter-clockwise (CCW) and then CW again 360 degrees for each rotation. This pattern repeats forever. CW/CCW/CW, pause, CW/CCW/CW, pause......
I have the motor turning and working as I expect.

The challenge:
One iteration at random, the wheel will be stopped (i.e. brake applied) after turning 90 degrees on the second CW spin.
If the brake has not been applied then everything should continue.
The 'brake' is independent of the project and is outside the control of the user.

I need a way to know that it has been stopped. I have been searching the forums and there are lots of suggestions of trying to read the current of the motor or other complex ideas. I thought the easier option would be to connect a Rotary Encoder to the output of the motor so that when the motor turns, the encoder turns too; so that's what I've got.
Speed is a consideration, not having too many steps to take or stops along the way is beneficial.

My head scratching moment is how to detect the Rotary Encoder has been moving and isn't anymore. If the brake has been applied then trying to continue turning will cause damage to the motor/support structure/wheel.

Possible methods I'm thinking of so far:

  • Move 90 degrees and then move a small increment and check the encoder? Use a count variable to count RE pulses and an iteration variable to count how many steps have been taken. Turn motor in small increments (~10 steps at a time) and increment iteration each time. Compare?
  • Measure how many pulses the RE takes for a 90 degree turn of the motor and then if pulses_ count >= pulses_to_turn_90 then it hasn't stalled?
  • Is there a way to count how many pulses have occurred in a set time?

Hardware:
1x 23HE45-4204S Stepper motor
1x DM556 driver
1x PSU
1x Arduino Uno
1x KY-040 Rotary Encoder

Rotary encoder tested and working using slightly modified In-Depth: How Rotary Encoder Works and Interface It with Arduino code (I don't care about the button):

// Rotary Encoder Inputs
#define CLK 2
#define DT 3

int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir = "";


void setup() {

  // Set encoder pins as inputs
  pinMode(CLK, INPUT);
  pinMode(DT, INPUT);

  // Setup Serial Monitor
  Serial.begin(9600);

  // Read the initial state of CLK
  lastStateCLK = digitalRead(CLK);
}

void loop() {

  // Read the current state of CLK
  currentStateCLK = digitalRead(CLK);

  // If last and current state of CLK are different, then pulse occurred
  // React to only 1 state change to avoid double count
  if (currentStateCLK != lastStateCLK  && currentStateCLK == 1) {

    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so decrement
    if (digitalRead(DT) != currentStateCLK) {
      counter --;
      currentDir = "CCW";
    } else {
      // Encoder is rotating CW so increment
      counter ++;
      currentDir = "CW";
    }

    Serial.print("Direction: ");
    Serial.print(currentDir);
    Serial.print(" | Counter: ");
    Serial.println(counter);
  }

  // Remember last CLK state
  lastStateCLK = currentStateCLK;

  // Put in a slight delay to help debounce the reading
  delay(1);
}

Example of my code to spin motor a full spin:

void fullSpinL() {
  //Serial.println("Left");
  digitalWrite(dirPin, HIGH);
  for (int x = 0; x < stepsPerRevolution; x++)
  {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);
  }
  delay(1000); // Wait a second
}

Code to turn a quarter turn:

void quarter() {                //Quarter turn right
  digitalWrite(dirPin, LOW);
  for (int x = 0; x < 100; x++)        //400 step motor so 1/4 = 100
  {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(1000);
  }
  delay(1000); // Wait a second
}

Part of writing this was to 'Rubber Duck" my thoughts but if anyone has any ideas on how to use a rotary encoder to detect when a stepper motor has stopped I would appreciate it.

Hope this is clear but please ask for clarifications!

Thanks

That encoder is for manual operation. Find one that is for position or RPM determination with contact free (not bouncing) operation.

Spend a few minutes considering your "initial conditions". Stepper motors move by steps and 360 degree rotation is done by COUNTING the steps being moved. Will your machine need to know where to begin it's rotation from the same beginning step each time you power it up?
There seems to be no feedback for the brake mechanism, so it's likely will be applied while the stepper is on mid-step. That will cause your program to loose step-count. You will need a way to recover the step count in order to continue 360 degree turns.

Hi Paul,

Thanks for your reply.

I should have added this above - once the brake has been applied, the machine should detect the stop and then cease rotatying and sit idle.

There is no requirement to know where to begin. It is assumed to be at 0 when power is applied.

Thanks,
Mike

Then all you need is to know, software wise, that the stepper motor is turning when it was requested to turn and not turning when it was told to turn. So, your plan for an encoder to indicate RPM or movement is all that is needed.
Think about using a rubber toothed belt and matching pullies to connect the two together. You only need to detect pulsing from the encoder, not actual counts of pulses, but that might be easier to program for.

Instead of that motor, I would suggest a closed-loop stepper. It has an encoder already attached:

https://www.amazon.com/CNCTOPBAOS-60x60x88mm-Closed-Loop-Controller-Engrvaving/dp/B079CCPCPQ/ref=sr_1_3

Also, I would use the RotaryEncoder library:

https://www.arduino.cc/reference/en/libraries/rotaryencoder/

It has some good examples on how to check for encoder movement.

1 Like

So instead of a library a basic retriggerable timer should also work.

Or something similar.

1 Like

Hi Paul,

Thanks, I already have two GT2 driver gears and a belt :wink:

Thanks Benjamin,

That's a really uselful link for next time.

I'm trying to accomplish my goal with the hardware i already have

Thanks! Ill have to have a proper look but looks very promising!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.