c++ - PJRC Encoder Object as Property of Another Object -
i'm borrowing pjrc's encoder library manage stepper-powered syringe pump running off sparkfun redboard , bigeasy driver.
i've been developing program modularly, defining lower-level classes first , working there. desire higher-level classes take instances of lower classes properties. in current nightmare, i'm building syringe pump class stepper motor , encoder objects properties.
i'm organizing library header file , '.cpp' file recommended arduino tutorials. pump class declared follows in '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 resist back-pressure void relax(); // low power state void pump(float vol, float rate); // pumps requested volume @ requested rate void release(); // moves plunger way out syringe can serviced void set(); // returns plunger 0 ml }; the relevant code in 'pump.cpp' file have been testing constructor , definition of pump() method, goes so:
// 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 encoder inside here /*encoder = new(encoder(2,3)); // set 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 motor if it's asleep // make sure doesn't push outside of acceptable range if (position() + vol <= nominalvolume && position() + vol >= 0) { // (ml) / (ml/deg) = deg float degrees = vol / degvolume; // find number of degrees turn motor serial.print("looking turn "); serial.print(degrees, dec); serial.print(" degrees @ "); // (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 turn motor serial.print(rpm, dec); serial.println(" rpm in full-stepping mode"); serial.print("going encoder count "); serial.print(encoder.read(), dec); serial.print(" "); serial.println(goal, dec); motor.drive(degrees, 1, rpm); // drive pump int err = goal - encoder.read(); // how far goal in counts? serial.print("reached encoder count "); serial.println(encoder.read(), dec); serial.print("missed "); serial.println(err, dec); } } i've been testing pump() method , threw in whole bunch of serial.print() try debug , figure out happening , can see, encoder object property of pump object doesn't have position updated shaft turns, whereas encoder object declared in arduino sketch , passed pump constructor does.
as can see above i've tried initialize encoder within pump constructor 2 or 3 things tried threw bunch of cryptic errors in arduino ide when tried compile, left commented out section can see trying.
what find exceedingly annoying while own stepper object works fine, pump object can turn motor, encoder object won't function inside pump object. when run sketch:
#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 pump pump pump(motor, encoder, 1440, 25, 2.328, 0.1); void setup() { // start serial connection serial.begin(9600); // set 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() {} i following in serial monitor:
looking turn 211.4397277832 degrees @ 58 rpm in full-stepping mode going encoder count 0 845 reached encoder count 0 missed 845 pump reading: 0.0000000000 encoder reading: 845 so, method encoder.read() returns 0 in pump object when called @ end of sketch in setup() function turns turned far wanted to.
thank reading. i'd appreciate guidance on how either pass active encoder object pump, or how initialize encoder object within pump without freaking out compiler.
the key was, in-fact, initialize encoder within pump object, i've been reading on arduino boards posted people variant of issue.
i constructed encoder within property declarations of 'pump.h'. since redboard i'm working arduino uno, in essence, acceptable pins 2 , 3 interrupts. declared encoder following line under class's list of private properties:
encoder encoder = encoder(2,3); // attached encoder and works flawlessly. there option pass encoder pins pump constructor , have flexible, time being need works more need perfect.
Comments
Post a Comment