Recently I was working on a project that involved rotary encoder. I thought I’d share some thoughts on how rotary encoder can be interfaced and programmed. Actually it is easy to work with rotary encoders – interfacing is simple – only three wires are required to connect to microcontroller (two for signal (quadrature outputs) and one for reference (GND)). When turned there is a Grey code produced on outputs that allows tracking turn speed and direction. These features allow having convenient user interface with single knob. Many rotary encoders also comes with button – so menu navigation couldn’t be easier. In our project we are going to use a 12-step mechanical rotary encoder from sparkfun.
We are going to interface it to ATMega32 board with graphical LCD.
You can find many projects in internet where one of rotary encoder pins is connecter to microcontroller interrupt pin. This enables easier detection of encoder turn. Using endless loop isn’t recommended because it occupies lots of MCU resources and is inefficient. Another logical solution is to use Timer that periodically generates interrupts so it could check if rotary encoder have been turned or button have been pressed. Lets stick with timer option as it allows connecting encoder to any available microcontroller pins. Encoder is connected to Atmega32 as follows:
Encoder A pin to atmega32 pin B2; encoder pin B to MCU pin B3 and button to pin B4. We are going to use atemga32 internal pull-ups on these pins, so other encoder pins have to be connected to ground.
Lets write simple library for reading rotary encoder. This will make code more reusable and modular. To do so we create two empty files rotary.c and rotary.h. In rotary.h we define our port pins and library function prototypes:
//define port where encoder is connected
#define ROTPORT PORTB
#define ROTDDR DDRB
#define ROTPIN PINB
//define rotary encoder pins
#define ROTPA PB2
#define ROTPB PB3
#define ROTPBUTTON PB4
//define macros to check status
#define ROTA !((1<<ROTPA)&ROTPIN)
#define ROTB !((1<<ROTPB)&ROTPIN)
#define ROTCLICK !((1<<ROTPBUTTON)&ROTPIN)
In library source file we declare following functions. First of all initialize pins where rotary encoder is connected:
For more detail: Interfacing rotary encoder to Atmega32
This free embedded project also found using:
- atmel rotary encoder
- rotary puls encoder