Use of 3 stepper motors with accelstepper and emergency stop

Hello, I am working on a project using three stepper motors, and I can control them with the accel stepper library as I need them to move at a certain speed and acceleration. I am using five push buttons to control two of them are connected to two-steppers for moving forward and backward, and the other two bottons are connected to one stepper for moving up and down.
Each stepper is moving at 90 degrees, and I am using a TB6600 driver and running them with Arduino.
My problem is I can not make my emergency pushbutton work; I want to stop the motor when it is moving (after the forward bottom is pressed) and before reaching the position where I set it to that position new position and stop the movement completely. I don't know how to implement this in my code.

note : the code below is a test code with one stepper, which should work with three stepper
I would appreciate any help, this is very urgent I need to have an emergency stop soon
this is my code


#include <AccelStepper.h>


// Define number of steps per revolution:
const int stepsPerRevolution = 200;
const int switchOne    = A5; // the forward pin
const int switchTwo    = A4; // the backward
const int switchThree  = A3; // the actuator up 
const int switchFour   = A2; // the actuator down
const int switchFive   = 2; // stop the motor


int p1buttonState = 0;         // current state of the button
int lastp1buttonState = 0;     // previous state of the button
int p2buttonState = 0;         // current state of the button
int lastp2buttonState = 0;     // previous state of the button

int p3buttonState = 0;         // current state of the button
int lastp3buttonState = 0;     // previous state of the button


unsigned long previousMillis = 1000;        // will store last time LED was updated
long OnTime = 1000;           // milliseconds of on-time
long OffTime = 750;          // milliseconds of off-time

bool bPress = false;
bool isForward = false;
bool isBackward = false;
bool isstop = false;
// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13



// Define the AccelStepper interface type:
#define MotorInterfaceType 2


int currentAngle = 0;

int angle = 0;

float stepPerAngle = 1.8; // full step = 1.8

int   numstep;

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, dirA, dirB);

bool isMoving = false;


void setup() {

  // set the switches 
  Serial.begin(9600);

  pinMode( switchOne, INPUT_PULLUP);

  pinMode( switchTwo, INPUT_PULLUP);

 pinMode( switchThree,INPUT_PULLUP);

  pinMode( switchFour, INPUT_PULLUP);

  pinMode( switchFive, INPUT_PULLUP);

  // Set the PWM and brake pins so that the direction pins can be used to control the motor:
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);

  // Set the maximum steps per second:
  stepper.setMaxSpeed(10);
  // Set the maximum acceleration in steps per second^2:
  stepper.setAcceleration(30);
  p1buttonState = switchOne;

}

