PJRC编码器对象作为另一个对象的属性
PJRC Encoder Object as Property of Another Object
我借用PJRC的编码器库来管理一个步进式注射器泵,我正在运行一个Sparkfun RedBoard和一个BigEasy Driver。
我一直在模块化地开发程序,首先定义低级类,然后从那里开始工作。我的愿望是高级类将低级类的实例作为属性。在我目前的噩梦中,我正在用步进电机和编码器对象作为属性构建一个注射器泵类。
我按照Arduino教程的建议将库组织成头文件和'.cpp'文件。Pump类在'Pump.h'中声明如下:
#include "Arduino.h"
#include "Stepper.h"
#include "Encoder.h"
#define PUMP_TOP_SPEED 50 // ml/min top pump speed
#define PUMP_ERROR 10 // encoder counts acceptable error
class Pump {
private:
Stepper motor; // object stepper motor
Encoder encoder; // object attached encoder
int countPerRev; // # encoder counts per relovlution
float nominalVolume; // mL nominal syringe volume
float innerDiameter; // cm syringe inner diameter
float shaftLead; // cm driveshaft threading lead distance
float degVolume; // mL effective volume change per degree of rotation
bool state; // boolean T = ready, F = slept
public:
// constructor
Pump(const Stepper& stp, const Encoder& enc, int cpr, float vol, float diam, float lead);
float volume(); // returns nominalVolume
float position(); // returns current pump position in mL
void hold(); // high power state to resist back-pressure
void relax(); // low power state
void pump(float vol, float rate); // pumps the requested volume at requested rate
void release(); // moves the plunger all the way out so syringe can be serviced
void set(); // returns plunger to zero mL
};
我一直在测试的'Pump.cpp'文件中的相关代码是构造函数和pump()
方法的定义,如下所示:
// constructor
Pump::Pump(const Stepper& stp, const Encoder& enc, int cpr, float vol, float diam, float lead) : motor(stp), encoder(enc), countPerRev(cpr), nominalVolume(vol), innerDiameter(diam), shaftLead(lead) {
// calculate volume per degree
// (diameter^2 / 4) * PI * (lead / 360) = mL / deg
// diam * diam * lead * PI / 360 / 4 = (diam diam lead PI) / 1440
degVolume = innerDiameter * innerDiameter * shaftLead * PI / 1440;
// construct the encoder inside here
/*encoder = new(Encoder(2,3));
// set it to 0
encoder.write(0);*/
}
// pumping function
void Pump::pump(float vol, float rate) {
/*
vol < 0 INFUSE
vol > 0 WITHDRAW
*/
if (rate > PUMP_TOP_SPEED) rate = PUMP_TOP_SPEED; // limit rate
if (!state) hold(); // wake up the motor if it's asleep
// make sure this doesn't push outside of the acceptable range
if (position() + vol <= nominalVolume && position() + vol >= 0) {
// (mL) / (mL/deg) = deg
float degrees = vol / degVolume; // find number of degrees to turn the motor
Serial.print("Looking to turn ");
Serial.print(degrees, DEC);
Serial.print(" degrees at ");
// (count) + (deg) * (count/rev) / (deg/rev) = count
long goal = encoder.read() + degrees * countPerRev / 360; // set target encoder reading
// (mL/min) / (mL/deg) / (deg/rev) = RPM
int rpm = abs(rate) / degVolume / 360; // find RPM to turn the motor
Serial.print(rpm, DEC);
Serial.println(" RPM in full-stepping mode");
Serial.print("Going from encoder count ");
Serial.print(encoder.read(), DEC);
Serial.print(" to ");
Serial.println(goal, DEC);
motor.drive(degrees, 1, rpm); // drive the pump
int err = goal - encoder.read(); // how far from the goal are we in counts?
Serial.print("Reached encoder count ");
Serial.println(encoder.read(), DEC);
Serial.print("Missed by ");
Serial.println(err, DEC);
}
}
我一直在测试我的pump()
方法,并抛出了一大堆Serial.print()
,试图调试和找出正在发生的事情,从我所看到的,编码器对象是泵对象的属性,它的位置随着轴的转动而更新,而编码器对象在Arduino草图中声明并传递给泵构造器。
正如你在上面看到的,我试图在泵构造函数中初始化编码器,但是当我试图编译时,我尝试的2或3件事都在Arduino IDE中抛出了一堆神秘的错误,留下注释部分,这样你就可以看到我在尝试什么。
我发现非常烦人的是,虽然我自己的步进对象工作得很好,泵对象可以转动电机,编码器对象不会在泵对象内起作用。当我运行草图时:
#include <Stepper.h>
#include <Encoder.h>
#include <Pump.h>
// initialize stepper
Stepper motor(4, 5, 6, 7, 8, 9, 10, 11);
// initialize encoder
Encoder encoder(2, 3);
// initialize the pump
Pump pump(motor, encoder, 1440, 25, 2.328, 0.1);
void setup() {
// start the Serial connection
Serial.begin(9600);
// set up the motor
motor.enable();
motor.reset();
// pump
pump.pump(0.25,25);
Serial.print("Pump reading: ");
Serial.println(pump.position(), DEC);
Serial.print("Encoder reading: ");
Serial.println(encoder.read(), DEC);
// cool boards
pump.relax();
}
void loop() {}
我在串行监视器中得到以下内容:
Looking to turn 211.4397277832 degrees at 58 RPM in full-stepping mode
Going from encoder count 0 to 845
Reached encoder count 0
Missed by 845
Pump reading: 0.0000000000
Encoder reading: 845
因此,方法encoder.read()
总是在泵对象中返回零,但是当我在setup()
函数的草图结束时调用它时,它会转到我想要的位置。
感谢您的阅读。我希望指导如何正确地传递一个活动的编码器对象到泵,或者如何在泵内正确初始化一个编码器对象,而不会吓坏编译器。
关键是,事实上,在泵对象内初始化编码器,因为我一直在Arduino板上阅读由人们发布的一些变体我的问题。
我在'Pump.h'的属性声明中构造了编码器。由于我正在使用的RedBoard是Arduino Uno,从本质上讲,唯一可接受的引脚是中断的2和3。我在类的私有属性列表下面用下面一行声明了编码器:
Encoder encoder = Encoder(2,3); // attached encoder
现在它完美地工作了。可能有一个选项,将编码器引脚传递给泵构造函数,并使其灵活,但目前我需要的是一些工作比我需要的东西更完美。
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 从多个源构造一个对象,包括一个对象向量
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 检查哪个对象调用了另一个对象的对象方法
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 包装一个对象并假装它是一个 int
- 当一个对象试图访问它的某个属性时,程序是否可能发送Segfault
- 只有Arduino的第一个对象在包含在另一个对象的集合/数组中时会丢失其数据属性值
- 如何有效地从该对象中包含的另一个对象访问对象字段/属性
- 如何检查对象属性更新是否存在 std::map 键,否则插入一个新键?
- 在构造子类对象的过程中,更改一个类属性的数据类型会导致segfault
- 对象作为另一个对象c++的属性
- 如何在C++中更改另一个类函数中的对象属性?
- PJRC编码器对象作为另一个对象的属性
- 从另一个列表中的对象属性创建一个新的值列表
- 不能在 C++ 中更改另一个对象中的对象属性
- 我的函数返回一个对象,但我无法通过返回值访问对象的属性。