Voice controlled stepper motor


> Blockquote

#define stepPin 4
#define dirPin 2
byte com = 0;
bool stopped = false; // Flag to indicate if the motor is stopped

void setup() {
  // Sets the two pins as Outputs
  Serial.begin(9600);
  Serial.write(0xAA);
  Serial.write(0x37);
  delay(1000);
  Serial.write(0xAA);
  Serial.write(0x21);
  pinMode(stepPin, OUTPUT);

}

void loop() {
  while (Serial.available()) {
    com = Serial.read();
  }

  if (com == 0x12 && !stopped)  // Right 
  {
    digitalWrite(dirPin, LOW);  
    for (int x = 0; x < 1600; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(700);  
      digitalWrite(stepPin, LOW);
      delayMicroseconds(700);
    }
    delay(100);
    com = 0x00;
  }
  else if (com == 0x11 && !stopped)  // Left
  {
    digitalWrite(dirPin, HIGH);  
    for (int x = 0; x < 1600; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(700);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(700);
    }
    delay(100);
    com = 0x00;
  }

  if (com == 0x13) { 
    stopped = true; // stop motor
    digitalWrite(dirPin, LOW);  
    for (int x = 0; x < 400; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(500);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(500);
    }
    delay(100);
    com = 0x00;
  }
   if (com == 0x14) {
    stopped = false; // resume operation
    digitalWrite(dirPin, LOW);  
    for (int x = 0; x < 0; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(500);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(500);
    }
    delay(100);
    com = 0x00;
  }
}

So i am running a code for a voice controlled stepper motor. i figured it up to this point but i need the motor to stop immediately when it is called currently it only stops when nothing else is happening

Can You show flow charts telling how You are thinking?

You have all of those delays in the code that the processor spends most of the time doing nothing.

The for loops (and while loops) block execution. Nothing can happen while they are executing except the code that is in the loop.

Your use of blocking code with delays and for loops mean the code can never be responsive.

The idea with embedded processor code is to let loop loop as quickly as possible doing small steps each loop. See the several things at a time tutorial linked below.

Libraries like AccelStepper and MobaTools have non-blocking movement functions. I prefer the MobaTools stepper library. Install the library using the IDE library manager. The MobaTools documentation.

Robin2's simple stepper code tutorial has example code for using millis() and micros() to write non-blocking code to control a stepper.

Here are some good tutorials on writing non-blocking code.
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

Hi @octopaws ,
Welcome to the forum..
hmm.. a bit difficult in understanding your stop and resume..
but as others pointed out those for loops have to be unrolled..
give this a spin..


#define stepPin 4
#define dirPin 2
byte com = 0;
byte lastcom = 0;
bool stopped = true; // Flag to indicate if the motor is stopped
byte direction = 0;
int numSteps = 0;
bool reached = true;


void setup() {
  // Sets the two pins as Outputs
  Serial.begin(9600);
  Serial.write(0xAA);
  Serial.write(0x37);
  delay(1000);
  Serial.write(0xAA);
  Serial.write(0x21);
  pinMode(stepPin, OUTPUT);

}

void loop() {
  while (Serial.available()) {
    byte abyte = Serial.read();
    //respond to valid commands only..
    if (abyte >= 0x11 && abyte <= 0x14) {
      com = abyte;
    }
  }

  if (com != lastcom) {
    lastcom = com;
    switch (com) {
      case 0x12: //right 1
        digitalWrite(dirPin, LOW);
        direction = 0;
        stopped = false;
        reached = false;
        //    Serial.println("roght");
        break;
      case 0x11: //left 2
        digitalWrite(dirPin, HIGH);
        direction = 1;
        stopped = false;
        reached = false;
        //    Serial.println("left");
        break;
      case 0x13: //stop 3
        stopped = true;
        //    Serial.println("stop");
        break;
      case 0x14: //resume 4
        stopped = false;
        //     Serial.println("resume");
        break;
    }
  }

  if (!stopped && !reached)  // Right
  {
    if (direction == 0) {
      numSteps++;
      if (numSteps > 1599) {
        numSteps = 1599;
        reached = true;
      }
    } else {
      numSteps--;
      if (numSteps < 1) {
        numSteps = 0;
        reached = true;
      }
    }
    if (!reached) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(700);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(700);
    }
  }

}

good luck.. ~q

\
#include <AccelStepper.h>

// Define pins for the stepper motor
#define stepPin 4
#define dirPin 2

// Variable to store received serial command
byte com = 0;

// Create a stepper motor object and assign pins
AccelStepper stepper(1, stepPin, dirPin); // 1 signifies a driver with 2 pins (STEP, DIR)

// Define positions for movement
int rightPosition = 500;
int leftPosition = -500;

// Variable to track the current motion direction
String motionDirection = "right";

void setup() {
// Initialize serial communication at a baud rate of 9600
Serial.begin(9600);

// Initialize stepper motor settings
stepper.setMaxSpeed(1000);     // Set the maximum speed for the stepper motor
stepper.setAcceleration(500);  // Set the acceleration for the stepper motor
stepper.setCurrentPosition(0); // Set the initial position to 0 steps

// Send initialization commands over serial communication
Serial.write(0xAA);
Serial.write(0x37);
delay(1000);  // Wait for a moment
Serial.write(0xAA);
Serial.write(0x21);

}

void loop() {
// Receive and process serial commands
String moveToDirection = getCommand();

// Check if a valid command is received
if (moveToDirection != "") {
    // Determine the motion based on current direction and command
    if (motionDirection == "left" && moveToDirection == "continue") {
        stepper.moveTo(leftPosition);
    } else if (motionDirection == "right" && moveToDirection == "continue") {
        stepper.moveTo(rightPosition);
    } else if (moveToDirection == "left") {
        stepper.moveTo(leftPosition);
    } else if (moveToDirection == "right") {
        stepper.moveTo(rightPosition);
    }
}

// Reset the command variable
moveToDirection = "";

// Perform stepper motor movement while there are steps remaining
while (stepper.distanceToGo() != 0) {
    stepper.run();
    
    // Check for new commands during movement
    if (moveToDirection != "") {
        if (motionDirection == "right" && moveToDirection == "left") {
            // Stop the motor, update the current position, and change direction
            int currentPosition = stepper.currentPosition();
            stepper.stop();
            stepper.setCurrentPosition(currentPosition);
            stepper.moveTo(leftPosition);
            motionDirection = "left";
        } else if (motionDirection == "left" && moveToDirection == "right") {
            // Stop the motor, update the current position, and change direction
            int currentPosition = stepper.currentPosition();
            stepper.stop();
            stepper.setCurrentPosition(currentPosition);
            stepper.moveTo(rightPosition);
            motionDirection = "right";
        } else if (moveToDirection == "stop") {
            // Stop the motor
            stepper.stop();
        }
    }
    
    // Check for new commands while the motor is running
    moveToDirection = getCommand();
}

}

// Function to receive and interpret serial commands
String getCommand() {
while (Serial.available()) {
com = Serial.read();
}
if (com == 0x11) {
return "right";
} else if (com == 0x12) {
return "left";
} else if (com == 0x13) {
return "continue";
} else if (com == 0x14) {
return "stop";
} else {
return "";
}
}
\\

Actually edited to this point and it seems to work fine. Thanks .