void loop() {
//isMoving = false;
unsigned long currentMillis = millis();
 
          stepper.setCurrentPosition(0);
    
        if((digitalRead(switchOne) == LOW )
         {
         // Set target position:
          stepper.setSpeed(5);
          stepper.moveTo(50);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          //stepper.stop();
          stepper.setCurrentPosition(0);
          //previousMillis = currentMillis; 
          isMoving = true;

            if (isMoving == true){
              if (digitalRead(switchFive) == LOW){
                stepper.setCurrentPosition(0);
                stepper.stop();
                stepper.disableOutputs();
              }

            }

          if((digitalRead(switchOne) == LOW ) && (currentMillis - previousMillis >= OnTime) && (isMoving == false )){

          stepper.setSpeed(5);
          stepper.moveTo(100);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          //stepper.stop();
          
          stepper.setCurrentPosition(0);
          }
          //previousMillis = currentMillis;
          
          //stepper.stop();
          //  if (p1buttonState == 1){
          //    buttom_press();
          //    stepper.setCurrentPosition(50);

           }
          
          //}
           
          if ((digitalRead(switchTwo) == LOW))
           {
          stepper.setSpeed(100);
          // Set target position:
          stepper.move(-50);
          // Run to position with set speed and acceleration:
          stepper.runToPosition(); 
          stepper.setCurrentPosition(0);
          //stepper.stop();
          //isMoving = true;
          
          delay (1000);

          stepper.setSpeed(100);
          stepper.moveTo(-100);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          stepper.stop();
          stepper.setCurrentPosition(0);
         }
         
        if ((digitalRead(switchFive) == LOW) && (isMoving == true ) && (stepper.run()==0) && (digitalRead(switchOne) == HIGH ) && (digitalRead(switchTwo) == HIGH) ) {
            
            stepper.setSpeed(0);
            stepper.move(-50);

            stepper.setCurrentPosition(0);
            stepper.stop();
            stepper.disableOutputs();
          }
    stepper.moveTo(0);
     stepper.runToPosition();
 
}

Emergency stop is usually an independent circuit that totally removes power from the steppers.
Like opening a relay in the power supply path. The Arduino is not in that circuit and is irrelevant.

Your use of delay() and blocking code (runToPosition()) make fast response impossible.

3 Likes

The first thing I would do is get rid of the delay()s

After that, look at your structure - at the moment it’s very linear whereas it should be event driven by the time (or the buttons)

so, using millis() timing might solve a lot of your problems

2 Likes

What they said.

Here's a good explanation of what's happening in your code and why it might need to change to do what you want:

1 Like

so some external hardware like a relay module would be useful for me in this situation to cut the power completely.

Okay, I will try it; I want two of the motors to run with one switch, but with some delay like 2 sec or so

Thank you so much

Cut power completely to the steppers and to the spindle if so equipped. In other words, stop all motion of the machine.

I did try to use millis() timing, but my switch five does not stop any motion of the motor or stop the stepper after switch one is pressed. It is like the program doesn't allow any other switch to work.

#include <AccelStepper.h>


// Define number of steps per revolution:
const int stepsPerRevolution = 200;
const int switchOne    = A5; // the forward pin
const int switchTwo    = A4; // the backward
const int switchThree  = A3; // the actuator up 
const int switchFour   = A2; // the actuator down
const int switchFive   = 2; // the actuator down


int p1buttonState = 0;         // current state of the button
int lastp1buttonState = 0;     // previous state of the button
int p2buttonState = 0;         // current state of the button
int lastp2buttonState = 0;     // previous state of the button

int p3buttonState = 0;         // current state of the button
int lastp3buttonState = 0;     // previous state of the button


unsigned long previousMillis = 1000;        // will store last time LED was updated
long OnTime = 1000;           // milliseconds of on-time
long OffTime = 750;          // milliseconds of off-time

bool bPress = false;
bool isForward = false;
bool isBackward = false;
bool isstop = false;
// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13



// Define the AccelStepper interface type:
#define MotorInterfaceType 2


int currentAngle = 0;

int angle = 0;

float stepPerAngle = 1.8; // full step = 1.8

int   numstep;

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, dirA, dirB);

bool isMoving = false;


void setup() {

  // set the switches 
  Serial.begin(9600);

  pinMode( switchOne, INPUT_PULLUP);

  pinMode( switchTwo, INPUT_PULLUP);

 pinMode( switchThree,INPUT_PULLUP);

  pinMode( switchFour, INPUT_PULLUP);

  pinMode( switchFive, INPUT_PULLUP);

  // Set the PWM and brake pins so that the direction pins can be used to control the motor:
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);

  // Set the maximum steps per second:
  stepper.setMaxSpeed(10);
  // Set the maximum acceleration in steps per second^2:
  stepper.setAcceleration(30);
  p1buttonState = switchOne;

}
// void buttom_press(){
//   for (int i =p1buttonState ; p1buttonState<2; i ++){
//     if ((i == 1 )&& (i <=2)) {
//      stepper.setCurrentPosition(0);
//     }
//   }
// }

