Hello,

I have the following subroutine which reads a 2bit gray code rotary encoder.
This encoder has also a push button I need to use for other functions.
The idea is to built a menu system to change some settings for my project
and I thought that a rotary encoder is ideal for that.

I press the button, I get in the menu, I rotate the encoder to select a value and
then I press the button again to go to next setting, etc...

I have searched the forum and I got some ideas how to make the rotary encoder work,
and I ended with the following code which is fine for my setup.

My problem is that I use the following code as a subroutine and I call this from many
places in my program.

Maybe it's something simple but I cannot think of something right now.
If you look at the code and comments, I want to get out of the loop when the button is pressed
to go the next menu, but since I'm in a subroutine I cannot use a GOTO, which would be
fine if it wasn't an overflow and PIC reset.

The need for the loop is to read the ports for any change, if the rotary encoder has moved and
wait if the there is no movement.

So, do you have any ideas how I can get out of this loop ?


Code:
' Rotary encoder is connected to B4 and B5, pull ups enabled.
' OLDR and NEWR are variables holding the states of ports B4 and B5
' LERI is a variable used to determine CW or CCW rotary encoder movement.
'
ROTARY:
'
PAUSE 15                                             ' Needed for smooth rotary encoder operation 
OLDR = PORTB & $30                           ' Mask other and get only Ports B4 and B5
GOSUB ROTARY1
RETURN
'
ROTARY1:
'
NEWR = PORTB & $30                              ' Mask other ports and get only B4 and B5

' IF BUT = 0 THEN GOTO MENU2               ' This is the wrong way to get out, overflow error !!!
' I need to get out of this loop when the button is pressed !!!
 
IF NEWR = $30 THEN ROTARY1                ' Same value - no movement (need to eliminate this)
LERI.0 = OLDR.4 ^ NEWR.5                     ' XOR old with new (need to find a simpler way)
LERI.1 = OLDR.5 ^ NEWR.4                     ' XOR old with new (need to find a simpler way)
ON LERI GOSUB CLCD, CCW, CW              ' Using CLCD as dummy label for index #0 - CCW=1, CW=2
RETURN
'
CCW:                                                     ' Left turn CounterCLockWise
'
X = X - 1
RETURN
'
CW:                                                       ' Right Turn ClockWise
'
X = X + 1
RETURN
'