我借用PJRC's Encoder library來管理步進驅動注射泵我運行的是Sparkfun RedBoard和BigEasy Driver。PJRC編碼器對象作爲另一個對象的屬性
我一直在模塊化地開發程序,首先定義低級類並從那裏開始工作。這是我的願望更高級別的類將較低類的實例作爲屬性。在我目前的噩夢中,我正在構建一個帶有步進電機和編碼器對象屬性的注射泵類。
我正按照Arduino教程推薦的將庫組織成頭文件和'.cpp'文件。該泵類被聲明爲「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草圖中聲明並傳遞給Pump構造函數。
正如你上面看到的,我嘗試初始化泵構造函數中的編碼器,但是我嘗試過的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()
函數中變成了我完全按照我想要的方式旋轉。
謝謝您的閱讀。我很感激有關如何正確傳遞一個活動的Encoder對象到Pump的指導,或者如何正確地初始化Pump中的一個Encoder對象而不會嚇壞編譯器。