Using a rotary encoder with Arduino or ATTiny85

A rotary encoder switch is a great input device that you can use to detect rotation left or right and button pressing. They are perfect for Arduino based projects as they are readily available on eBay for a couple of quid, and allow simple input.

Rotary encoder used with ATTiny85
LED Driver with rotary encoder

I have been using these rotary switches in many small projects with the ATTiny85 device programmed with the Arduino environment.

Here is a simple 12v LED driver using the rotation of the rotary encoder to control the brightness, and the switch to turn the LED’s on and off.

Rotary Encoder output

Rotary Encoder Waveform
Rotary Encoder Waveform

Each rotation generates pulses that can be a challenge to detect correctly, this is a  typical waveform generated by rotation

There are plenty of articles on the web that suggest the best way to read the rotation, but many of them are flawed. I am using the Pin Change Interrupt feature of the ATTiny85 device, this would also work with other ATMEL devices as used on the Arduino boards.

The simplest and best way to read a rotary encoder

Rotary encoder and ATTiny85 Circuit diagram
Rotary encoder with ATTiny85 circuit

To show clearly how this works I have drawn a simplified circuit diagram, and also removed unnecessary  elements from the code. This could then be the basis for any project that uses a rotary encoder.

Using a couple of 100nf capacitors to arrest the switch bounce noise, the channel A and channel B of the rotary encoder are connected to PB3 and PB4, these have interrupt change enabled.

I have also connected the switch to PB2. Although I have removed code that does anything with the switch, it is possible to use PB2 to wake the device from sleep with an external interrupt setting. This is great if you are making a low power project that sets the device to sleep to save energy.

The Code

Here is the fastest and cleanest code that reads all the edges of the waveform in either direction: