Creating AccelStepper objects in separate header file for usage in other files

Hi, I am a beginner to arduino and I am trying to use the AccelStepper library to run a couple motors. I do not want to use the MultiStepper library since it does not offer acceleration capabilities, and for the purpose of this question I do not care about coordinated movement. I have created a main .ino script, a config.h file, and a movement.cpp and movement.h file. I have posted each file below.

I keep running into a compiling error that says I have multiple definitions of the 'steppers', 'stepperZ', 'stepperY', 'stepperX', and 'AMISstepper'. I noticed that these are specifically objects created by AccelStepper library so I am not entirely sure if it is something to do with the library classes or basic coding format.

I am using a Nucleo L476RG with AMIS-30543 stepper motor drivers

StepperAccelExample.ino:

#include <SPI.h>
#include <AMIS30543.h>
#include <AccelStepper.h>

#include "config.h"
#include "movement.h"

void setup()
{
  SPI.begin();

  for (int i = 0; i < stepperAmount; i++) {
    AMISstepper[i].init(amisSlaveSelect[i]);
    delay(1);

    AMISstepper[i].resetSettings();
    AMISstepper[i].setCurrentMilliamps(1800);
    AMISstepper[i].setStepMode(4);
    AMISstepper[i].enableDriver();

    steppers[i]->setMaxSpeed(maximumSpeed[i]);
    steppers[i]->setAcceleration(maximumAccel[i]);

    if (i == 1) {
      steppers[i]->setPinsInverted(true, false, false);
    }
  }
}

void loop()
{
  movement(zeros);
  delay(500);

  movement(steps);
  delay(500);
}

config.h:

#pragma once
#include "Arduino.h"
#include <SPI.h>
#include <AMIS30543.h>
#include <AccelStepper.h>

#define stepperAmount  3

const uint8_t amisDirPin[stepperAmount] = {PB11, PB12, PB13};
const uint8_t amisStepPin[stepperAmount] = {PC5, PC6, PC7};
const uint8_t amisSlaveSelect[stepperAmount] = {PB3 , PB4, PB5};

const int steps[stepperAmount] = {33333, 6252, 66667}; // microsteps
const int maximumSpeed[stepperAmount] = {7111, 4190, 14222}; // steps per second
const int maximumAccel[stepperAmount] = {6667, 3928, 13333}; // steps per second^2

const int zeros[stepperAmount] = {0, 0, 0};

AMIS30543 AMISstepper[stepperAmount] = {};
AccelStepper stepperX(AccelStepper::DRIVER, amisStepPin[0], amisDirPin[0]);
AccelStepper stepperY(AccelStepper::DRIVER, amisStepPin[1], amisDirPin[1]);
AccelStepper stepperZ(AccelStepper::DRIVER, amisStepPin[2], amisDirPin[2]);

AccelStepper *steppers[] = {&stepperX, &stepperY, &stepperZ}

movement.cpp

#include "Arduino.h"
#include <SPI.h>
#include <AMIS30543.h>
#include <AccelStepper.h>

#include "config.h"
#include "movement.h"

void movement(const int pos[stepperAmount]) {

  for (int i = 0; i < stepperAmount; i++) {
    steppers[i]->moveTo(pos[i]);
  }

  while (steppers[0]->isRunning() || steppers[1]->isRunning() || steppers[2]->isRunning()) {
    for (int i = 0; i < stepperAmount; i++) {
      steppers[i]->run();
    }
  }
}

movement.h:

#pragma once

#include "Arduino.h"
#include <SPI.h>
#include <AMIS30543.h>
#include <AccelStepper.h>

#include "config.h"

void movement(const int[3]);

You should not define variables in .h files, only declare them (as extern). That along with #including movement.h in movement.cpp and the main .ino file is causing the problem.

See my Post #5 In This Thread.

1 Like

Move these lines into your .ino or .cpp file. Replace them in the .h file with:

extern AccelStepper stepperX,  stepperY, stepperZ;
extern AccelStepper *steppers[3] ;
1 Like

Is it best practice to have so many externs in the .h? Or is there a better way to handle these const?

config.h

#pragma once
#include "Arduino.h"
#include <SPI.h>
#include <AMIS30543.h>
#include <AccelStepper.h>

#define stepperAmount  3

extern const uint8_t amisSlaveSelect[stepperAmount];

extern const int steps[stepperAmount]; // microsteps
extern const int maximumSpeed[stepperAmount]; // steps per second
extern const int maximumAccel[stepperAmount]; // steps per second^2
extern const int zeros[stepperAmount];

extern AMIS30543 AMISstepper[stepperAmount];

extern AccelStepper stepperX, stepperY, stepperZ;

extern AccelStepper *steppers[stepperAmount];

config.cpp

#include "config.h"

#define stepperAmount  3

const uint8_t amisDirPin[stepperAmount] = {PB11, PB12, PB13};
const uint8_t amisStepPin[stepperAmount] = {PC5, PC6, PC7};

const uint8_t amisSlaveSelect[] = {PB3 , PB4, PB5};

const int steps[] = {33333, 6252, 66667}; // microsteps
const int maximumSpeed[] = {7111, 4190, 14222}; // steps per second
const int maximumAccel[] = {6667, 3928, 13333}; // steps per second^2
const int zeros[] = {0, 0, 0};

AMIS30543 AMISstepper[stepperAmount] = {};
AccelStepper stepperX(AccelStepper::DRIVER, amisStepPin[0], amisDirPin[0]);
AccelStepper stepperY(AccelStepper::DRIVER, amisStepPin[1], amisDirPin[1]);
AccelStepper stepperZ(AccelStepper::DRIVER, amisStepPin[2], amisDirPin[2]);

AccelStepper *steppers[] = {&stepperX, &stepperY, &stepperZ};

Thank you for showing an example. I was having a hard time implementing @gfvalvo solution!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.