G'day forum people

I have a small problem getting a dual encoder from ALPS to work, it is the type that when you go right, both outputd rise or fall, one slightly in front of the other, depending on direction. I found some excellent code examples from the archives here but it does funny things.
The counter which increments or decrements depending on how many times you rotate seems to jump up in 2's, i.e 1000 - 1002 - 1004
I have spent 3 days trying to get it to count up in 1's ( or down ).

I am new to programming, mainly an RF hardware guy - this is probably something real simple, can anyone work it out. This is for a ham radio project that when finished I will gladly display the full code. The PLL is an LMX2306 for use on 144 Mhz.

Hope its O.K to post a long post, cheers from Queensland, Australia

Code follows:

'************************************************* ***************
'* Name : 2 metre _PLL.BAS *
'* Author : [Nigel Andrews] *
'* Notice : Original encoder code based on picbasic forum *
'* Date : 12/07/2005 *
'* Version : 1.0 *
'* Notes : Attempt to write some code that outputs bits to *
'* : the LMX2306 PLL in conjunction with displayed *
'* : LCD frequency, remember to add 21.4 Mhz offset *
'* : for the receiver Intermediate Frequency *
'* : *
'************************************************* ***************


'************************************************* ***************
' *
'LCD commands *
' *
'Command Operation *
' *
'$FE, 1 Clear display *
'$FE, 2 Return home (beginning of first line) *
'$FE, $0C Cursor off *
'$FE, $0E Underline cursor on *
'$FE, $0F Blinking cursor on *
'$FE, $10 Move cursor left one position *
'$FE, $14 Move cursor right one position *
'$FE, $C0 Move cursor to beginning of second line *
'$FE, $94 Move cursor to beginning of third line *
'$FE, $D4 Move cursor to beginning of fourth line *
'$FE, $18 Shift entire line left one position *
' *
'************************************************* ***************

' DEVICE IS A 16F877 AT 4MHZ


DEFINE LOADER_USED 1 'bootloader software


clear

' Port allocations:
' Port A LCD Port
' A.0 - DB4 on LCD
' A.1 - DB5 on LCD
' A.2 - DB6 on LCD
' A.3 - DB7 on LCD
' A.4 - Register Select ( R/S )
' A.5 - Enable ( E )

' Note LCD is in 4 bit mode, R/W tied to ground ( Write only )

' Port B

' B.0 - Do not use, used by code to calculate encoder position by bit swapping
' B.1 - Do not use, used by code to calculate encoder position by bit swapping
' B.2 - B2 Encoder tied high
' B.3 - B1 Encoder tied high
' B.4 - A2 Encoder tied high (Low voltage programming - PGM )
' B.5 - A1 Encoder tied high
' B.6 - not allocated (ICSP Clock - PGC )
' B.7 - not allocated (ICSP Data - PGD )
' *Note - ICD inputs are switched from ICSP programming to encoder with a 3 pole switch

' Port C

' C.6 - RS-232 Transmit ( also used for loading program using bootloader )
' C.7 - RS-232 Receive ( also used for loading program using bootloader )



' LCD SETUP DEFINES


define LCD_DREG PORTA ' set LCD data port
DEFINE LCD_DBIT 0 ' set starting bit ( 0 or 4 ) if 4 bit bus
dEFINE LCD_RSREG PORTA ' set LCD register select port
DEFINE LCD_RSBIT 4 ' set LCD register select bit
DEFINE LCD_EREG PORTA ' set LCD enable port
DEFINE LCD_EBIT 5 ' set LCD enable bit
DEFINE LCD_BITS 4 ' set LCD bus size ( 4 or 8 bits )
DEFINE LCD_LINES 2 ' set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' set command delay time in us
DEFINE LCD_DATAUS 50 ' set data delay time in us


'encoder setup

zFlags var byte
Changed var zflags.0

OldA var byte ' Previous state of encoder A bits
NewA var byte ' Current state of encoder A bits
DirectionA var bit ' Direction of encoder A travel; 1=CCW.
zza6 var NewA.0 ' the first bit
zza15 var OldA.1 ' the second bit
PositionA var word ' To hold position count 0 to 65536

OldB var byte ' Previous state of encoder B bits
NewB var byte ' Current state of encoder B bits
DirectionB var bit ' Direction of encoder B travel; 1=CCW.
zzb6 var NewB.0 ' the first bit
zzb15 var OldB.1 ' the second bit
PositionB var word ' To hold position count 0 to 65536

true con 1
false con 0

PositionA = 1000 'initialize position A counter
PositionB = 1000 'initialize position B counter


Init:
adcon1 = 6 'set porta to digital I/O
trisa = %00000000 'set porta to outputs
trisb = %11111111 'set portb to inputs


lcdout $fe,1 ' Clear LCD
pause 1000 ' 1 second delay

lcdout $fe,$80,#DirectionA," ",#positionA 'display 0 or 1 on top line encoder A
'0 = right, 1 = left plus position count

lcdout $fe,$c0,#DirectionB," ",#positionB 'display 0 or 1 on bottom line encoder B
'0 = right, 1 = left plus position count

MainLoop:

OldA = newA
OldB = newB
Changed = false


Again:

NewA = PortB & %00110000 'copy encoder bits to NewA
NewB = PortB & %00001100 'Copy encoder bits to NewB
NewA = NewA >> 4 'shift input of PortB the first and second bit
'comment, does this mean that bits 0 and 1 cannot
'be used for other I/O usage?

NewB = NewB >> 2 'shift input of PortB the third and fourth bit
'again, does this mean that bits 0 and 1 cannot
'be used for other I/O usage?
IF NewA <> OldA Then Gosub ChangedA
IF NewB <> OldB Then Gosub ChangedB
if Changed = false then Again

lcdout $fe,1
lcdout $fe,$80,#DirectionA," ",#positionA 'display 0or1 on top line encoder A
'0 = right, 1 = left plus position count

lcdout $fe,$c0,#DirectionB," ",#positionB 'display 0or1 on bottom encoder B
'0 = right, 1 = left plus position count


Goto mainloop


'The following checks the direction and increments/decrements the counter
'note the counter goes in reverse, this is because the encoder is wired
'in reverse, final version will be corrected to line up with code

' Current BUG - counter counts by 2! cannot get it to count up by 1
' if you partially rotate the encoder it will increment up or down by 1 but this
' is not its normal operation, it appears the software does not like 2
' rising or falling edges even though one leads the other.

ChangedA:

DirectionA = zza6 ^ zza15 'XOR right bit of new w/ left bit of old.
'give 1 if the two bits are different,
'and 0 if they are the same.


IF DirectionA = 1 Then 'first bit and second bit are different

PositionA = PositionA -1 'Currently increments counter up by 2

else
PositionA = PositionA + 1 'Currently decrements counter down by 2
pause 5
endif
Changed = true
Return

ChangedB:

DirectionB = zzb6 ^ zzb15 'XOR right bit of new w/ left bit of old.
'give 1 if the two bits are different,
'and 0 if they are the same.

IF DirectionB = 1 Then
PositionB = PositionB - 1 'Currently increments counter up by 2


else
PositionB = PositionB + 1 'Currently decrements counter down by 2
pause 5
endif
Changed = true
Return


end