Stop a stepper during a "moveTo" command.

I have a 28BYJ48 stepper driving an auger. I also have a “beam break” sensor. I drive the auger one full rotation, check to see if the beam has been broken, if not, drive another rotation etc., until I get a beam break event. The problem is, there may be over rotation and I get 2 beam break events. Is there a way to stop the stepper while it’s in the moveTo command, and the distanceToGo has not reached 0?

I’m using Arduino UNO with 28BYJ48 stepper and Accelstepper library.

Use stop(). :slight_smile:

If you are using the run() or runSpeed() functions to make the stepper motor move then it will stop instantly if you stop calling that function.

However if you are using run() and acceleration it would be better to use the stop() function which will decelerate the motor to a stop as quickly as possible based on the acceleration value you have given it.

...R

Is there a way to stop the stepper while it's in the moveTo command, and the distanceToGo has not reached 0?

you can use command ' stop() ', but the stepper will stop only when reached 0.

if you want to stop immediately, maybe you can use additional component to stop the rotation ( manual mode ) , such as pushbutton, switch, etc, i think :).

but it's better if you share the code to us.

cheers, nielyay

#include <AccelStepper.h>

#define SensorPin 4
#define motorPin1  9     // Blue   - 28BYJ48 pin 1
#define motorPin2  10     // Green - 28BYJ48 pin 2
#define motorPin3  11    // Purple - 28BYJ48 pin 3
#define motorPin4  12    // Yellow - 28BYJ48 pin 4

#define HALFSTEP 8
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

long lastDisplayUpdateTime = 0;  
long updateDelay = 3000;  

int sensorState = 0;
int lastState;

void setup()
{ 
  pinMode (SensorPin, INPUT);
  digitalWrite(SensorPin, HIGH);
  stepper1.setCurrentPosition(0);
  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(500.0);
}
bool isRunning = false;

void loop()
{   
 
  if ((millis() - lastDisplayUpdateTime) > updateDelay) {    
    stepper1.runToNewPosition(3000);
    sensorState = digitalRead(SensorPin);
    lastDisplayUpdateTime = millis();
    stepper1.setCurrentPosition(0);
  }
  if (sensorState == LOW && lastState == HIGH) { // it's been broken, stop the motor
    stepper1.stop();
    isRunning = false;
  }    
}

I revised this a little for this post, I made it run 3000 steps , every 3 seconds.
I need to be able to stop it in the midst of the running 3000 steps. That’s where I’m stumped.
The stepper1.stop(); command does not work. It seems that the motor is in that “run” loop until it completes the distance (3000 steps), ie: the sensor is not being queried during that time.

This is for a ball clock that I’m building. I need the auger to turn until a ball is delivered, then stop.

Just a moment...

if (sensorState == LOW && lastState == HIGH) {
  if ((millis() - lastDisplayUpdateTime) > updateDelay) {    
    stepper1.runToNewPosition(500);
    sensorState = digitalRead(SensorPin);
    //lastDisplayUpdateTime = millis();
    stepper1.setCurrentPosition(0);
  }
 }

This works. Take small steps (500), check the sensor, take more steps. But, now any "smoothness" is gone from the auger, it turns (500 steps), stops, turns, stops, ad infinitum.

Any help with that maybe, or a completely different approach?

I've increased the Acceleration to 100,000 and decreased the steps to 50. With the above change in code and this, I at least have a workable system. Probably REAL crude, but workable. I would like to see a more elegant code that would be more efficient. Thanks for the advice everyone.

I think the solution was given in reply #2. The problem is, you're not using run().