Loop freeze after a single serial "packet" received?

So I will try to keep things short, but I guess we shall see :slight_smile:

I'm working on a project that controls 4 steppers. These 4 steppers get sent speed over serial in a packet. The packet for each speed is steps per second with positive being forward and negative being backward. A packet looks like so: <FLSpeed, FRSpeed, BLSpeed, BRSpeed> ie. <200, -150, 300, 100>. This should decode as follows:

FLSpeed: 200
FRSpeed: -150
BLSpeed: 300
BRSpeed: 100

After receiving the serial and parsing it into its respective variables, these speeds are then sent to their respective steppers using the AccelStepper Library method called .setSpeed(speed). Then after the steppers are run at the speed using .runSpeed() from AccellStepper. Then it SHOULD repeat this whole process.

I think it is very important for others to know what I EXPECT the program to do so they get a good understanding of what my end goal is and why the current program behavior is not what I want to happen.

What is expected from the code:

The intended goal for this code is for it to take in a serial "packet" that is sent in ie. <200, -150, 300, 100> then decode, and send the speeds to the steppers, then run the steppers at those speeds. It should continue to run these steppers at these speeds until the speeds change. If I send <200, -150, 300, 100> then <0,0,0,0> the steppers should run at their respective steps per second and the direction specified, then once it receives the <0,0,0,0> it should stop etc.

What the code actually does:

This is where the problem lies. With the current code (I will attach at the bottom), the Arduino will receive the first serial command I send to it, then start to run the steppers. This is all going as planned. Then I will send another packet like <0,0,0,0> or any other variant and the motors just continue to go at the first speed that was specified in the first command sent.

I can only assume that something is blocking somewhere in the code, mainly in the recvWithStartEndMarkers() method, or the newData boolean is stuck being false, thus never sending new values to the speed variables.

I thought I would post this here to see if I am overlooking something very obvious or if I am not understanding something correctly. I will continue to try and troubleshoot this problem and if I do end up fixing it I will put the solution here. If anyone also has any suggestions on how to also make my code better and if there are better practices to use, I'm all ears!

Most of the serial code is ripped off another thread that details Serial Input Basics. Example 5 is where most of the code was taken from. Found here: Serial Input Basics - updated - Introductory Tutorials - Arduino Forum

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be 1 for a driver like DRV8825
#define BRdirPin 7
#define BRstepPin 6

#define FLdirPin 4
#define FLstepPin 5

#define BLdirPin 8
#define BLstepPin 9

#define FRdirPin 2
#define FRstepPin 3
#define motorInterfaceType 1

int FLSpeed = 0;
int FRSpeed = 0;
int BLSpeed = 0;
int BRSpeed = 0;

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];

// Create a new instance of the AccelStepper class for each stepper:
AccelStepper BLstepper = AccelStepper(motorInterfaceType, BLstepPin, BLdirPin);
AccelStepper BRstepper = AccelStepper(motorInterfaceType, BRstepPin, BRdirPin);
AccelStepper FLstepper = AccelStepper(motorInterfaceType, FLstepPin, FLdirPin);
AccelStepper FRstepper = AccelStepper(motorInterfaceType, FRstepPin, FRdirPin);

boolean newData = false;

void sendSpeedsToSteppers() {
  BLstepper.setSpeed(-BLSpeed);
  BRstepper.setSpeed(BRSpeed);
  FLstepper.setSpeed(-FLSpeed);
  FRstepper.setSpeed(FRSpeed);
}

void runSteppers() {
  BLstepper.runSpeed();
  BRstepper.runSpeed();
  FLstepper.runSpeed();
  FRstepper.runSpeed();
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }
    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

//split the data into its parts
void parseData() {

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars,",");
  FLSpeed = atoi(strtokIndx);
 
  strtokIndx = strtok(NULL, ",");
  FRSpeed = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ",");
  BLSpeed = atoi(strtokIndx);
  
  strtokIndx = strtok(NULL, ",");
  BRSpeed = atoi(strtokIndx); 

}

void setup() {
  // Set the maximum speed in steps per second:
  BLstepper.setMaxSpeed(800);
  BRstepper.setMaxSpeed(800);
  FLstepper.setMaxSpeed(800);
  FRstepper.setMaxSpeed(800);
}

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    parseData();
  }
  sendSpeedsToSteppers();
  runSteppers();
}

Once newData is true it is never reset to false