Quadrature encoder

    Aug 30 2011 | 7:58 am
    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:
    Any help would be appreciated ! Thanks. Ad

    • Sep 02 2011 | 9:34 am
      Anyone ? _
    • Sep 02 2011 | 12:06 pm
      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?
    • Sep 02 2011 | 1:00 pm
      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:
    • Sep 02 2011 | 2:11 pm
      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:
    • Sep 02 2011 | 4:57 pm
      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?
    • Sep 02 2011 | 9:08 pm
      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! __
    • Sep 03 2011 | 2:10 am
      You're right! :-)
      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.
    • Sep 04 2011 | 5:40 pm
      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< 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,