DC servo motor with optical encoder
i'm replace stepper motor dc servo motor optical encoder. of pid-library br3ttb (http://www.arduino.cc/playground/code/pidlibrary) able control either velocity or position of motor.
the real challenge @ moment, me, control both velocity , position. more want to:
1.) ramp velocity @ start;
2.) keep velocity constant;
3.) ramp down velocity before given position;
4.) , hold given position whatever happens.
if understand correctly should use 'cascade control' (http:// http://en.wikipedia.org/wiki/pid_controller#cascade_control); using 2 pids arranged 1 pid controlling set point of another. however, interpretation not working should. ideas?
the real challenge @ moment, me, control both velocity , position. more want to:
1.) ramp velocity @ start;
2.) keep velocity constant;
3.) ramp down velocity before given position;
4.) , hold given position whatever happens.
if understand correctly should use 'cascade control' (http:// http://en.wikipedia.org/wiki/pid_controller#cascade_control); using 2 pids arranged 1 pid controlling set point of another. however, interpretation not working should. ideas?
code: [select]
#include <avr/interrupt.h>
#include <pid_beta6.h>
#define encoderpina 3 //quadrature track (interrupt 1)
#define encoderpinb 4 //quadrature track b
#define outputpin 11
volatile long encoderpos = 0;
long encoderpos0 = 0;
unsigned long time = 0;
unsigned long time0 = 0;
int rpm = 0;
int error = 0;
double displacementsetpoint, displacementinput, displacementoutput;
pid displacementpid(&displacementinput, &displacementoutput, &displacementsetpoint, 2,3,0);
double velocitysetpoint, velocityinput, velocityoutput;
pid velocitypid(&velocityinput, &velocityoutput, &velocitysetpoint, 2,3,0);
void setup(){
pinmode(encoderpina, input);
digitalwrite(encoderpina, high); // turn on pullup resistor
pinmode(encoderpinb, input);
digitalwrite(encoderpinb, high); // turn on pullup resistor
attachinterrupt(1, doencoder, change); // encoder track on interrupt 1 (pin 3)
displacementpid.setmode(auto);
velocitypid.setmode(auto);
beginserial(115200);
}
void loop(){
time = micros();
rpm = 60 * 1000000 * abs(encoderpos - encoderpos0) / ((time - time0) * 2000);
error = 100 * (rpm - velocitysetpoint) / velocitysetpoint;
encoderpos0 = encoderpos;
time0 = time;
displacementsetpoint = 30000; // position
displacementinput = encoderpos; // read input interrupt
displacementpid.compute(); // calculate magic number
velocitysetpoint = displacementoutput; // use output set point velocity (?)
velocityinput = rpm; // input rpm calculation
velocitypid.compute(); // calculate output
analogwrite(outputpin,velocityoutput); // use velocityoutput
}
void doencoder(){ //every time change happens on encoder pin doencoder run.
if (digitalread(encoderpina) == high) { // found low-to-high on channel a
if (digitalread(encoderpinb) == low) { //ccw
encoderpos = (encoderpos - 1);
}
else { //cw
encoderpos = (encoderpos + 1);
}
}
else { //found high-to-low on channel a
if (digitalread(encoderpinb) == low) { //cw
encoderpos = (encoderpos + 1);
}
else { //ccw
encoderpos = (encoderpos - 1);
}
}
}
hi, im quite interested know if got work , problem was?
thanks
thanks
Arduino Forum > Forum 2005-2010 (read only) > Software > Syntax & Programs > DC servo motor with optical encoder
arduino
Comments
Post a Comment