void loop() {
//isMoving = false;
unsigned long currentMillis = millis();
 
          stepper.setCurrentPosition(0);
    
        if((digitalRead(switchOne) == LOW )
         {
         // Set target position:
          stepper.setSpeed(5);
          stepper.moveTo(50);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          //stepper.stop();
          stepper.setCurrentPosition(0);
          //previousMillis = currentMillis; 
          isMoving = true;

            if (isMoving == true){
              if (digitalRead(switchFive) == LOW){
                stepper.setCurrentPosition(0);
                stepper.stop();
                stepper.disableOutputs();
              }

            }

          if((digitalRead(switchOne) == LOW ) && (currentMillis - previousMillis >= OnTime) && (isMoving == false )){

          stepper.setSpeed(5);
          stepper.moveTo(100);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          //stepper.stop();
          
          stepper.setCurrentPosition(0);
          }
          //previousMillis = currentMillis;
          
          //stepper.stop();
          //  if (p1buttonState == 1){
          //    buttom_press();
          //    stepper.setCurrentPosition(50);

           }
          
          //}
           
          if ((digitalRead(switchTwo) == LOW))
           {
          stepper.setSpeed(100);
          // Set target position:
          stepper.move(-50);
          // Run to position with set speed and acceleration:
          stepper.runToPosition(); 
          stepper.setCurrentPosition(0);
          //stepper.stop();
          //isMoving = true;
          
          delay (1000);

          stepper.setSpeed(100);
          stepper.moveTo(-100);
          // Run to position with set speed and acceleration:
          stepper.runToPosition();
          stepper.stop();
          stepper.setCurrentPosition(0);
         }
         
        if ((digitalRead(switchFive) == LOW) && (isMoving == true ) && (stepper.run()==0) && (digitalRead(switchOne) == HIGH ) && (digitalRead(switchTwo) == HIGH) ) {
            
            stepper.setSpeed(0);
            stepper.move(-50);

            stepper.setCurrentPosition(0);
            stepper.stop();
            stepper.disableOutputs();
          }

    //       stepper.moveTo(0);
    //       stepper.runToPosition();

    //       if ((digitalRead(switchThree) == LOW)) {
    //       // Set target position:
    //       stepper.setSpeed(5);
    //       stepper.moveTo(50);
    //       // Run to position with set speed and acceleration:
    //       stepper.runToPosition();
    //       stepper.stop();
    //       stepper.setCurrentPosition(0);
          
    //       delay(2000);

    //       stepper.setSpeed(5);
    //       stepper.moveTo(100);
    //       // Run to position with set speed and acceleration:
    //       stepper.runToPosition();
    //       stepper.stop();
    //       stepper.setCurrentPosition(0);
    //       }
          
    //           //stepper.moveTo(0);
              
    //           //stepper.setCurrentPosition(0);
    //           //stepper.runToPosition();

    //      if((digitalRead(switchFour) == LOW))
    //      {
    //      // Set target position:
    //       stepper.setSpeed(5);
    //       stepper.moveTo(50);
    //       // Run to position with set speed and acceleration:
    //       stepper.runToPosition();
    //       stepper.stop();
    //       stepper.setCurrentPosition(0);
          
    //       delay(1000);

    //       stepper.setSpeed(5);
    //       stepper.moveTo(100);
    //       // Run to position with set speed and acceleration:
    //       stepper.runToPosition();
    //       stepper.stop();
    //       stepper.setCurrentPosition(0);
          
    //       }

       
     stepper.moveTo(0);
     stepper.runToPosition();
 
}

You are still using the runToPosition() function which is blocking. Nothing else can happen while those functions are executing. Use the non-blocking run() or runSpeed() functions.

The MobaTools stepper library may be of interest. I think that it is easier to learn and use for many applications. There is pretty good documentation for the library as well. And several examples.

1 Like

Thank you so much for your help it is working now i added
attachInterrupt(digitalPinToInterrupt(switchFive), stopMotor, FALLING);
and removed the stepper.runToPosition();

1 Like

Your structure - at the moment it’s very https://epiccarry.com/destiny-2/ whereas it should be event driven by the time (or the buttons)

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