Home \ Help \ Search \ Login RSS

Welcome, Guest. Please Login

This forum is now READ-ONLY! Please visit http://forum.wiring.co/ for the new forum.

Wiring ForumWiring HardwareTangible computing › Rotary Encoder Drift??

Page Index Toggle Pages: 1
Rotary Encoder Drift?? (Read 17904 times)
08/17/07 at 18:30:35

roypardi   Offline
Junior Member
I Love YaBB 2!
Boston USA

Posts: 57
**
 
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)


[b]The encoder:[/b]
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);
  }
}[/code]
 
IP Logged
 
Reply #1 - 08/18/07 at 21:50:06

Alan_Kilian   Offline
Full Member
Wiring? It looks like
Java to me.

Posts: 118
***
 
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.
 
IP Logged
 
Reply #2 - 08/20/07 at 20:48:53

roypardi   Offline
Junior Member
I Love YaBB 2!
Boston USA

Posts: 57
**
 
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
 
IP Logged
 
Reply #3 - 08/22/07 at 00:55:10

Alan_Kilian   Offline
Full Member
Wiring? It looks like
Java to me.

Posts: 118
***
 
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.
 
IP Logged
 
Reply #4 - 08/22/07 at 06:59:52

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
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.
 
IP Logged
 
Reply #5 - 08/22/07 at 18:15:27

roypardi   Offline
Junior Member
I Love YaBB 2!
Boston USA

Posts: 57
**
 
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... Wink
 
IP Logged
 
Reply #6 - 08/23/07 at 02:34:10

Alan_Kilian   Offline
Full Member
Wiring? It looks like
Java to me.

Posts: 118
***
 
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)
 
IP Logged
 
Reply #7 - 08/23/07 at 14:10:56

roypardi   Offline
Junior Member
I Love YaBB 2!
Boston USA

Posts: 57
**
 
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
 
IP Logged
 
Reply #8 - 08/23/07 at 17:05:04

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
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.
 
IP Logged
 
Reply #9 - 08/24/07 at 14:01:14

roypardi   Offline
Junior Member
I Love YaBB 2!
Boston USA

Posts: 57
**
 
Is there a tech reason that the Encoder lib can use only 4 of the interrupt pins? (just curious).
 
IP Logged
 
Reply #10 - 08/25/07 at 21:38:56

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
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.
 
IP Logged
 
Page Index Toggle Pages: 1