circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

Issue 152 March 2003
Using Rotary Encoders as Input Devices


PROGRAM CODE

Let’s look at the code needed to read the Grayhill 2-bit Gray code encoders (see Listing 1). The code was written in BASCOM-AVR and should run on any AVR microcontroller. To make matters easier, BASCOM-AVR has built-in I2C routines. The early statements in the program Config sda and config scl define the port lines used for the I2C bus. There are various statements needed to configure the INT1 line as an input, enable weak pull-ups on this line, and configure INT1 for falling-edge interrupt response. The PCF8574 is then set so that all of its lines are inputs by writing all ones to it.

The INT1 ISR, labeled Frontpanel in this case, handles the actual reading of the encoders. When an encoder position changes and causes an interrupt to occur, the first chore is to read the PCF8574’s 8-bit input latch. The two bits corresponding to the first encoder are selected using the AND function. This value is concatenated with the prior 2-bit value to form a 4-bit nibble. Of the 16 possible values of this 4-bit nibble, only eight of them are valid. The other eight result from cases in which the current encoder value is the same as the prior encoder value, in which case the ISR routine isn’t called because a change didn’t occur.

This 4-bit value is then fed to the BASIC Lookup function. This function returns a number by looking up a value from a 16-entry table, using the original 4-bit value as an index into that table. If you look at the table (labeled Relookup), you’ll see four positive ones and four negative ones corresponding to the eight possible transitions of the encoder outputs. There are eight zeros in the table that correspond to the eight cases in which the encoder hadn’t changed position. Strictly speaking, the latter eight entries will never be used, but they’re necessary as placeholders in the table.

After the look-up process, either a positive one or a negative one is added to the variable representing the position of the encoder shaft. This variable will generally represent some parameter in the actual program itself (i.e., it’s seldom ever used to represent the actual position of the encoder’s shaft itself). The second encoder is read in the same fashion, using different bits from the PCF8574’s input port. Additional code can be added to the ISR to handle various other switches that might be connected to the PCF8574. For this example, the main program just sits in a loop and prints the encoder values when they change.

The code for the Bourns ECW1J-B24-BC0024 encoders isn’t shown here, but you may download it from Circuit Cellar’s ftp site along with the rest of the code. The Bourns signal output is not as perfect a match to the PCF8574’s architecture as the Grayhill unit, but it still works with some modifications to the code.

If you’re like me, then you’re probably always running out of I/O lines on your favorite microcontroller before your projects are finished. Using the PCF8574 to handle your rotary encoder/panel switch interfacing will help to alleviate this problem.