/* Quadrature encoder for the Orangutan, ATmega168 This code assumes that the A and B outputs of a quadrature encoder is connected to PORTC, pins 4&5 If the decoded direction is incorrect, swap the A&B terminals or change the logic of the interrupt service routine accordingly The algorithm is from Scott Edwards, in Nuts&Volts Vol 1 Oct. 1995 (Basic Stamp #8) and is described in an article available on line at http://www.parallax.com/dl/docs/cols/nv/vol1/col/nv8.pdf Interrupts are required to avoid missing encoder states. However, if skipped states is not a problem (e.g a volume control), the decoding can take place in the main routine. */ #include #include #include //global variables: encoder position and direction of rotation unsigned int enc_pos; unsigned char enc_dir; /* PORTC Pin change interrupt service routine. Decodes the encoder. For algorithm, see Scott Edwards article from Nuts&Volts V1 Oct. 1995 nv8.pdf (righthand bit of old A,B) xor (lefthand bit of new A,B) => dir. Increment or decrement encoder position accordingly */ ISR (PCINT1_vect) { static unsigned char enc_last=0,enc_now; enc_now = (PINC & (3<<4))>>4; //read the port pins and shift result to bottom bits enc_dir = (enc_last & 1)^((enc_now & 2) >> 1); //determine direction of rotation if(enc_dir==0) enc_pos++; else enc_pos--; //update encoder position enc_last=enc_now; //remember last state } #include "lcd.c" int main(void) { unsigned char buf[8]; enc_pos=0; //Initialize encoder position LCDInit(); //Initialize LCD display DDRC &=~(3<<4); //Port C pins 4 and 5 as input PCMSK1 |= (3<