我正在為 Arduino 設備撰寫步進電機設備。在我的頭檔案中,我宣告了 AccelStepper 庫的實體。稍后我想使用指標陣列迭代步進器。我發現這些實體有不同的地址。你能解釋一下這里出了什么問題,并給我一個提示,我該如何解決這個問題?
檔案: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);
};
檔案彎管機.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;
}
請忽略 msg_h.say() 方法,它只是Serial.print取決于除錯級別。
我希望的地址feederStepper保持不變,但實際上我得到了不同的地址。我用MESSAGE x前綴標記了輸出行。從 MSG1 到 MSG2,地址不同。是什么原因?我希望在bender.h 中宣告該地址是保留的(并且仍然存在)。
輸出:
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?
uj5u.com熱心網友回復:
是的,您宣告了多個 AccelStepper 物件。要創建指向步進電機物件的指標陣列,如上所述,您可以完全從 Bender 類中洗掉物件,并且只保留指向陣列中物件的三個指標。例如:
#define FEED_IDX 0
#define ROT_IDX 1
#define BEND_IDX 2
steppers[FEED_IDX] = new AccelStepper(1, P_FEED_STEP, P_FEED_DIR);
steppers[ROT_IDX] = new AccelStepper(1, P_ROT_STEP, P_ROT_DIR);
steppers[BEND_IDX] = new AccelStepper(1, P_BEND_STEP, P_BEND_DIR);
然后只需在代碼中使用 _IDX 常量來區分它們。
另一種方法是,如果要將三個物件保留在 Bender 物件中,則完全洗掉 Bender 建構式中的步進電機宣告,并將初始化串列添加到設定三個步進器的建構式中。代碼應如下所示:
Bender::Bender() :
// initializer list to setup stepper motor objects
feederStepper(1, P_FEED_STEP, P_FEED_DIR), // (Type:driver, STEP, DIR)
rotationStepper(1, P_ROT_STEP, P_ROT_DIR),
benderStepper(1, P_BEND_STEP, P_BEND_DIR)
{
sprintf(strbuf, "MESSAGE 1: &feederStepper=%p", &feederStepper);
msg_h.say(strbuf, L_ALWAYS);
steppers[0] = &feederStepper;
steppers[1] = &rotationStepper;
steppers[2] = &benderStepper;
這兩個代碼示例在 Arduino 1.8.12 中都可以正常編譯,但我沒有合適的硬體,而且你的代碼不完整,所以我無法運行它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/448786.html
