Proton BASIC Community

Proton (Positron) => Lounge => Topic started by: RGV250 on Jun 18, 2023, 08:43 AM

Title: Quadrature (rotary) encoder example
Post by: RGV250 on Jun 18, 2023, 08:43 AM
Hi,
I am looking at a quadrature encoder, I wondered if anyone has an example before I spend too much time looking.

Regards,
Bob
Title: Re: Quadrature (rotary) encoder example
Post by: basiclover on Jun 18, 2023, 11:57 AM
hope this help you
From Les for 18F25k22
https://protoncompiler.com/index.php/topic,290.0.html
Title: Re: Quadrature (rotary) encoder example
Post by: flosigud on Jun 18, 2023, 04:33 PM
Here is one. Uses IOC interupt and reads two encoders.
'    -------------------------------------------------------------
'    Name    : Quadrature.BAS
'    Author    : Flosi Guðmundssn
'    Notice    : Copyright (c) 2017 Flosi Guðmundsson
'            : All Rights Reserved
'    Date    : 2.4.2017
'    Version : 1.0
'    Notes    : Interrupt on Change is used to read two quadrature
'            : encoders and increment counter. Mainloop sends
'            : result serially over Bluetooth to TouchDRO app.
'    -------------------------------------------------------------
     Device 18F26K22
    Declare Xtal 80
    Symbol PLLEN = OSCTUNE.6                    ' PLL enable
    Symbol PLLRDY = OSCCON2.7                    ' PLL run status
    PLLEN=1                                        ' Enable PLL 4x 16MHz = 64Mhz
    While PLLRDY=0:Wend                            ' Wait until PLL is stable
'    Include "18f26k22intosc64.Inc"
    Declare Hserial_Baud = 115200
    Declare Reminders = Off
'    Declare Optimiser_Level 3
    Declare Dead_Code_Remove = On
   
    On_Hardware_Interrupt Interrupt_handler

    TRISA = %00000000
    TRISB = %11110011                        ' Quadrature inputs, Int0, Int1
    TRISC = %00000000

    Symbol GIE = INTCON.7                    ' Global Interrupt Enable
    Symbol PEIE = INTCON.6                    ' Periferal Interrupt Enable
    Symbol IPEN = RCON.7                    ' Interrupt Priorty Enable

    Dim wFSR1 As FSR1L.Word                    ' Used for look up table

'    Setup for Interrupt On Change for PortB 6-7
'    ----------------------------------------------------------------------------

    Symbol RBIF = INTCON.0
    Symbol RBIE = INTCON.3

'    Setup for Int0
'    ----------------------------------------------------------------------------

    Symbol INT0F = INTCON.1
    Symbol INT0IE = INTCON.4
    Symbol INTEDG0 = INTCON2.6
   
'    Setup for Int1
'    ----------------------------------------------------------------------------

    Symbol INT1F = INTCON3.0
    Symbol INT1IE = INTCON3.3
    Symbol INTEDG1 = INTCON2.5

'    PortB pullups
'    ------------------------------------------------------------------------

    Symbol NOT_RBPU = INTCON2.7
    IOCB = $F0                                 ' PortB 7-4 used
    NOT_RBPU = 0                            ' PortB pullups on

'    Enable interrupts
'    ----------------------------------------------------------------------------

    IPEN = 0                                ' Interrupt priority OFF
    GIE = 1                                    ' Global Interrupt enable
    PEIE = 1                                ' Enable peripheral enable
    INT0IE = 1                                ' Int0 Interrupt Enable
    INT1IE = 1                                ' Int1 Interrupt Enable
    RBIE = 1                                ' PortB Interrupt Enable

'
'    Look up table for incrementing or decrementing the counter   
'    and pointer to look up table
'    ----------------------------------------------------------------------------

    Dim tLookUp[16] As SByte = 0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0
    wFSR1 = VarPtr tLookUp

    Dim bNewX As Byte
    Dim bNewZ As Byte
    Dim bOldX As Byte
    Dim bOldZ As Byte

    Dim swCntX As SWord                     ' values to increment/decrement
    Dim swCntZ As SWord
    Dim sbInc As SByte                         ' value of increment,0,1,-1

'    Dim bTmp As Byte
    Dim fCntReady As Bit
   
    swCntX = 0
    swCntZ = 0

    While 1 = 1
        While fCntReady = 0 : Wend
        fCntReady = 0
        HRSOut "x",SDec swCntX,";","Z",SDec swCntZ,";",10   
    Wend

Interrupt_handler:
    Context Save
    If RBIF = 1 Then                        ' On RBIF interrupt
        RBIF = 0
        Swapf PORTB,WREG                    ' WREG 3-0 = PORTB 7-4
        bNewZ =    WREG
        bNewX = WREG & 3                    ' bNewX = PortB 4,5
        Ror bNewZ
        Ror bNewZ
        bNewZ = bNewZ & 3                    ' bNewZ = PortB 6,7

        If bNewX <> bOldX Then
            bOldX = bOldX * 4
            WREG = bOldX + bNewX            ' Index to table
            sbInc = PLUSW1                    ' Get element
            bOldX = bNewX                     ' update old value
            swCntX = swCntX + sbInc            ' change count
            Set fCntReady
        EndIf
        If bNewZ <> bOldZ Then
            bOldZ = bOldZ * 4
            WREG = bOldZ + bNewZ            ' Index to table
            swCntZ = swCntZ + PLUSW1
            sbInc = PLUSW1                    ' Get element
            bOldZ = bNewZ                     ' update old value
            swCntZ = swCntZ + sbInc            ' change count
            Set fCntReady
        EndIf
        RBIF=0
    EndIf
    If INT0F=1 Then                            ' Push button X to clear
        INT0F=0
        swCntX = 0
        Set fCntReady
    EndIf
    If INT1F=1 Then                            ' Push button Z to clear
        INT1F=0
        swCntZ = 0
        Set fCntReady
    EndIf
    Context Restore       
Title: Re: Quadrature (rotary) encoder example
Post by: RGV250 on Jun 19, 2023, 12:36 PM
Hi Basiclover,
I have got Les's code working but wondered if there will be an issue if the PIC has a lot to do. It is running on a PIC24 at 80mhz so probably not an issue?

Hi Flosigud,
I will have a look at your code later as it would be nice to have both options.

Regards,
Bob
Title: Re: Quadrature (rotary) encoder example
Post by: basiclover on Jun 19, 2023, 02:58 PM
@ RGV250
Good news that LES's code works for you. I think a faster pic would be rather a benefit
I'am interested in your findings about rotary encoders.I assume you didn't forget the debouncing RC on the 2 pins
Title: Re: Quadrature (rotary) encoder example
Post by: flosigud on Jun 19, 2023, 06:05 PM
My program was written with speed in mind on 18f25k22. It would need major rewrite to work on 24f.Some 16 bit PICs have hardware encoders that should be fast enough.
Title: Re: Quadrature (rotary) encoder example
Post by: RGV250 on Jun 19, 2023, 08:16 PM
Hi,
I haven't put the caps in as it will be difficult due to the board design, I will keep an eye on it and see if I need it but so far so good using the serial port to show the count and direction. I am only thinking of menu's and things like that so probably not a great issue if it does miss a step.

I did wonder if it would be possible to modify for the 24HJ, the one I have does not have hardware encoders, at least I have the basis to work on if it is possible to change. It will be good to get into PIC24 interrupts as I have only just started with them really.

Bob