Hello , for 2 weeks i'm trying to wirte code to read encoder running at 60kHz and i'm unable to
. I learnt by heart all posts about encoders , timers overflow , interrupts etc. and it's too difficult . If it is possible to run PWM at that frequency http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210751945/3 it should be possible to read also. Now i have 2 encoders on pin 2and4 and 3and5 for quadrature .
Generally i need to read 6 encoders on Arduino Mega using all hardware interrupts .
I read about timer overflow but i don't know why it doesn't work for me .
Any help would be VERY appreciated.
T.
// motor encoder
#define encoder0PinA 2
#define encoder0PinB 4
// controller encoder
#define encoder1PinA 3
#define encoder1PinB 5
#define SpeedPin 10
#define DirectionPin 12
int encoder0Pos = 0;
int encoder1Pos = 0;
int target = 0;
//correction = Kp * error + Kd * (error - prevError) + kI * (sum of errors)
//PID controller constants
float KP = 1 ; //position multiplier (gain) 1
float KI = 0.02; // Intergral multiplier (gain) 0,5
float KD = 1; // derivative multiplier (gain) 0,1
int lastError = 0;
int sumError = 0;
int czas = 0 ;
//Integral term min/max (random value and not yet tested/verified)
int iMax = 100;
int iMin = 0;
void setup() {
pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
pinMode(encoder1PinA, INPUT);
pinMode(encoder1PinB, INPUT);
pinMode(DirectionPin, OUTPUT);
pinMode(SpeedPin, OUTPUT);
attachInterrupt(0, doEncoderMotor0, CHANGE); // encoder pin on interrupt 0 - pin 2
attachInterrupt(1, doEncoderMotor1,CHANGE);
}
void loop(){
// zakres mnozenia 0.5 - 3
target = encoder1Pos ;
docalc();
}
void docalc() {
int error = encoder0Pos - target ; // find the error term of current position - target
lastError = error;
sumError += error;
//scale the sum for the integral term
if(sumError > iMax) {
sumError = iMax;
} else if(sumError < iMin){
sumError = iMin;
}
int ms = KP * error + KD * (error - lastError) +KI * (sumError);
if(ms > 0){
digitalWrite ( DirectionPin ,HIGH );
}
if(ms < 0){
digitalWrite ( DirectionPin , LOW );
ms = -1 * ms;
}
while (ms > 500){
analogWrite ( SpeedPin, 90 );
ms = ms -4 ;
encoder0Pos = target ;
}
int motorSpeed = map(ms,0,800,0,200);
analogWrite ( SpeedPin, motorSpeed );
}
void doEncoderMotor0(){
if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
encoder0Pos = encoder0Pos - 1; // CCW
}
else {
encoder0Pos = encoder0Pos + 1; // CW
}
}
else // found a high-to-low on channel A
{
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
}
void doEncoderMotor1(){
// look for a low-to-high on channel B
if (digitalRead(encoder1PinB) == HIGH) {
// check channel A to see which way encoder is turning
if (digitalRead(encoder1PinA) == LOW) {
encoder1Pos = encoder1Pos - 1; // CCW
}
else {
encoder1Pos = encoder1Pos + 1; // CW
}
}
// Look for a high-to-low on channel B
else {
// check channel B to see which way encoder is turning
if (digitalRead(encoder1PinA) == LOW) {
encoder1Pos = encoder1Pos + 1; // CW
}
else {
encoder1Pos = encoder1Pos - 1; // CCW
}
}
}