Using Adafruit Motor Shield with 15 steppers and AccelStepper

I'm having trouble with keeping it simple.

I have 8 Adafruit Motorshields, stacked on an Arduino Mega (soon to be switched with a Due)

I used the Adafruit Motorshield example using AccelStepper to create non-blocking functions running multiple motors, where you pass it the stepForwad and stepBackward function for the one specific motor.

AccelStepper accelStepper(stepForward, stepBackward);

But once you want 15 steppers, then there has to be 30 functions (2 each) which seems like it should be less repetitive passing functions with parameters like (stepForward(theMotor), stepBackward(theMotor)) which it doesn't seem to like.

I just started learning pointers this week so I may have something screwed up here but overall it does compile...

I even toyed around with making a class to manage the association between AFMS and AccelStepper but the AccelStepper doesn't like references to non-static functions... >:(

halp?!?

Adafruit_MotorShield AFMS0(0x60), AFMS1(0x61), AFMS2(0x62), AFMS3(0x63), AFMS4(0x64), AFMS5(0x65), AFMS6(0x66), AFMS7(0x67);
Adafruit_MotorShield *AFMS[] = {&AFMS0, &AFMS1, &AFMS2, &AFMS3, &AFMS4, &AFMS5, &AFMS6, &AFMS7};
const int BOARD_COUNT = 8, MOTOR_COUNT = 15, REV_STEPS = 200;

Adafruit_StepperMotor *stepper[MOTOR_COUNT];
AccelStepper accelStepper[MOTOR_COUNT];
void (*moveMotor[])(void)=
  {&mf1, &mf2, &mf3, &mf4};
  
void initAS() {
  // for loop goes here to iterate and initialize all accelSteppers
  accelStepper[0] = AccelStepper(moveMotor[0], moveMotor[1]);
}

void setupMotors() {
  int afmsIndex = 0;
  int motorIndex = 0;
  
  while(motorIndex < MOTOR_COUNT) {
    stepper[motorIndex] = AFMS[afmsIndex]->getStepper(200, 1);
    motorIndex++;

    if(motorIndex < MOTOR_COUNT) {
      stepper[motorIndex] = AFMS[afmsIndex]->getStepper(200, 2);
    }
    
    if (afmsIndex < BOARD_COUNT) {
      afmsIndex++;
    }

    motorIndex++;
  }
}
  
void mf1() {
  stepper[0]->onestep(FORWARD, DOUBLE);
}
void mb1() {
  stepper[0]->onestep(BACKWARD, DOUBLE);
}
void mf2() {
  stepper[1]->onestep(FORWARD, DOUBLE);
}
void mb2() {
  stepper[1]->onestep(BACKWARD, DOUBLE);
}
void mf3() {
  stepper[0]->onestep(FORWARD, DOUBLE);
}
void mb3() {
  stepper[0]->onestep(BACKWARD, DOUBLE);
}

// ... it goes on till mb14

The pain is just in the setup, not when dealing with all those steppers... Probably easiest to just bite the bullet and type it out

#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>
//#include <MultiStepper.h>

Adafruit_MotorShield AFMS0(0x60), AFMS1(0x61), AFMS2(0x62), AFMS3(0x63), AFMS4(0x64), AFMS5(0x65), AFMS6(0x66), AFMS7(0x67);
Adafruit_MotorShield *AFMS[] = {&AFMS0, &AFMS1, &AFMS2, &AFMS3, &AFMS4, &AFMS5, &AFMS6, &AFMS7};
const int BOARD_COUNT = 8, MOTOR_COUNT = 15, REV_STEPS = 200;

Adafruit_StepperMotor *stepper[MOTOR_COUNT];
AccelStepper accelStepper[MOTOR_COUNT];

