Wednesday, 5 July 2006.

Rotary encoder

Using a rotary encoder is really easy once you understand the principle of operation. I found a lot of code snippets on the net, about how to connect a rotary encoder to an AVR (or any other microcontroller indeed). Some of them did not work out for me because they required an interrupt pin. Others did not work at all. Here is the code, which actually did work out. One of the nice things about it is that it does not require any interrupts, so one can use just about any two free pins, and a timer.


+---+       +------
| A |-------| PC0
|   |       |
| B |-------| PC1
+---+       |
  |         |
 GND


static volatile int8_t enc_delta;

ISR(TIMER0_OVF_vect) { static uint8_t last_state = 0,last_cnt = 0; uint8_t new_state;

new_state=PINC & (_BV(PINC1) | _BV(PINC0)); if ((new_state^last_cnt)==(_BV(PINC1) | _BV(PINC0)) ) { if ((new_state ^ last_state)==_BV(PINC1)) { enc_delta += 1; } else { enc_delta -= 1; }

last_cnt=new_state; }

last_state=new_state; }

void rotary_init() { /* Switch the internal pull-ups on port C on */ PORTC |= (_BV(PC0)|_BV(PC1)); /* PC0 and PC1 are inputs */ DDRC &= ~(_BV(DDC0) | _BV(DDC1)); /* sample the inputs with clk/8 */ TCCR0 = _BV(CS01); /* enable the overflow irq in order to sample the inputs */ TIMSK |= _BV(TOIE0); }


The code is taken from a post by Christian Kranz on www.mikrocontroller.net.

Posted by k155la3 | Permalink | Your comment