Hi Folks,

I'm trying to get my head around what is happening with my attempt at using a Rotary Encoder... it is functional however something weird is happening periodically returning from the interrupt.

My "I'm Alive" serial string is returned to and finds itself sprinkled among the debug terminal data. I'm sure it is staring at me but I can't see why. Any help appreciated.

Thanks,
Bill

PS
@ richard
I persisted for hours trying your method (with appropriate pin changes) and had no joy so went with the Old vs New method. It would only count in one direction with either CW or CCW.

Code:

'****************************************************************************************************
'*  Name    : RE test WJS.pbp                                                                       *                                      
'*  Author  : WJ Sherwood                                                                           *
'*  Notice  : Copyright (c) 2021  	                                                                *
'*          : All Rights Reserved                                                                   *
'*  Date    : 07/02/21                                                                              *
'*  Device  : 16F1788                                                                               *
'*  Version : 1    (PBP 3.0.10.4)                                                                   *
'*  Notes   : Spurious "I'm Alive" serial traffic following RE action - what am I missing?          *
'*          : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low.                     *
'*          : 											                                            *
'****************************************************************************************************
'

'=========================================================================================================
'        CONFIGURE DEVICE 
'=========================================================================================================
#CONFIG ; 16F1788.
        __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON &  _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF
#ENDCONFIG

' -----[ Initialization ]------------------------------------------------------------------------------------------------ 
    TRISA = %00000000       ' Set I/O.
    TRISB = %01111111       ' Set I/O.
    TRISC = %00000000       ' Set I/O.

define  OSC  4
        OSCCON = %01101010   ' 4Mhz (F1788).
'define  OSC  32
'        OSCCON = %11110000   ; 32 MHz, 

    ANSELA = 0           ; all digital          
    ANSELB = 0           ; all digital 

' Define LCD connections       
    DEFINE  LCD_DREG        PORTA	' LCD Data Port
    DEFINE  LCD_DBIT        0		' Starting Data Bit
    DEFINE  LCD_RSREG       PORTA	' Register Select Port
    DEFINE  LCD_RSBIT       4		' Register Select Bit
    DEFINE  LCD_EREG        PORTA	' Enable Port
    DEFINE  LCD_EBIT        7		' Enable Bit
    DEFINE  LCD_BITS		4		' Data Bus Size
    DEFINE  LCD_LINES		2		' Number of Lines on LCD

'=========================================================================================================
'        PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'=========================================================================================================
' Rotary Encoder stuff
Old_Bits    VAR BYTE bank0  ' Encoder port bits before change.
New_Bits    VAR BYTE bank0  ' Encoder port bits after change.
RotEnc1_val VAR word bank0  ' Connected to PORTB<5:6>.
MaxLimit    var word bank0  ' Used for setting upper limit for encoder counts.
RotEncDir   VAR BIT  bank0  ' Direction of rotation bit.
ButtPush    var bit  bank0  ' Flag shows button was pushed, allows quick exit from Int handler.

                    
    Include "MODEDEFS.BAS"      ' Include Shiftin/out modes.
    INCLUDE "DT_INTS-14.bas"    ' Needs to be assembled with MPASM **********
    INCLUDE "ReEnterPBP.bas"    ; Include if using PBP interrupts	

    OPTION_REG.6 = 0        ' INTEDG set to interrupt on falling edge.
'    OPTION_REG.6 = 1        ' INTEDG set to interrupt on rising edge.

'   IOCBP = %01110000        ; REa portb.6, REb portb.5  pos edge trigger
   IOCBN = %01110000        ; REa portb.6, REb portb.5, REsw portb.4  neg edge trigger - falling edge only.
   IOCBF = 0                ; Reset the PortB flag.
   INTCON = %11001000       ; GIE, PEIE, IOCIE.
   
'    RotEnc1_val = 0         '
    pause 500               ' Let everything settle...

'latc.6 = 0                  ' Prevent garbled serial - newer PICs, true.        
latc.6 = 1                  ' Prevent garbled serial - newer PICs, inverted.        
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

ASM
INT_LIST  macro    ; IntSource,         Label,  Type, ResetFlag?
        INT_Handler    IOC_INT,  _Rot_Encoder,   PBP,  yes  ; Newer PICs.
    endm
    INT_CREATE              ; Creates the interrupt processor .
ENDASM

@    INT_ENABLE   IOC_INT   ; Newer PICs.
Old_Bits = PORTB & (%01100000)  ; RE uses B.6,B.5 - REa and REb.
'Old_Bits = PORTB & (%01110000)  ; RE uses B.6,B.5,B.4 - includes RE push button.


Main:   
goto main                       ' endless loop waiting for INT. 


   
'---[IOC - interrupt handler]---------------------------------------------------
Rot_Encoder:
    if PortB.4 = 0 then             ' Check if Encoder pushbutton was pushed.
serout2 PORTC.6,16468,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
    ButtPush = 1                    ' Set the flag for a quick exit.
goto DoneRotEnc                     ' Clean up and exit.
    endif

' Don't forget 4 counts per detent (Quadrature).
     New_Bits = PORTB & (%01110000)         ' Set port bits for Encoder's chosen A and B channels.
     IF (New_Bits & %01110000) = (Old_Bits & %01110000) then DoneRotEnc ' No change.
     RotEncDir = New_Bits.6 ^ Old_Bits.5    ' Bit XOR compare to get direction of rotation.
     if RotEncDir = 0 then                  ' CCW so decrement.
        if PORTB.6 and PORTB.5 = 1 then     ' Only when RE both pins high (convert quad counts to singles).
        RotEnc1_val = RotEnc1_val - 1       ' Decrement the count.
          if RotEnc1_val => 65530 then RotEnc1_val = 0  ' Limit the max.
          if RotEnc1_val <= 4 then RotEnc1_val = 0      ' Limit the min.
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
        endif
     ELSE           ' RotEncDir = 1, CW so increment.
        if PORTB.6 and PORTB.5 = 1 then     ' Only when RE both pins high (convert quad counts to singles).
          RotEnc1_val = RotEnc1_val + 1     ' Increment the count.
          if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
        endif
     ENDIF


DoneRotEnc:
     Old_Bits = New_Bits
    INTCON.0 = 0        ; Clean up and exit - clear IOCIF.
    IOCBF = 0           ; Reset the flag.
@ INT_RETURN

end