void mf0() {stepper[0]->onestep(FORWARD,  DOUBLE);}
void mb0() {stepper[0]->onestep(BACKWARD, DOUBLE);}
void mf1() {stepper[1]->onestep(FORWARD,  DOUBLE);}
void mb1() {stepper[1]->onestep(BACKWARD, DOUBLE);}
void mf2() {stepper[2]->onestep(FORWARD,  DOUBLE);}
void mb2() {stepper[2]->onestep(BACKWARD, DOUBLE);}
void mf3() {stepper[3]->onestep(FORWARD,  DOUBLE);}
void mb3() {stepper[3]->onestep(BACKWARD, DOUBLE);}
void mf4() {stepper[4]->onestep(FORWARD,  DOUBLE);}
void mb4() {stepper[4]->onestep(BACKWARD, DOUBLE);}
void mf5() {stepper[5]->onestep(FORWARD,  DOUBLE);}
void mb5() {stepper[5]->onestep(BACKWARD, DOUBLE);}
void mf6() {stepper[6]->onestep(FORWARD,  DOUBLE);}
void mb6() {stepper[6]->onestep(BACKWARD, DOUBLE);}
void mf7() {stepper[7]->onestep(FORWARD,  DOUBLE);}
void mb7() {stepper[7]->onestep(BACKWARD, DOUBLE);}
void mf8() {stepper[8]->onestep(FORWARD,  DOUBLE);}
void mb8() {stepper[8]->onestep(BACKWARD, DOUBLE);}
void mf9() {stepper[9]->onestep(FORWARD,  DOUBLE);}
void mb9() {stepper[9]->onestep(BACKWARD, DOUBLE);}
void mf10() {stepper[10]->onestep(FORWARD,  DOUBLE);}
void mb10() {stepper[10]->onestep(BACKWARD, DOUBLE);}
void mf11() {stepper[11]->onestep(FORWARD,  DOUBLE);}
void mb11() {stepper[11]->onestep(BACKWARD, DOUBLE);}
void mf12() {stepper[12]->onestep(FORWARD,  DOUBLE);}
void mb12() {stepper[12]->onestep(BACKWARD, DOUBLE);}
void mf13() {stepper[13]->onestep(FORWARD,  DOUBLE);}
void mb13() {stepper[13]->onestep(BACKWARD, DOUBLE);}
void mf14() {stepper[14]->onestep(FORWARD,  DOUBLE);}
void mb14() {stepper[14]->onestep(BACKWARD, DOUBLE);}
void mf15() {stepper[15]->onestep(FORWARD,  DOUBLE);}
void mb15() {stepper[15]->onestep(BACKWARD, DOUBLE);}

void (*moveMotor[MOTOR_COUNT*2])(void) = {
  &mf0, &mb0,
  &mf1, &mb1,
  &mf2, &mb2,
  &mf3, &mb3,
  &mf4, &mb4,
  &mf5, &mb5,
  &mf6, &mb6,
  &mf7, &mb7,
  &mf8, &mb8,
  &mf9, &mb9,
  &mf10, &mb10,
  &mf11, &mb11,
  &mf12, &mb12,
  &mf13, &mb13,
  &mf14, &mb14,
};

void setupMotors() {
  for (int i= 0; i < MOTOR_COUNT; i++ ) {
    int board = i / 2;
    int motor_num = i % 2 + 1;
    stepper[i] = AFMS[board]->getStepper(REV_STEPS, motor_num);
    accelStepper[i] = AccelStepper(moveMotor[i*2], moveMotor[i*2+1]);
  }
}

void setup()
{
  Serial.begin(9600);
  while(!Serial);

  setupMotors();
  for( int i=0; i<BOARD_COUNT; i++ ) { 
    AFMS[i]->begin();
    Serial.print( F("board[") ); Serial.print(i); Serial.print( F("] = ") ); Serial.println((unsigned long)AFMS[i], HEX);
    Serial.print( F("  motor[") ); Serial.print(i*2); Serial.print( F("] = ") ); Serial.println((unsigned long)&(accelStepper[i*2]), HEX);
    Serial.print( F("  motor[") ); Serial.print(i*2+1); Serial.print( F("] = ") ); Serial.println((unsigned long)&(accelStepper[i*2+1]), HEX);
  }

  accelStepper[0].setMaxSpeed(100.0);
  accelStepper[0].setAcceleration(100.0);
  accelStepper[0].moveTo(24);

}

void loop() {
}

Holy moly, well thank you blh64. I'll work with your code there and move forward. I even installed CLion to see if it would help me with more verbose errors but yeah it seems like I can't get away with the insanity of writing the way I would in JavaScript land.

I appreciate the answer, thank you. Your code is very informative!

Learning a lot today...

An Adafruit DC motor shield is NOT a stepper motor driver, despite of what they say.
You can abuse it to run small high impedance steppers, but most modern steppers are low impedance.
So which stepper motors have you got (link).
Leo..

Probably easiest to just bite the bullet and type it out

Oh god no.

The thing is you have too much code that simply duplicates as it is. Just have a forward and back function and pass the motor’e Index to it.

If that was the real code you posted the the index in some of them is all too pot. But you can use that technique for making multiple instances of a library call, providing the library is written correctly.

I would have thought that your main problem would be your power supply and lack of adequate bulk decoupling capacitors.

Grumpy_Mike:
Oh god no.

The thing is you have too much code that simply duplicates as it is. Just have a forward and back function and pass the motor’e Index to it.

But the AccelStepper library doesn't support that. It supports a forward and back function that takes zero parameters.
You could re-work the AccelStepper library to support a parameter...

Are you saying you can’t do this to move any motor?

void moveForward(int i){
stepper[i]->onestep(FORWARD,  DOUBLE);
}

And the same sort of thing to move back?

Grumpy_Mike:
Are you saying you can’t do this to move any motor?

void moveForward(int i){

stepper[i]->onestep(FORWARD,  DOUBLE);
}



And the same sort of thing to move back?

Yes. That is exactly what I am saying. The AccelStepper library doesn't support that.