Not the best programming techniques but uses interrupts and is fast enough for x4 encoders like ALPS with push switch used to reset the position counter.
Based on Henrik's example and tested on 16F886.
Code:
intcon=%10001000
iocb=7
Encoder VAR BYTE
Old_Enc VAR BYTE
Test VAR BYTE
Dir VAR WORD ' Must be same size as Position variable
position var word
ch_a var portb.0
ch_b var portb.1
detent var byte
flag var bit
clear
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
wsave var byte $70 system
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _rotary, PBP, yes
endm
INT_CREATE
ENDASM
@ INT_ENABLE RBC_INT ; Enable PortB.0 interrupt for signal reception
goto main
rotary:
'-------------------------------------------------------------
'--------------Poll encoder and keep count -------------------
'-------------Alternative routine with 4x decoding------------
'-------------------------------------------------------------
Encoder.0 = Ch_A
Encoder.1 = Ch_B
Test = Encoder ^ Old_Enc
Dir = 0
If Test = 1 THEN
If Old_Enc = 0 THEN Dir = 1
IF Old_Enc = 1 THEN DIR = -1
IF Old_Enc = 2 THEN Dir = -1
If Old_Enc = 3 Then Dir = 1
ENDIF
IF Test = 2 THEN
IF Old_Enc = 0 THEN DIR = -1
IF Old_Enc = 1 THEN Dir = 1
IF Old_Enc = 2 THEN Dir = 1
IF Old_Enc = 3 THEN Dir = -1
ENDIF
if !portb.2 then 'Reset counter
position=0
flag=1
endif
if Old_Enc <> Encoder then
Old_Enc = Encoder
detent=detent+1 'Increment position after 4 pulses (one detent on ALPS encoder)
if detent = 4 then
Position = Position + Dir
detent=0
flag=1
endif
endif
@ INT_RETURN
main:
while 1
if flag then
hserout [#position,13,10]
flag=0
endif
'other code stuff here
wend
END
Ioannis
Bookmarks