Quadrature encoder

Aug 30, 2011 at 7:58am

Quadrature encoder

Hi
I want to track the speed and the direction of rotation of a wheel.
I use a rotary optical encoder which outputs 2 signals on phase quadrature. (see the doc).

I have a lot of errors of the direction when the speed is high.
Here’s my code to detect the clock-wise and anti-clockwise rotation:

– Pasted Max Patch, click to expand. –

Any help would be appreciated !
Thanks.
Ad

[attachment=169953,2584]

Attachments:
  1. QuadratureEncoder.png
#58685
Sep 2, 2011 at 9:34am

Anyone ?
_

#210998
Sep 2, 2011 at 12:06pm

I built a bicycle-controlled game of “Pong” using reed switches and spoke magnets, and found that I had to set the gearing of the bike such that the wheel rotated quite slowly.

I have no experience with the encoders you describe, but it looks like they operate on the same principle as my out-of-phase reed switch setup. I suspect that either the frequency at which you poll your inputs may be too low for the speed of rotation you need to track. If you’re unable to gain more precision that way, then perhaps you could “gear down” the wheel, and use a second (slower-rotating) wheel to drive the encoders?

#210999
Sep 2, 2011 at 1:00pm

Hi Ad,
Encoders need very high sampling rates to work properly. A typical encoder can easily have around 100 ppr (pulses per revolution). What kind of signal converter are you using to sample the encoders into max? If you’re using anything like an arduino you might even find that it is to slow. A good alternative is finding a decent quadrature decoder IC like the ones from Avago or US Digital:

http://www.avagotech.com/pages/en/motion_control_encoder_products/integrated_circuits/decoder_ic/

http://usdigital.com/products/interfaces/ics

#211000
Sep 2, 2011 at 2:11pm

Thx you for your respnonses.
I use arduino Duemilanove yes. A 16MhZ process should do the trick no ?

Has anyone experienced this ?

Here’s the encoder I use:

http://fr.farnell.com/bourns/ena1j-b28-l00128l/encodeur-optique/dp/9358242?Ntt=ENA1J-B28-L00128L

__

#211001
Sep 2, 2011 at 4:57pm

I’ve successfully read an encoder on the Arduino, but it only really worked when the encoder was going into the Arduino interrupts, and the Arduino was detecting/accumulating the direction.

What sort of code is running on the Arduino?

#211002
Sep 2, 2011 at 9:08pm

I use sarcduino so it’s a simple digital read wich communicates with max.
Would you have some code samples ? I suppose I would need to make the treatment in the arduino environement and then sends values into max ? Am I right ?
Thx you!
__

#211003
Sep 3, 2011 at 2:10am

You’re right! :-)

There are several examples at:

http://www.arduino.cc/playground/Main/RotaryEncoders

I got satisfactory results from a mix of several of those techniques. Still, like Chris mentioned, you’ll need to use pin interrupts. Most arduinos only have two interrupts, which mean you’ll only be able to use one encoder (one interrupt per encoder channel). The exception is the Mega, which has 6 native interrupts.
You can go around these limitations by addressing pins directly and using bit shifting but that’s way more advanced.

#211004
Sep 4, 2011 at 5:40pm

Hi !
I use this code but I don’t know what to do with the result:
It doesn’t count actually…

Ivan, I didn’t use the main rotary encoders code because they turn on the PULLUPS, and I think my bourns encoder doesn’t like it !

uint8_t encoder_A = 2;
uint8_t encoder_B = 3;
// Make sure that you declare it as volatile to avoid any memory corruption
volatile long int count = 0;
volatile uint8_t sstatus = 0;
void encoder_counter()
{
sstatus=1;
sstatus|=digitalRead(encoder_A);
sstatus< <=1;
sstatus|=digitalRead(encoder_B);
// four bit status
int fbs=sstatus&15;
if (fbs==2||fbs==4||fbs==11||fbs==13)
{
++count;
}
else
{
–count;
}
}

void setup()
{ Serial.begin(9600);

pinMode(encoder_A, INPUT);
pinMode(encoder_B, INPUT);
// pin 2 corresponds to interrupt 0 as per arduino
attachInterrupt (0, encoder_counter, CHANGE);
// pin 3 corresponds to interrupt 1 as per arduino
attachInterrupt (1, encoder_counter, CHANGE);
}

void loop()
{
Serial.println(count, DEC);
}

What do you think of that code ?
Thx,

#211005

You must be logged in to reply to this topic.