Here I post an update of the code posted in #18. This new code has a more efficient ISR so it can read at higher frequency. I don't know the maximum frequency that the system can acheive, so if someone with some spare time will give a try and post the result, could be useful.

As the previuos code, the mainloop doesn't do much, it simply update the display.

Here the code revised:
Code:
' PicBasic program to demonstrate how to read an optical encoder
' in quadrature. The code uses a 2 lines LCD in 4-bits mode 
'                 **** MCU USED: PIC 16F628 ***
'
' ------------------ LCD should be connected as follows -------------------
'       LCD     PIC Port
'       ---     --------
'       DB4     PortA.0
'       DB5     PortA.1
'       DB6     PortA.2
'       DB7     PortA.3
'       RS      PortA.4 (add 4.7K pullup resistor to 5 volts)
'       E       PortB.0
'       RW      Ground
'       Vdd     5 volts
'       Vss     Ground
'       Vo      20K potentiometer (or ground)
'       DB0-3   No connected

'-------------------------------------------------------------------------
' Encoder channel A     PortB.6  (use pullups resistor if necessary)
' Encoder channel B     PortB.7  (use pullups resistor if necessary)
' N/U                   PortB.0  (output)
' N/U                   PortB.1  (output)
' N/U                   PortB.2  (output)
' N/U                   PortB.3  (output)
' N/U                   PortB.4  (input - to be grounded)
' N/U                   PortB.5  (input - to be grounded)
'
'-------------------------------------------------------------------------

INCLUDE "DT_INTS-14.bas"    ' Base Interrupt System  (by Darrel Taylor)

DEFINE OSC 20

eeprom 0,[2,0,3,1,1,3,0,2]

Define LCD_DREG PORTA
Define LCD_DBIT 0
Define LCD_RSREG PORTA
define LCD_RSBIT 4
define LCD_EREG PORTB
define LCD_EBIT 0
define LCD_BITS 4
define LCD_LINES 2
define LCD_COMMANDUS 2000
define LCD_DATAUS 50

CMCON = %00000111
TrisA = %00000000
TrisB = %11110000
PortB = 0

Flag                var bit
wsave               VAR BYTE    $70     SYSTEM  ' alternate save location for W 
Q_New               var Byte
Q_Old               var byte
M_Count             var byte [4]
P_Count             var byte [4]
Q_Count             var word

' ---------------------- Set variable value @ startup ----------------------  
     
For Q_Old = 0 to 3
Read Q_Old,M_Count[Q_Old]
Read Q_Old + 4,P_Count[Q_Old]
Next Q_Old
     
  Q_Count = 0   
    Q_New = 0
    Q_Old = 0
     Flag = 0  
      
ASM
INT_LIST  macro    ; IntSource,        Label,  Type,  Resetflag?                
        INT_Handler    RBC_INT,  _Encoder,   ASM,  yes       
    endm
    INT_CREATE                   ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RBC_INT            ; enable external (INT) interrupts

'---------------------------- Initialize LCD ----------------------------

Lcdout $fe, 1                               ' Clear LCD screen
Lcdout "System Ready"                       ' Display message
Pause 500                                   ' Wait .5 second

Goto Main_Loop

Encoder:                                    ' ISR 

Q_New = PortB.7 + PortB.7 + PortB.6         ' get port status
 
If M_Count[Q_Old] = Q_New then              ' if M_Count code satisfied then minus
          Q_Count = Q_Count - 1
             Flag = 1                       ' set flag to true to update display
goto Q_Skip
endif

If P_Count[Q_Old] = Q_New then              ' if M_Count code satisfied then plus
          Q_Count = Q_Count + 1
             Flag = 1                       ' set flag to true to update display
endif

Q_Skip:

Q_Old = Q_New                               ' update Q_Old Byte
 
@ INT_RETURN

Main_Loop:   

if Flag = 1 then
Lcdout $fe, 1                              ' Clear LCD screen
lcdout dec Q_Count                         ' Display encoder position (counts)
Flag = 0                                   ' reset flag to false, display updated
endif

goto Main_Loop

end
Cheers

Al.