Rotary Encoding

For an upcoming project we want to use rotary encoding with optical sensors, so I did a bit of hacking testing today…

I’m using two photo interrupters mounted on breakout boards with 220 ohm resistors.

For an encoding disk I searched for a suitable SVG file and found this blog post, which just happened to have a link to a perl script (of course!) to generate encoding disks. A little Inkscape magic and I printed out a disk to test with.

I should note that my original plan was to use the Silhouette Cameo to cut the slots in the disk, but the paper version actually worked fine for testing. In the final piece we’ll probably use a piece of laser-cut acrylic.

With my encoding disk ready I hot glued it to a bolt and chucked it in the drill. This gave me an easy way to vary the speed and direction.

Rotary Encoding

I grabbed the Encoder_Polling library and used the counter example and that was about it. I could now see if the disk was spinning and in which direction (by looking at the numbers increase or decrease.)

I really thought I’d need to mount the photo interrupters more precisely, but I pretty much left them hanging in mid-air supported by wires on a breadboard and it worked fine. (Maybe I just got lucky?) There’s a lot more code to write, but this was a good start.

Oh, if you want to learn way too much about reading rotary encoders with an Arduino, visit the Reading Rotary Encoders page and set aside a few hours…

Note: I also found an online encoder wheel generator.

5 Responses to “Rotary Encoding”

  1. gregNo Gravatar says:

    hey I am needing to do the same thing. Did you have to change anything with the encoder polling library?

    When I try to compile the sketch on a arduino leonardo I get the following. Any ideas? What arduino were you using?

    Build options changed, rebuilding all
    Counter.cpp.o: In function `setup’:
    /Arduino/Counter.ino:12: undefined reference to `encoder_begin(unsigned char, unsigned char)’
    Counter.cpp.o: In function `loop’:
    /Arduino/Counter.ino:17: undefined reference to `encoder_data()’
    collect2: error: ld returned 1 exit status
    Error compiling.

  2. Hmmm, I used an Arduino Mega. Did you install the library properly?

  3. gregNo Gravatar says:

    Yeah, it’s a weird thing. Maybe I am doing it wrong. I re-installed the Arduino software and everything compiled fine. Then when I choose my board, Leonardo, it gives me a bunch of errors. I’ll just keep messing with it. I also saw errors about “encoder” being defined twice.

    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp: In function ‘void encoder_begin(uint8_t, uint8_t)’:
    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp:62: error: ‘TCCR2A’ was not declared in this scope
    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp:63: error: ‘TCCR2B’ was not declared in this scope
    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp:65: error: ‘TCNT2′ was not declared in this scope
    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp:66: error: ‘OCR2A’ was not declared in this scope
    \Arduino\libraries\Encoder_Polling\Encoder_Polling.cpp:67: error: ‘WGM21′ was not declared in this scope


  4. gregNo Gravatar says:


    Turns out the Leonardo has different interrupt names. TCCR0A rather than TCCR2A and so on.


  5. Good to know, greg. Thanks for the note!

« | »

buy the button:

Buy The Button