Listing 1— Now you can read Grayhill rotary encoders using a PC8574 I/O expander. The code was written for BASCOM-AVR
because it supports the I2C protocol in software.
Dim Param As Byte
Dim Param2 As Byte
Dim Encoder As Byte
Dim Enctemp As Byte
Dim Letemp As Byte
Dim Lastencoder As Byte
Dim Paramflag As Byte
Declare Sub Pcf8574write(byval Value As Byte)
Const Pcf8574w = 64 //Define I2C addresses for PCF8574
Const Pcf8574r = 65
Const True = 1
Const False = 0
//Configure the software I2C port to use ports C2 and C3
Config Sda = Portc.3
Config Scl = Portc.2
Reset Ddrd.3 //Configure INT1 line as an input
Set Portd.3 //Set weak pull-up on INT1
Mcucr = 8 //Set INT1 for falling-edge interrupt
On Int1 Frontpanel //Define INT1 interrupt vector
Enable Int1
Enable Interrupts
Call Pcf8574write(255) //Make all PCF8574 lines as inputs
//Sample code—constant check/display both rotary encoder values
Param = 0
Param2 = 0
Do
If Paramflag = True Then
Print Param
Print Param2
Paramflag = False
End If
Loop
Sub Pcf8574write(byval Value As Byte)
I2cstart //Start condition
I2cwbyte Pcf8574w //I2C address
I2cwbyte Value //Write data
I2cstop //Stop condition
Return
End Sub
//ISR to handle PCF8574 interrupts (Rotary encoders/switches)
Frontpanel:
I2cstart //Generate start
I2cwbyte Pcf8574r //I2C address
I2crbyte Enctemp , Nack //Read byte
I2cstop //Generate stop
//Do encoder 1
Encoder = Enctemp And 3
Shift Encoder , Left , 2
Letemp = Lastencoder And 3
Encoder = Encoder + Letemp
Letemp = Lookup(encoder , Relookup)
If Letemp <> 0 Then
Param = Param + Letemp
Paramflag = True
End If
//Do encoder 2
Encoder = Enctemp And 12
Letemp = Lastencoder And 12
Shift Letemp , Right , 2
Encoder = Encoder + Letemp
Letemp = Lookup(encoder , Relookup)
If Letemp <> 0 Then
Param2 = Param2 + Letemp
Paramflag = True
End If
Lastencoder = Enctemp
//Add code to read switches here
Return
End
Relookup:
Data 0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0