Saturday, September 04, 2010

Geckodrive accuracy test



I hooked up the quadrature encoder outputs from one Tohoko Ricoh Type 7K00011 servomotor into an Arduino. I am using the input pull-up trick of doing a digitalWrite(HIGH) on the quadrature input pins. The quadrature A and B inputs are translated by the Arduino program into the step and direction signals into Geckodrive 320X controller attached to a second 7K00011 servomotor.

One thing I found is that to ensure accuracy, the pulses going to the Geckodrive 320X must have a very short high time. I started with a 500 uS high time, but the second motor was not tracking the first one very closely. I ended up with 10 uS high time for the pulse, and that seemed to keep the two motor shafts perfectly synchronized. The Geckodrive is rated for Step Pulse "1" Time down to 1.5 uS.

A second thing I found is that for every one quadrature step on the first motor, I needed to send four pulses to the Geckodrive. There is something in the spec sheet that says "Feedback Resolution: X4 Encoder Line Count", so maybe that explains it.

Here is the code for this example (which can help you with quadrature encoder decoding in general as well):

//
// Use quadrature sensors in one unpowered motor to
// drive other powered motor in synchronized fashion
//

int a=0; // current quadrature A
int b=0; // current quadrature B
int al=0; // last quadrature A
int bl=0; // last quadrature B

void setup() {
pinMode(2, OUTPUT); // step to Geckodrive
pinMode(3,OUTPUT); // direction to Geckodrive
digitalWrite(3,LOW);
pinMode(6, INPUT); // A quadrature input
pinMode(7, INPUT); // B quadrature input
digitalWrite(6,HIGH); // pull-up A input
digitalWrite(7,HIGH); // pull-up B input
}

void pulse(int direction)
// perform one pulse
{
unsigned long wait=0;
digitalWrite(3,direction); // signal direction
for(int i=0;i<4; i){
wait=micros();
digitalWrite(2,HIGH);
while(micros()-wait<10); // high for 10 uS
digitalWrite(2,LOW);
wait=micros();
while(micros()-wait<15); // low for at least 15 uS
}
}

void loop()
{
a=digitalRead(6); // read quadrature A
b=digitalRead(7); // read quadrature B

// decode quadrature input
// and pulse in proper direction

if((al != a) || (bl != b)){
if((al == 0) && (bl == 0)){
if((a==0)&&(b==1)){
pulse(LOW);
}else if((a==1)&&(b==0)){
pulse(HIGH);
}
}
if((al=0)&&(bl=1)){
if((a==1)&&(b==1)){
pulse(LOW);
}else if((a==0)&&(b==0)){
pulse(HIGH);
}
}
if((al==1)&&(bl==1)){
if((a==1)&&(b==0)){
pulse(LOW);
}else if((a==0)&&(b==0)){
pulse(HIGH);
}
}
if((al==1)&&(bl==0)){
if((a==0)&&(b==0)){
pulse(LOW);
}else if((a==1)&&(b==1)){
pulse(HIGH);
}
}
}
// record history of last quadrature state
al=a;
bl=b;
}

No comments: