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