Controlling stepper motor with serial monitor - motor stops during each read

Hi there!

I’m using a Wantai Stepper motor (serial: 57BYGH420) and a microstep driver to control the speed and direction of a wire cutter which is supported by two timing belts.

I have written a programme which uses the serial monitor to read either ‘d’ or ‘s’ for direction or speed respectively. If directional control is selected, it then reads ‘f’, ‘r’, or ‘s’ for forward, reverse and stop. If speed control is selected, an integer between 0 and 10 is input to give the number of steps per minute.

My problem is that whenever I input either ‘d’ or ‘s’, the motor stops until a speed or direction has been set. I would like the motor to continue while inputting commands to the serial monitor so that the speed or direction can be adjusted while the motor is still turning.

I believe I am just messing up with using ‘while’ or ‘if’ conditions for Serial.available() but I haven’t been able to find the right combination for the desired effect.

I know there are much simpler ways to input single commands to control both speed and direction at the same time, but I aim to create a GUI at a later stage which will control this system, so I am trying to keep everything separate at the moment so it is easier to implement.

Appreciate any help with this! Thanks!

#include <AccelStepper.h>

AccelStepper stepper(AccelStepper::DRIVER, 8, 9); //Pulse 9; direction 8

int spd = 1000;    // The current speed in steps/second
int sign = 1;      // Either 1, 0 or -1
int vector;       // Describes both speed and direction of motor

// ######################################################################################################

void setup()
{  
  Serial.begin(9600);
  Serial.println("---Control of Speed and Direction---");
  stepper.setMaxSpeed(1000); 
  Serial.println("\n\n########## PLEASE ENTER DIRECTION ('d') OR SPEED ('s') ##########");
}

// ####################################################################################################
void loop()
  {  
  char n;   //Nsture determines whether the command is a speed or direction change
  
  if(Serial.available())
  {
    
    n = Serial.read();

//-------------------------DIRECTIONAL CONTROL-----------------------------------------------------------
    if (n == 'd'){
    Serial.println("\nDirectional Control: Please enter FORWARD ('f'), REVERSE ('r'), or STOP ('s'): ");
      while (Serial.available()==0);
      { 
  
        char d = Serial.read();
        
        if (d == 'f') {  // forward
          sign = 1;
          Serial.println("Direction: FORWARD");
        }
        else if (d == 'r') {  // reverse
          sign = -1;
          Serial.println("Direction: REVERSE");
        }
        else if (d == 's') {  // stop
          sign = 0;
          Serial.println("Motor STOPPED");
        }
        else {
          Serial.println("Invalid command. Please start again");
        }
      }
    } 

//-------------------------SPEED CONTROL----------------------------------------------------------------
    else if (n == 's'){
      Serial.println("\nSpeed Control: Please enter a number between 0 and 10: ");
      while (Serial.available() == 0);
      {
        int s = Serial.parseInt();
        
        if (0 <= s <= 10){
          spd = s*100;
          Serial.print("Motor Speed: ");
          Serial.println(spd);
        }
  
        else {
          Serial.println("Invalid speed. Please start again");
        }
      }
    }
//--------------------------INVALID INITIAL ENTRY----------------------------------------------------------
    else {
      Serial.println("\nInvalid Entry: Please start again");
    }

//--------------------------DEFINING AND PRINTING MOTOR VECTOR----------------------------------------------

    vector = spd*sign;
    stepper.setSpeed(vector);
    Serial.print("\nMotor vector: ");
    Serial.println(vector);
    Serial.println("\n\n########## PLEASE ENTER DIRECTION ('d') OR SPEED ('s') ##########");
  }
  stepper.runSpeed();
}

Rather than send data in a 2-step process send a single message - for example ‘F’ ‘R’ or ‘S’

OR, if the ‘d’ character is needed for some other purpose send dF dR or dS, Better still would be to send etc. See Serial Input Basics

Do NOT use a blocking WHILE when using the accelstepper library.

…R

You might try:

if(Serial.available())
{
  n = Serial.read();
  if(n == 's')
    spd = Serial.parseInt();

Then you could enter "s200" [ENTER] in serial monitor. Use h (halt) for stop.

edgemoron:

 spd = Serial.parseInt();

Serial.parseInt() is a blocking function and should not be used in this application.

…R

      while (Serial.available()==0);
      {
 
        char d = Serial.read();

Why is there a useless curly brace after the while statement?

Hey,

Thanks for your help! I took out the blocking while statements and replaced them with a single input that reads both speed and direction, as in your serial input examples: eg.

Cheers!

Is it possible to use this code also with the A4988 module? Only 2 output pins are enough?

boromyr:
Is it possible to use this code also with the A4988 module? Only 2 output pins are enough?

If you are talking about the code in the Original Post then it is intended for an A4988 type of driver.

I strongly suspect you should start your own Thread and provide a description of what you are trying to create as this Thread seems to have been stopped in mid air before you came along.

...R