Stepper Strafing Code

Hi - I have a dead end that I'd like to find a way around, but anything I think of adds a lot of code.

I have two stepper motors - while one spins constantly in a single direction, the other strafes back and forth. There are numerous 'blocks' of commands in arrays that run sequentially.

void blockWinder() {
  s2_aCon();  // this performs math and populates the arrays with speeds and destinations for the steppers.

stepper1.enableOutputs();
stepper2.enableOutputs();

    s2_zero();       // this moves the strafing motor to an end stop and sets the position to 0.

    
  for (int i = 0; i < 20; i ++) {        // there are 20 'blocks' in the arrays
    stepper1.setCurrentPosition(0); // stepper one moves in one direction until finished, and starts again on the next block

    stepper1.setMaxSpeed(MaxSpeed1);
    stepper1.setAcceleration(Accel1);

    stepper2.setMaxSpeed(MaxSpeed2[i]); //variable speed for stepper 2
    stepper2.setAcceleration(MAX_XCL);
    
    stepper2.moveTo(Move2_A[i]); // position A is the starting place for the strafing motion
    
    stepper1.moveTo(Move1[i]); // each block's number of winds differs
    

    /* *** RUNNER *** */
 
    while (stepper1.distanceToGo() > 0) {
      stepper1.run();

    if (stepper2.currentPosition() == Move2_A[i]) {stepper2.moveTo(Move2_B[i]);}

    if (stepper2.currentPosition() == Move2_B[i]) {stepper2.moveTo(Move2_A[i]);}

      stepper2.run();
    };
  
    /* *** RUNNER *** */
    
  };
  
  stepper2.moveTo(0);
  stepper2.runToPosition();
  windStatus = false;
  stepper1.disableOutputs();
  stepper2.disableOutputs();
}


void loop() {
  while (windStatus == true) {
//   blockWinder();
  }
}

OK - sorry for the pile of crap, but the problem area is in the RUNNER part up there. It constricts the loop to run out each block's # of winds on stepper1, whilst strafing back and forth with stepper2, then moving to the next block.

My issue is with this:

if (stepper2.currentPosition() == Move2_A[i]) {stepper2.moveTo(Move2_B[i]);}
if (stepper2.currentPosition() == Move2_B[i]) {stepper2.moveTo(Move2_A[i]);}

Move2_A and Move2_B are derived from 6 possible locations, all using the same 0 point established at the beginning of the function for stepper2.

Sometimes, the stepper motor starts overrunning the bounds established when there's a block change - I'm guessing it's getting confused when it hits a step location at the end of a movement and sets that same location on the new block and accepts a command to move the other way.

I would like to avoid having to reset my 0 point for every block because it's a lot of calculations every time the block changes, so I'm just wondering how I can get the strafing action between the two defined points without relying on the method above.

Sorry if this is really incoherent, I can post the whole code below.

#include <AccelStepper.h>


// 2 mm/rev, 4 starts -- 100 steps per mm
AccelStepper stepper1(AccelStepper::DRIVER, 26, 25);
AccelStepper stepper2(AccelStepper::DRIVER, 16, 27);

