encoder with pid controller
i encounter following problems:
1)i need bit more precision. want count 1/2 ticks. got code here post 21. edit it, doesn't work leftencoderaset.
2)how can set value of ticks , goes in value.
3)how can find dead zone of dc motor , embed in code.
1)i need bit more precision. want count 1/2 ticks. got code here post 21. edit it, doesn't work leftencoderaset.
2)how can set value of ticks , goes in value.
3)how can find dead zone of dc motor , embed in code.
code: [select]
#include <digitalwritefast.h>
// quadrature encoders
// left encoder
#define c_leftencoderinterrupt 0
#define c_leftencoderpina 2
#define c_leftencoderinterrupt 1
#define c_leftencoderpinb 3
#define leftencoderisreversed
//
volatile bool _leftencoderaset;
volatile bool _leftencoderbset;
volatile long _leftencoderticks = 0;
//variables pid
double setpoint=1350.0;//h timi p thelw na paei
unsigned long lasttime;
double errsum, lasterr;
double input, output;
double kp=0.009;
double ki=0;
double kd=0;
int speedpin=5;
int motorpin1=6;
int motorpin2=7;
//send command dc motor
void loop(){
input=_leftencoderticks;
compute();
if(output > 0) {
cc();
}
else if(output<=0){
ccw();
}
serial.print(_leftencoderticks);
serial.print("\n");
delay(20);
}
//motor control function
void cc(){
digitalwrite(motorpin1,low);
digitalwrite(motorpin2,high);
analogwrite(speedpin, abs(output));//abs apoliti t
}
void ccw(){
digitalwrite(motorpin1,high);
digitalwrite(motorpin2,low);
analogwrite(speedpin, abs(output));
}
//compute controller output pid algorithm
void compute()
{
/*how long since last calculated*/
unsigned long = millis();
double timechange = (double)(now - lasttime);
input=_leftencoderticks;
/*compute working error variables*/
double error = setpoint - input;
errsum += (error * timechange);
double derr = (error - lasterr) / timechange;
/*compute pid output*/
output = ((kp * error + ki * errsum + kd * derr)+60);
if(output>255){output = 255;}
else if(output <-255){output = -255;}
else{}
/*remember variables next time*/
lasterr = error;
lasttime = now;
}
void setup()
{
serial.begin(115200);
// quadrature encoders
// left encoder
pinmode(c_leftencoderpina, input); // sets pin input
digitalwrite(c_leftencoderpina, low); // turn on pullup resistors
pinmode(c_leftencoderpinb, input); // sets pin b input
digitalwrite(c_leftencoderpinb, low); // turn on pullup resistors
_leftencoderaset = digitalreadfast(c_leftencoderpina); // read input pin
_leftencoderbset = digitalreadfast(c_leftencoderpinb); // read input pin
attachinterrupt(c_leftencoderinterrupt, handleleftmotorinterrupta, rising);
attachinterrupt(c_leftencoderinterrupt, handleleftmotorinterruptb, rising);
pinmode(motorpin1, output);
pinmode(motorpin2, output);
pinmode(speedpin, output);
// left encoder
pinmode(c_leftencoderpina, input); // sets pin input
digitalwrite(c_leftencoderpina, high); // turn on pullup resistors
pinmode(c_leftencoderpinb, input); // sets pin b input
digitalwrite(c_leftencoderpinb, high); // turn on pullup resistors
_leftencoderaset = digitalreadfast(c_leftencoderpina); // read input pin
_leftencoderbset = digitalreadfast(c_leftencoderpinb); // read input pin
attachinterrupt(c_leftencoderinterrupt, handleleftmotorinterrupta, falling);
attachinterrupt(c_leftencoderinterrupt, handleleftmotorinterruptb, falling);
pinmode(motorpin1, output);
pinmode(motorpin2, output);
pinmode(speedpin, output);
}
// interrupt service routines left motor's quadrature encoder
void handleleftmotorinterrupta()
{
// test transition
_leftencoderaset = digitalreadfast(c_leftencoderpina); // read input pin
_leftencoderbset = digitalreadfast(c_leftencoderpinb); // read input pin
// , adjust counter + if leads b
#ifdef leftencoderisreversed
_leftencoderticks += (_leftencoderaset != _leftencoderbset) ? -1 : +1;
#else
_leftencoderticks -= (_leftencoderaset != _leftencoderbset) ? -1 : +1;
#endif
}
// interrupt service routines left motor's quadrature encoder
void handleleftmotorinterruptb()
{
// test transition
_leftencoderaset = digitalreadfast(c_leftencoderpina); // read input pin
_leftencoderbset = digitalreadfast(c_leftencoderpinb); // read input pin
// , adjust counter + if leads b
#ifdef leftencoderisreversed
_leftencoderticks += (_leftencoderaset != _leftencoderbset) ? -1 : +1;
#else
_leftencoderticks -= (_leftencoderaset != _leftencoderbset) ? -1 : +1;
#endif
}
2)how can set value of ticks , goes in value.
3)how can find dead zone of dc motor , embed in code.
sorry, don't understand question.
perhaps consider encoder value number of half-ticks, semi-ticks etc. still dealing integer value.
if want drive motor until encoder position reaches specified value method of doing semi-ticks same ticks - integer value less than, more or equal target position.
what mean dead zone?
Arduino Forum > Using Arduino > Programming Questions > encoder with pid controller
arduino
Comments
Post a Comment