Wiring Forum
http://wiring.org.co/cgi-bin/yabb/YaBB.pl
Wiring Hardware >> Tangible computing >> Rotary Encoder Drift??
http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1187375437

Message started by roypardi on 08/17/07 at 18:30:35

Title: Rotary Encoder Drift??
Post by roypardi on 08/17/07 at 18:30:35
I'm really stuck here so I hope someone can help-

I have a Maxon motor with a rotary encoder attached and am using the barebones code (+ using v12 of Wiring) below to try to sort out an issue with the encoder position drifting. By drift I mean that the reported position accumulates errors so that the reported position is out of scope with the actual number of motor shaft turns.

To try to isolate the issue I have the motor set up so I can rotate the shaft by hand a fixed number of turns- so I am confident that I return it to it's starting point. The greater the number of turns and the faster I turn, the more the errors accumulate.

For my project I don't need absolute accuracy but I can't have as much drift as I am seeing. I believe I have the encoder correctly wired up and the code below works so I am stumped and have spent 2 days at this trying everything I can think of.

Could the encoder be sending pulses faster than the Wiring board can handle? If so do I have any options? Would additional interrupts help? I don't need greater resolution - just less/no drift?

The only other thing I can think to try is to hold my test up to an arduino board to see if I get the same drift issue.

Thanks for *any* tips!!

--Roy (lists AT roypardi.com)


The encoder:
http://pdf.directindustry.com/pdf/maxon-motor/programm-07-08/7173-21152-_251.html



Code:
int statusLED = 48;
int encoder0PinA = 2;
int encoder0PinB  = 15;
int encoder0Pos = 0;

void setup(){
 pinMode(statusLED, OUTPUT);
 digitalWrite(statusLED, HIGH);

 Serial.begin(9600);

 pinMode(encoder0PinA, INPUT);
 pinMode(encoder0PinB, INPUT  );

 attachInterrupt(encoder0PinA, doEncoder, RISING);
}

void loop()
{
 Serial.println (encoder0Pos, DEC);
 delay(30);
}

void doEncoder(){
 if (digitalRead(encoder0PinB) == LOW) {
   encoder0Pos = (encoder0Pos + 1);  
   digitalWrite(statusLED, HIGH);
 }
 else {
   encoder0Pos = (encoder0Pos - 1);
   digitalWrite(statusLED, LOW);
 }
}

Title: Re: Rotary Encoder Drift??
Post by Alan_Kilian on 08/18/07 at 21:50:06
That code is not going to work.

Imagine that encoder phase A goes low/high/low/high/low/high when it's
right st the edge of a count.

Your code will keep incrementing the position even though the shaft is
not moving continuously forward.

You should try interrupting on both low-to-high and high-to-low and either
increment or decrement the counter.

Title: Re: Rotary Encoder Drift??
Post by roypardi on 08/20/07 at 20:48:53
I took a look at the Encoder library source and that is how it is set up: to check the state of the B pin when A is RISING - so I don't think my problem was there. This is assuming that RISING is a discreet event that only causes one interrupt, That *seems* to be the case but I have no idea.

With some help from folks on the Arduino bbs I've been able to narrow it down to my Serial.print() commands causing encoder pulses (+ interrupts I guess) to be missed. I bumped up the Serial speed, reduced the print calls and it looks like the missed pulses are greatly reduced.

--Roy

Title: Re: Rotary Encoder Drift??
Post by Alan_Kilian on 08/22/07 at 00:55:10

roypardi wrote on 08/20/07 at 20:48:53:
I took a look at the Encoder library source and that is how it is set up: to check the state of the B pin when A is RISING


Yeah, I checked Version 0011 and that's the way it is setup.

It's wrong though.

I'll try and find some time to write a correct encoder library if I can find the time.

Title: Re: Rotary Encoder Drift??
Post by barragan on 08/22/07 at 06:59:52
hi Alan, IŽve made some changes to Encoder.cpp http://wiring.uniandes.edu.co/source/trunk/wiring/lib/Encoder/Encoder.cpp?revision=386&view=markup I havenŽt had the chance to test it yet, IŽll give it a try tomorrow.

Title: Re: Rotary Encoder Drift??
Post by roypardi on 08/22/07 at 18:15:27
Hi-

Seems like the change will give greater resolution (possibly breaking existing projects?) since it now tracks CHANGE instead of just RISING.

I still have the question about RISING being a discreet even: low > high that results in just one interrupt. Isn't that the way it works?

If so, then there wouldn't be an edge state where it continually fired off interrupts even is the shaft isn't moving.

But that's just my rudimentary understanding of all this encoder stuff... ;)

Title: Re: Rotary Encoder Drift??
Post by Alan_Kilian on 08/23/07 at 02:34:10
You are correct that RISING will give ONE interrupt on a rising edge.

Now imagine that you wiggle the shaft a little bit between a black and white bit.
you'll get RISING, FALLING, RISING, FALLING etc.

Each RISING will count +1 and the FALLING will not do anything, so even
though you are not rotating continuously in one direction, the counter will
keep incrementing (forever) and you get farther and farther from the right answer.

You would need to count (-1) on FALLING in this case.
(It's more complicated. You need 4 states to count properly)

Title: Re: Rotary Encoder Drift??
Post by roypardi on 08/23/07 at 14:10:56
Ok - that makes sense

oh - fwiw - there seems a conflict in the docs @ how many interrupt pins there are.

This page says 4:
http://wiring.org.co/reference/libraries/Encoder/Encoder_.html

This page says 8:
http://wiring.org.co/ioboard/index.html#070

Title: Re: Rotary Encoder Drift??
Post by barragan on 08/23/07 at 17:05:04
Yes, is true, it should be clearer, the Encoder library only uses 4 of the 8 External interrupts pins. I made some changes last night to the library again.

Title: Re: Rotary Encoder Drift??
Post by roypardi on 08/24/07 at 14:01:14
Is there a tech reason that the Encoder lib can use only 4 of the interrupt pins? (just curious).

Title: Re: Rotary Encoder Drift??
Post by barragan on 08/25/07 at 21:38:56
Yes, there are only 8 external interrupts pins, and a few timers so if we use all of them for a library then people might have trouble having simultaneous applications requiring the interrupts or timers. (Serial, Pulses, Encoder, Servo) etc.

Wiring Forum » Powered by YaBB 2.5 AE!
YaBB Forum Software © 2000-2010. All Rights Reserved.