I am programming a stepper motor device for an Arduino device. In my header file I declared instances of the AccelStepper library. Later I want to iterate over the steppers using an array of pointers. I found that the instances have different addresses. Could you explain whats wrong here and give me a hint how I can fix this?
file: bender.h
typedef char arg_t[32]; // string type with defined length for passing args from cmd line to the methods
class Bender
{
public:
Bender();
int init(arg_t []);
int feed(arg_t []);
int setStepperMaxSpeed(arg_t []);
private:
char strbuf[128];
AccelStepper feederStepper;
AccelStepper rotationStepper;
AccelStepper benderStepper;
AccelStepper *steppers[3];
arg_t stepperNames[3];
float stepperMaxSpeeds[3];
MessageControl msg_h;
int _setBenderPin(int);
int _setStpMaxSpd(int, float);
};
file bender.cpp
#include <settings.h>
#include "BenderControl.h"
#include <Arduino.h>
Bender::Bender()
{
sprintf(strbuf, "MESSAGE 1: &feederStepper=%p", &feederStepper);
msg_h.say(strbuf, L_ALWAYS);
AccelStepper feederStepper(1, P_FEED_STEP, P_FEED_DIR); // (Type:driver, STEP, DIR)
AccelStepper rotationStepper(1, P_ROT_STEP, P_ROT_DIR);
AccelStepper benderStepper(1, P_BEND_STEP, P_BEND_DIR);
steppers[0] = &feederStepper;
steppers[1] = &rotationStepper;
steppers[2] = &benderStepper;
sprintf(strbuf, "MESSAGE 2: &feederStepper=%p", &feederStepper);
msg_h.say(strbuf, L_ALWAYS);
stepperMaxSpeeds[0] = (float)FEEDER_MAX_SPEED;
stepperMaxSpeeds[1] = (float)BENDER_MAX_SPEED;
stepperMaxSpeeds[2] = (float)ROTATION_MAX_SPEED;
strcpy(stepperNames[0], "feed");
strcpy(stepperNames[1], "bend");
strcpy(stepperNames[2], "rot");
benderServo.attach(P_SERVO);
}
int Bender::init(arg_t args[])
{
int result = -1;
msg_h.say("Bender initializing\n", L_INFO);
result = _setStpMaxSpd(0, stepperMaxSpeeds[0]);
/*will evaluate result later, work in progress here*/
_setStpMaxSpd(1, stepperMaxSpeeds[1]);
_setStpMaxSpd(2, stepperMaxSpeeds[2]);
msg_h.say("Bender initialized\n", L_INFO);
return 0;
}
int Bender::_setStpMaxSpd(int idx, float val)
{
//sprintf(strbuf, "PRIVATE _setStpMaxSpd set to ");
//dtostrf(val, 4,1, &strbuf[strlen(strbuf)]);
//strncat(strbuf, "\n", 2);
//msg_h.say(strbuf, L_INFO);
//delay(50);
int ret = -1;
sprintf(strbuf, "MESSAGE3: &feederstepper %p\n", &feederStepper);
msg_h.say(strbuf, L_INFO);
sprintf(strbuf, "MESSAGE4: &benderstepper %p\n", &benderStepper);
msg_h.say(strbuf, L_INFO);
sprintf(strbuf, "MESSAGE5: &rotationstepper %p\n", &rotationStepper);
msg_h.say(strbuf, L_INFO);
sprintf(strbuf, "MESSAGE6: steppers[idx] %p\n", steppers[idx]);
msg_h.say(strbuf, L_INFO);
delay(100);
//feederStepper.setMaxSpeed(val);
steppers[idx]->setMaxSpeed(val);
delay(100);
float maxs = steppers[idx]->maxSpeed();
sprintf(strbuf, "Setpoint / real value: ");
dtostrf((double)val, 4,2, &strbuf[strlen(strbuf)]);
strncat(strbuf, " / ", 3);
dtostrf((double)maxs, 4,2, &strbuf[strlen(strbuf)]);
strncat(strbuf, "\n", 2);
msg_h.say(strbuf, L_INFO);
delay(50);
if (abs(maxs - val) > 0.01)
{
msg_h.say("SET FAIL", L_INFO);
sprintf(strbuf, "Could not set max speed of stepper %s to ", stepperNames[idx]);
dtostrf(val, 4,1, &strbuf[strlen(strbuf)]);
strncat(strbuf, "\n", 2);
msg_h.say(strbuf, L_ERROR);
ret = -1;
}
else
{
sprintf(strbuf, "Stepper %s max speed = ", stepperNames[idx]);
dtostrf(maxs, 4, 1, &strbuf[strlen(strbuf)]);
strncat(strbuf, "\n", 2);
msg_h.say(strbuf, L_INFO);
ret = 0;
delay(50);
}
return ret;
}
Please ignore msg_h.say() method, it is just a Serial.print
depending on the debug level.
I expected the address of feederStepper
to remain the same but in reality I get different addresses.
I marked the output lines with a MESSAGE x prefix.
From MSG1 to MSG2 the address differs. What is the reason? I expected with the declaration in bender.h the address is reserved (and remains).
Output:
MESSAGE1: &feederStepper=0x1e11
MESSAGE2: &feederStepper=0x21aa // why has the address changed here?
MESSAGE3: &feederstepper 0x1e11 // and why is here the old address from MSG1?
MESSAGE4: &benderstepper 0x1e99
MESSAGE5: &rotationstepper 0x1e55
MESSAGE6: steppers[idx] 0x21aa
Is it possible that I have two instances of the feederStepper (and the other steppers) in my program? What's the correct way to fix this? Should I initialize the pointer array right at the declaration in the bender.h file?
Cheers, Stefan
Edit after user17732522's comment: Is it a proper way to do it so:
//file: bender.h
//...
AccelStepper *steppers[3];
//...
and
//file: bender.cpp
//...
steppers[0] = &AccelStepper(1, P_FEED_STEP, P_FEED_DIR);
steppers[1] = &AccelStepper(1, P_BEND_STEP, P_BEND_DIR);
steppers[2] = &AccelStepper(1, P_ROT_STEP, P_ROT_DIR);
//...
Is this sulution better?