Sunday, September 19, 2010

Determining Encoder Rotational Direction Using An ATMEGA168


While working on a DC motor controller project I needed to decode quadrature encoder signals.

Basically a quadrature encoder has two signal lines, A and B. Rotational direction of the encoder can be determined by the phase difference between these signals. 

A simple way to detect the phase difference of the signals with the ATMEGA168 is to generate an interrupt on the falling edge of signal A and look at the value of signal B. If signal B is high of the falling edge of signal A the encoder is turning one way. And if signal B is low on the falling edge of signal A the encoder is turning the other way.


In order to setup up the input pins and the external interrupt the ATMEGA168's registers need to be configured as follows:

Set data direction as input and enable internal pullups
The two signal lines from my encoder are connected to PD2 and PD3, Pins 4 and 5 on the ATMEGA168. These pins need to be set as input in The Port D Data Direction Register, DDRD, and their internal pullups need to be enabled in the The Port D Data Register, PORTD.
DDRD |= (1 << PD2)      PORTD |= (1 << PD2)
DDRD |= (1 << PD3)      PORTD |= (1 << PD3)

Set interrupt to generate on falling edge of signal
I want the interrupt to trigger on the falling edge of encoder signal A. External Interrupt Control Register A , EICRA, is used to set the external interrupt sense control.
EICRA |= (1 << ISC01)

Enable the external interrupt
Lastly the external interrupt needs to be enabled. This is done in the External Interrupt Mask Register, EIMSK.
EIMSK |= (1 << INT0)

No comments:

Post a Comment