2015-09-30 114 views
0

我借用PJRC's Encoder library來管理步進驅動注射泵我運行的是Sparkfun RedBoardBigEasy DriverPJRC編碼器對象作爲另一個對象的屬性

我一直在模塊化地開發程序,首先定義低級類並從那裏開始工作。這是我的願望更高級別的類將較低類的實例作爲屬性。在我目前的噩夢中,我正在構建一個帶有步進電機和編碼器對象屬性的注射泵類。

我正按照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對象而不會嚇壞編譯器。

回答

0

事實上,關鍵在於初始化Pump對象中的編碼器,因爲我一直在閱讀人們發佈的Arduino板卡上的某些版本的問題。

我在'Pump.h'屬性聲明中構造了編碼器。由於我正在使用的RedBoard是Arduino Uno,本質上,唯一可接受的引腳是2和3中斷。我宣佈編碼器下面的類屬於私有屬性列表中的以下行:

Encoder encoder = Encoder(2,3);  // attached encoder 

它現在可以正常工作。有可能選擇將編碼器引腳傳遞給Pump構造函數,並使其具有靈活性,但是目前我需要的東西比我需要的東西更完美。

相關問題