/* DELME */ // These are some constant parameters to test things out, later will be user entered
float RPMs = 1100;
float bobbinPlate = 1.1;
float bobbinSpace = 26;
float gauge = 0.0633;
bool dirCW = true;
int blockNum[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int blockArea[] = {1,6,3,4,5,1,6,3,4,5,1,6,3,4,5,1,6,3,4,5};
int blockStrafe[] = {1,4,3,2,1,3,2,4,1,2,1,4,3,2,1,3,2,4,1,2};
long blockWinds[] = {6000,100,400,600,2000,6000,4000,200,100,400,600,2000,6000,4000,200,100,400,600,2000,6000};
/* DELME */

long MAX_SPD = 5000;
long MAX_XCL = 100000;
int to_step = 100;

long MaxSpeed1 = (RPMs*800)/60;
long Accel1 = 2000;
long Move1[21];
long MaxSpeed2[21];
int Move2_A[21];
int Move2_B[21];


int s2_bobbinPlate = bobbinPlate*to_step;
int s2_bobbinSpace = bobbinSpace*to_step;

  int Strafe_4 = s2_bobbinSpace;
  int Strafe_3 = Strafe_4*.66;
  int Strafe_2 = Strafe_4*.33;
  int Strafe_1 = 0;
  int gaugeLen = gauge*to_step;
  int RawSpeed2 = 0;
  
bool windStatus = false;

void setup() {
  windStatus = true;
  stepper1.setMinPulseWidth(20);
  stepper1.setEnablePin(17);
  stepper1.setPinsInverted(false,false,true);
  stepper1.disableOutputs();
  stepper2.setMinPulseWidth(20);
  stepper2.setEnablePin(14);
  stepper2.setPinsInverted(false,false,true);
  stepper2.disableOutputs();
}

/* *** BLOCK MATH autoWind Page ! *** */

void s2_aCon() {

  for (int i = 0; i < 20; i ++) {
    if (blockArea[i] == 1) {
      Move2_A[i] = Strafe_1;
      Move2_B[i] = Strafe_2;
      };
    if (blockArea[i] == 2) {
      Move2_A[i] = Strafe_2;
      Move2_B[i] = Strafe_3;
      };
    if (blockArea[i] == 3) {
      Move2_A[i] = Strafe_3;
      Move2_B[i] = Strafe_4;
      };
    if (blockArea[i] == 4) {
      Move2_A[i] = Strafe_1;
      Move2_B[i] = Strafe_3;
      };
    if (blockArea[i] == 5) {
      Move2_A[i] = Strafe_2;
      Move2_B[i] = Strafe_4;
      };
    if (blockArea[i] == 6) {
      Move2_A[i] = Strafe_1;
      Move2_B[i] = Strafe_4;
      };


    if (blockStrafe[i] == 1) {RawSpeed2 = s2_bobbinSpace/2;}
    if (blockStrafe[i] == 2) {RawSpeed2 = s2_bobbinSpace/4;}
    if (blockStrafe[i] == 3) {RawSpeed2 = s2_bobbinSpace/8;}
    if (blockStrafe[i] == 4) {RawSpeed2 = (MaxSpeed1/800) * gaugeLen;}


// bobbinSpace / gauge = # s1_winds_per_s2_strafe
    
      if (blockArea[i] == 1) {MaxSpeed2[i] = RawSpeed2*.333;};
      if (blockArea[i] == 2) {MaxSpeed2[i] = RawSpeed2*.333;};
      if (blockArea[i] == 3) {MaxSpeed2[i] = RawSpeed2*.333;};
      if (blockArea[i] == 4) {MaxSpeed2[i] = RawSpeed2*.666;};
      if (blockArea[i] == 5) {MaxSpeed2[i] = RawSpeed2*.666;};
      if (blockArea[i] == 6) {MaxSpeed2[i] = RawSpeed2;};

      Move1[i] = blockWinds[i]*800;
      
    };
}
/* *** BLOCK MATH *** */

void s2_zero() {
  //move to bump stop, set 0  
  stepper2.setCurrentPosition(0);
};
void s2_bobComp() {
  //do bobbin plate compensation, set 0
  stepper2.setMaxSpeed(MAX_SPD);
  stepper2.setAcceleration(MAX_XCL);
  stepper2.moveTo(s2_bobbinPlate);
  stepper2.runToPosition();
  stepper2.setCurrentPosition(0);
};

void blockWinder() {
  s2_aCon();

stepper1.enableOutputs();
stepper2.enableOutputs();
    s2_zero();
    s2_bobComp();
    
  for (int i = 0; i < 20; i ++) {
    stepper1.setCurrentPosition(0);

    stepper1.setMaxSpeed(MaxSpeed1);
    stepper1.setAcceleration(Accel1);

    stepper2.setMaxSpeed(MaxSpeed2[i]);
    stepper2.setAcceleration(MAX_XCL);
    
    stepper2.moveTo(Move2_A[i]);

    if (dirCW != true) {Move1[i] = -Move1[i];}
    
    stepper1.moveTo(Move1[i]);
    
    /* *** RUNNER *** */
    if (dirCW != true) {
    while (stepper1.distanceToGo() < 0) {
      stepper1.run();
    if (stepper2.currentPosition() == Move2_A[i]) {
      stepper2.moveTo(Move2_B[i]);}
    if (stepper2.currentPosition() == Move2_B[i]) {
      stepper2.moveTo(Move2_A[i]);}
    stepper2.run();}} else {
    while (stepper1.distanceToGo() > 0) {
      stepper1.run();
    if (stepper2.currentPosition() == Move2_A[i]) {
      stepper2.moveTo(Move2_B[i]);}
    if (stepper2.currentPosition() == Move2_B[i]) {
      stepper2.moveTo(Move2_A[i]);}
      stepper2.run();
    };
  }
    /* *** RUNNER *** */
    
  };
  
  stepper2.moveTo(0);
  stepper2.runToPosition();
  windStatus = false;
  stepper1.disableOutputs();
  stepper2.disableOutputs();
}


void loop() {
  while (windStatus == true) {
blockWinder();
  }

}

by "Sometimes, the stepper motor starts overrunning the bounds" do you mean overunning the bounds of an array?

For example, trying to access the 11th element of a 10 element size array? (trying to access Array[11] of array[10])

Just trying to wrap my head around the actual issue.

Styryl:
by "Sometimes, the stepper motor starts overrunning the bounds" do you mean overunning the bounds of an array?

For example, trying to access the 11th element of a 10 element size array? (trying to access Array[11] of array[10])

Just trying to wrap my head around the actual issue.

No sorry, I'll explain better:

I've got a defined size (int bobbinSpace = mm / int s2_bobbinspace = distance in steps). That area is divided into thirds:

|-------|-------|-------|
|       |       |       |
1       2       3       4

the first point is always 0, #4 is the full length of the space, #2 is 33% of #4, and #3 is 66% of 4.

So Move2_A will always be 1, 2, or 3, and Move2_B will always be 2,3, or 4. So the strafing action can happen on any multiple of thirds in this space.

I'm not sure why exactly, but sometimes the function sends the stepper driving past the zero point or defined space width, then it starts doing its strafing a long way away.

I just thought of a way to ensure that doesn't happen - I think I need to make the stepper2 motor drive to Move2_A point before the strafing loop begins...I think that'll do it. It's not ideal, since I'd rather have a continuous motion, but I can't wrap my head around the math and it's a tall order to dump on benevolent internet people.

If you can picture an idea, I'd like to hear about it but don't worry if it's a hassle, I can work around it.

All is well, I can live with the millisecond of time it takes to run to the A point in between