My rotary encoder adventures


+ Reply to Thread
Results 1 to 17 of 17

Hybrid View

  1. #1
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037

    Default My rotary encoder adventures

    This is what I have to far:

    Code:
    '------------------------------------------------------------------------------
    '                      SPEED 26-36us to execute IF logic                      '
    '------------------------------------------------------------------------------
    '
    ' Change log
    ' 2024-08-18  Convert from 16F1937
    
    @ ERRORLEVEL -301   ; turn off ADC clock ignored message
    @ ERRORLEVEL -306   ; turn off crossing page boundary message
    
    '***********************************************************************
    ' Default in file: PBP3_1\DEVICES\PIC16F1936.PBPINC                    *
    ' List in file:    PBP3_1\DEVICE_REFERENCE\PIC16F1936.INFO             *
    ' Note:            PIC18 devices, the __CONFIG directive has           *
    '                    been superceded by the CONFIG directive           *
    '***********************************************************************
    #CONFIG
     __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF 
     __CONFIG _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    ;--- Defines -------------------------------------------------------------------
    
    DEFINE OSC 32
                                            
    DEFINE  LCD_DREG      PORTB             ' Set LCD data port
    DEFINE  LCD_DBIT      0                 ' Set starting data bit
    DEFINE  LCD_RSREG     PORTC             ' Set LCD register select port
    DEFINE  LCD_RSBIT     5                 ' Set LCD register select bit
    DEFINE  LCD_EREG      PORTC             ' Set LCD enable port
    DEFINE  LCD_EBIT      4                 ' Set LCD enable bit
    DEFINE  LCD_BITS      4                 ' Set LCD bus size
    DEFINE  LCD_LINES     4                 ' Set number of lines on LCD
    DEFINE  LCD_COMMANDUS 1000              ' Set command delay time in microseconds
    DEFINE  LCD_DATAUS    50                ' Set data delay time in microseconds
    
    define  CCP4_REG     PORTC              ' PWM Pulse out to LCD contrast
    DEFINE  CCP4_BIT     1                  '   2N2907 PNP with 1K on base
    define  CCP5_REG     PORTC              ' PWM Pulse out to LCD backlight
    DEFINE  CCP5_BIT     2                  '   2N2222A NPN with 1K on base
    
    DEFINE  HSER_RCSTA 90h                  ' Enable serial port & continuous receive
    DEFINE  HSER_TXSTA 24h                  ' Enable transmit, BRGH = 1
    Define  HSER_BAUD 115200
    DEFINE  HSER_CLROERR 1                  ' Clear overflow automatically
    DEFINE  HSER_SPBRGH  0
    DEFINE  HSER_SPBRG  68
    
    ;--- Setup registers -----------------------------------------------------------
    
    SPLLEN          CON %1                  ' PLL enable
    IRCF            CON %1110               ' to enable 8 MHz
    SCS             CON %00                 ' system clock determined by FOSC
    OSCCON = (SPLLEN << 7) | (IRCF << 3) | SCS
    
    BAUDCON.3 = 1                           ' Enable 16 bit baudrate generator
    
    ;--- Setup analog pins to digital ----------------------------------------------
    
    ANSELA = %00000000
    ANSELB = %00000000
    'ANSELC = %00000000                     ' No analog on port C
    'ANSELD = %00000000                     ' No port D
    'ANSELE = %00000000                     ' No analog on port E
    
    ;--- Setup Port directions -----------------------------------------------------
    
    TRISA = %00000111                       ' Pin A7 = ...available
                                            ' Pin A6 = ...available
                                            ' Pin A5 = ...available
                                            ' Pin A4 = ...available
                                            ' Pin A3 = ...available
                                            ' Pin A2 = SPST
                                            ' Pin A1 = WiperB
                                            ' Pin A0 = WiperA
    
    TRISB = %00000000                       ' Pin B7 = iCSP clock
                                            ' Pin B6 = ICSP data
                                            ' Pin B5 = Blink LED1
                                            ' Pin B4 = Blink LED2
                                            ' Pin B3 = LCD data D7
                                            ' Pin B2 = LCD data D6
                                            ' Pin B1 = LCD data D5
                                            ' Pin B0 = LCD data D4
    
    TRISC = %10000000                       ' Pin C7 = RX
                                            ' Pin C6 = TX
                                            ' Pin C5 = LCD RS
                                            ' Pin C4 = LCD EN
                                            ' Pin C3 = ...available
                                            ' Pin C2 = PWM LCD backlight
                                            ' Pin C1 = PWM LCD contrast
                                            ' Pin C0 = ...available
    
    'TRISD = %00000000                       ' No port D
    '
    TRISE = %00000000                       ' Pin E3 = MCLR
    
    ;--- Setup constants -----------------------------------------------------------
    
    
    ;--- Setup pins ----------------------------------------------------------------
    
    Enc1_WiperA         var PortA.0
    Enc1_WiperB         var PortA.1
    Enc1_SPST           VAR PortA.2
    
    BlinkLED1           VAR LatB.5         ' Switch these ON/OFF to determine time
    BlinkLED2           VAR LatB.4         '   required to execute a section of code
    
    ;--- Setup variables -----------------------------------------------------------
    
    Enc1_previous       var BYTE
    Enc1_rotation       var BYTE
    Enc1_direction      VAr BYTE
    
    USARTcounter        VAr WORd            ' Used to show program is looping
    Enc1_counter        VAr WORd            ' Used to display encoder movement
    
    ;--- Program initialization ----------------------------------------------------
    
        BlinkLED1 = 0
        BlinkLED2 = 0
    
        HPWM 2,100,1953                     ' LCD contrast (V0 pin)
        HPWM 1,180,1953                     ' LCD backlight (LED anode)
    
        USARTcounter = 0
    
        Enc1_previous = 0
        Enc1_rotation = 0
        Enc1_direction = 0
        Enc1_counter = 0
            
        goto Start
    
    ;--- Subroutines ---------------------------------------------------------------
    
    Start:
        Pause 500                           ' Let PIC and LCD stabilize
    
        LCDOUT $FE, 1 : Pauseus 1
        LCDOUT $FE, $80, "ROTARY ENCODER TEST" : Pauseus 1
    
    Mainloop:
        
        BlinkLED1 = 1                       ' Top of LOOP on Logic 2 probe
        BlinkLED2 = 0
    
        if USARTcounter < 65025 then        ' To show program is working
            USARTcounter = USARTcounter + 1
        else
            USARTcounter = 0
        endif
    
    '  Wiper Chart:
    '  ============
    '     A   B
    '    --- ---
    '     0   0
    '     1   0  /\ CCW
    '     1   1
    '     0   1  \/ CW
    '     0   0
    '
    ' Careful, EC11 30 detents 15 pulses will move from 00 to 11
    '          EC11 20 detents can move from 00 back to 00 in one click
    
        if Enc1_WiperA = 0 and Enc1_WiperB = 0 then ' See wiper chart above
            if Enc1_previous = 01 then              ' 2 digits to follow chart better
                Enc1_direction = 1                  ' 1=CW, 0=CCW
                Enc1_rotation = 1                   ' Motion occurred
            else
                if Enc1_previous = 10 then
                    Enc1_direction = 0              ' 0=CCW
                    Enc1_rotation = 1               ' Motion occurred
                else
                    Enc1_direction = 0              ' Not relevant without motion
                    Enc1_rotation = 0               ' No motion occurred
                endif
            endif
            Enc1_previous = 00                      ' Save wiper position
        endif
    
        if Enc1_WiperA = 1 and Enc1_WiperB = 0 then
            if Enc1_previous = 00 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 11 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 10
        endif
    
        if Enc1_WiperA = 1 and Enc1_WiperB = 1 then
            if Enc1_previous = 10 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 01 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 11
        endif
    
        if Enc1_WiperA = 0 and Enc1_WiperB = 1 then
            if Enc1_previous = 11 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 00 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 01
        endif
    
        if Enc1_rotation = 1 then
            if (Enc1_WiperA = 0 and Enc1_WiperB = 0) or _
               (Enc1_WiperA = 1 and Enc1_WiperB = 1) then
                if Enc1_direction = 1 then
                    Enc1_counter = Enc1_counter + 1     ' Turned 1 position CW
                else
                    if Enc1_counter > 0 then
                        Enc1_counter = Enc1_counter - 1 ' Turned 1 position CCW
                    endif
                endif
            endif
        endif
    
        BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
        BlinkLED2 = 1
    
        hserout ["#:", DEC5 USARTcounter,_
                 " C:", dec3 Enc1_counter,_
                 " A:", DEC1 Enc1_WiperA,_
                 " B:", DEC1 Enc1_WiperB,_
                 " SW:", DEC1 Enc1_SPST, 10]
    
        BlinkLED1 = 0                       ' After HSEROUT on Logic 2 probe
        BlinkLED2 = 0
    
        LCDOUT $FE, $D4, "C:", dec3 Enc1_counter,_
                        "  A:", DEC1 Enc1_WiperA,_
                        " B:", DEC1 Enc1_WiperB,_
                        "  SW:", DEC1 Enc1_SPST : Pauseus 1
    
        BlinkLED1 = 0                       ' After LCDOUT on Logic 2 probe
        BlinkLED2 = 0
        
        goto mainloop
    end

    To put things into perspective, these are the times I've observed so far:

    Name:  Encoder probe d.png
Views: 571
Size:  67.0 KB


    Those encoder readings on channels 0 and 1 were done while turning the encoder as fast as I could. I wanted to see if I could over-run the time it takes the PIC to execute all the encoder code at 32 MHz.

    The PIC is not even close to being overwhelmed, so now I know I should be able to process at least 2 encoders at the same time (at least that's what should happen in my mind ).
    Last edited by Demon; - 19th August 2024 at 20:47.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Here's an example of a chinesium EC11 clone:

    Name:  Encoder probe e.png
Views: 562
Size:  51.1 KB


    Every time I press on the switch built into the shaft, wiper A bounces. Also, note how wiper A never came down at the top left.

    So now I have some good quality control tests to do on EC11s that I'll be having made in china.



    (I would never have thought of checking for this defect. I'm fiddling with my Saleae Logic 2 probe on a rotary encoder. I just wanted to see how a manual press would compare with the encoder pulses.)


    EDIT: These are from AliExpress; you get what you pay for. But when you order from Alibaba, you can get reimbursed if you can demonstrate that a product is not performing accord to specifications.

    I don't mind the aliexpress lower quality, I use them mainly for testing.
    Last edited by Demon; - 19th August 2024 at 21:06.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,036


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Quote Originally Posted by Demon View Post
    Every time I press on the switch built into the shaft, wiper A bounces. Also, note how wiper A never came down at the top left.
    Who could imagine that....! Wow, chinese keep surprising me!

    Ioannis

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,580


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    You have turned off the WDT (for speed I suppose) but forgot to tell PBP about it so no speed gained.

    Anyway, try this as your encoder logic and see if it beats 26us.
    Code:
    New_Encoder 	VAR BYTE
    Old_Encoder     VAR BYTE
    Test            VAR BYTE
    Enc1_counter    VAR WORD
    
    BlinkLED1           VAR LatB.5         ' Switch these ON/OFF to determine time
    BlinkLED2           VAR LatB.4 
    
    MainLoop:    
        BlinkLED1 = 1                       ' Top of LOOP on Logic 2 probe
        BlinkLED2 = 0
    
        New_Encoder = PortA & %00000011                 ' Read encoder signals on RA0 and RA1
        Test = New_Encoder ^ Old_Encoder                ' Bitwise XOR current state with previous state to see if any pins changed.
            
        IF Test.0 = 1 THEN                              ' Edge detected on channel A?
            IF Old_Encoder.0 ^ Old_Encoder.1 THEN       ' If Old_Encoder is 0 or 3 we count up, otherwise we count down.
                Enc1_counter = Enc1_counter + 1
            ELSE
                Enc1_counter = Enc1_counter - 1
            ENDIF
            GOTO MainLoop        
        ENDIF
    
        IF Test.1 = 1 THEN                              ' Edge detected on channel B?
            IF Old_Encoder.0 ^/ Old_Encoder.1 THEN      ' If Old_Encoder is 1 or 2 we count up, otherwise we count down.
                Enc1_counter = Enc1_counter + 1
            ELSE
                Enc1_counter = Enc1_counter - 1
            ENDIF
            Goto MainLoop
        ENDIF
    
        BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
        BlinkLED2 = 1
        
        ' Other stuff here...
        
        Goto MainLoop
    EDIT: Oh, the timing measurment will not work properly since we're jumping back to mainloop before flipping the LEDs but you can fix that.
    Last edited by HenrikOlsson; - 19th August 2024 at 21:19.

  5. #5
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Holy poopenstuff!

    My logic took about 20us, yours took about 2.4us!

    :O

    I knew there was room for improvement with bit manipulation, but I didn't expect nearly a ten-fold acceleration.


    EDIT: Ooops, just noticed you're jumping out with turning off LED, adjusting now.


    3.9 to 4.9us, depending on where it jumps out of logic.

    Still, that's 4-5 times faster than my IFs.


    EDIT SOME MORE: I put my LCDOUTs back in to check on Enc1_Counter, and something funky is going on. It's looping like crazy, gonna check to see if I can figure it out.
    Last edited by Demon; - 19th August 2024 at 22:09.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  6. #6
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Henrik, my encoder goes from 00 to 11 in one click, then back to 00 in the next click.

    Does your encoder do that also?

    EDIT: I put in an old encoder that goes from 00 to 00 and that one works "better" from click to click, but as I move that one slowly, I can see the counter moving super fast, then stop on the click.
    Last edited by Demon; - 19th August 2024 at 22:15.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    [QUOTE=HenrikOlsson;155986]You have turned off the WDT (for speed I suppose) but forgot to tell PBP about it so no speed gained.

    You're assuming I know what I'm doing.

    I didn't think I'd need WDT, until someone tells me I should use it.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  8. #8
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Henrik, maybe a video would be helpful. 1st half is with a encoder with 30detents/15pulses, 2nd half is 20detents (I don't have datasheet for that one, no idea how many pulses).




    That rocker switch selects logic; mine is first in video, yours is 2nd when switch is rocked to the right.

    My code with combined logic. I added a switch and moved LCDOUT into a subroutine to keep the code clean:

    Code:
        goto Start
    
    ;--- Subroutines ---------------------------------------------------------------
    LCDoutput:
    
        LCDOUT $FE, $D4, "C:", dec5 Enc1_counter,_
                         " A:", DEC1 Enc1_WiperA,_
                         " B:", DEC1 Enc1_WiperB,_
                         " SW:", DEC1 Enc1_SPST : Pauseus 1
        Return
    
    Start:
        Pause 500                           ' Let PIC and LCD stabilize
    
        LCDOUT $FE, 1 : Pauseus 1
        LCDOUT $FE, $80, "ROTARY ENCODER TEST" : Pauseus 1
    
    Mainloop:
        
        BlinkLED1 = 1                       ' Top of LOOP on Logic 2 probe
        if logicselector = 1 then goto MyLogic
    
    '  Wiper Chart:
    '  ============
    '     A   B
    '    --- ---
    '     0   0
    '     1   0  /\ CCW
    '     1   1
    '     0   1  \/ CW
    '     0   0
    '
    ' Careful, EC11 30 detents 15 pulses will move from 00 to 11
    '          EC11 20 detents can move from 00 back to 00 in one click
    
        New_Encoder = PortA & %00000011                 ' Read encoder signals on RA0 and RA1
        Test = New_Encoder ^ Old_Encoder                ' Bitwise XOR current state with previous state to see if any pins changed.
            
        IF Test.0 = 1 THEN                              ' Edge detected on channel A?
            IF Old_Encoder.0 ^ Old_Encoder.1 THEN       ' If Old_Encoder is 0 or 3 we count up, otherwise we count down.
                Enc1_counter = Enc1_counter + 1
            ELSE
                Enc1_counter = Enc1_counter - 1
            ENDIF
            BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
            GOSUB LCDoutput
            GOTO MainLoop        
        ENDIF
    
        IF Test.1 = 1 THEN                              ' Edge detected on channel B?
            IF Old_Encoder.0 ^/ Old_Encoder.1 THEN      ' If Old_Encoder is 1 or 2 we count up, otherwise we count down.
                Enc1_counter = Enc1_counter + 1
            ELSE
                Enc1_counter = Enc1_counter - 1
            ENDIF
            BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
            GOSUB LCDoutput
            Goto MainLoop
        ENDIF
    
        BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
    
        GOSUB LCDoutput
        
        goto mainloop
    
    MyLogic:
    
        if Enc1_WiperA = 0 and Enc1_WiperB = 0 then ' See wiper chart above
            if Enc1_previous = 01 then              ' 2 digits to follow chart better
                Enc1_direction = 1                  ' 1=CW, 0=CCW
                Enc1_rotation = 1                   ' Motion occurred
            else
                if Enc1_previous = 10 then
                    Enc1_direction = 0              ' 0=CCW
                    Enc1_rotation = 1               ' Motion occurred
                else
                    Enc1_direction = 0              ' Not relevant without motion
                    Enc1_rotation = 0               ' No motion occurred
                endif
            endif
            Enc1_previous = 00                      ' Save wiper position
        endif
    
        if Enc1_WiperA = 1 and Enc1_WiperB = 0 then
            if Enc1_previous = 00 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 11 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 10
        endif
    
        if Enc1_WiperA = 1 and Enc1_WiperB = 1 then
            if Enc1_previous = 10 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 01 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 11
        endif
    
        if Enc1_WiperA = 0 and Enc1_WiperB = 1 then
            if Enc1_previous = 11 then
                Enc1_direction = 1
                Enc1_rotation = 1
            else
                if Enc1_previous = 00 then
                    Enc1_direction = 0
                    Enc1_rotation = 1
                else
                    Enc1_direction = 0
                    Enc1_rotation = 0
                endif
            endif
            Enc1_previous = 01
        endif
    
        if Enc1_rotation = 1 then
            if (Enc1_WiperA = 0 and Enc1_WiperB = 0) or _
               (Enc1_WiperA = 1 and Enc1_WiperB = 1) then
                if Enc1_direction = 1 then
                    Enc1_counter = Enc1_counter + 1     ' Turned 1 position CW
                else
                    if Enc1_counter > 0 then
                        Enc1_counter = Enc1_counter - 1 ' Turned 1 position CCW
                    endif
                endif
            endif
        endif
    
        GOSUB LCDoutput
        
        goto mainloop
    Last edited by Demon; - 20th August 2024 at 01:14.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  9. #9
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,037


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    Henrik, inspired by your code. I got down to 6.4 - 8.6us:

    Goes in initialization section:

    Code:
        Enc1_previous = %11111111
        Enc1_Current = %00000000
        Enc1_counter = 0
    MainLoop:

    Code:
    MyLogic:
    
        Enc1_Current = (Enc1_WiperA << 1) + Enc1_WiperB
    
        IF Enc1_Current != Enc1_Previous THEN
            IF Enc1_Current = %00000011 THEN
                IF Enc1_Previous = %00000010 THEN
                    Enc1_counter = Enc1_counter + 1
                ELSE
                    IF Enc1_Previous = %00000001 THEN
                        Enc1_counter = Enc1_counter - 1
                    ENDIF
                ENDIF
            ELSE
                IF Enc1_Current = %00000000 THEN
                    IF Enc1_Previous = %00000001 THEN
                        Enc1_counter = Enc1_counter + 1
                    ELSE
                        IF Enc1_Previous = %00000010 THEN
                            Enc1_counter = Enc1_counter - 1
                        ENDIF
                    ENDIF
                ENDIF
            ENDIF
        ENDIF
        
        Enc1_Previous = Enc1_Current
    
        BlinkLED1 = 0                       ' Bottom of IFs on Logic 2 probe
    
        GOSUB LCDoutput
        
        goto mainloop

    Since my encoder doesn't stop on 01 or 10, I only need to check 11 and 00. Already 3 times faster than my original.


    EDIT: Updated times

    Name:  Encoder probe f.png
Views: 578
Size:  104.6 KB
    Last edited by Demon; - 20th August 2024 at 02:36.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  10. #10
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,580


    Did you find this post helpful? Yes | No

    Default Re: My rotary encoder adventures

    I use that code with an optical encoder to convert from quartature to up/down pulses and it tracks the encoder perfectly to >200k edges per second. I modified it to incorporate your counter but I might have messed something up.

    Since my encoder doesn't stop on 01 or 10, I only need to check 11 and 00. Already 3 times faster than my original.
    It might not have a detent at every quadrature state but it sure must "go thru" them.
    If you are at 00 and go to 11, which direction did it turn? There's no way to know unless also decoding the 10/01 states in between the detents - and you are doing that.

    Also, don't forget that your LCDoutput subroutine takes considerable amount of time, you can not allow the encoder to pass thru two (or more) states without reading it or it WILL miss pulses or even count backwards.

    Take your logic analyzer capture and measure the time between the rising edges of channel A and B respectively.
    The pulsewidth of channel A is 11ms but the time between the edges on A and B is much shorter than 5.5ms due to the fact that the phase shift is far from 90° on your encoder. Lets say it's 2ms... How long does your LCDoutput subroutine take?

Similar Threads

  1. Rotary encoder with DT interrupts
    By louislouis in forum mel PIC BASIC Pro
    Replies: 33
    Last Post: - 21st March 2021, 16:45
  2. Rotary encoder subroutine
    By Fanias in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 10th October 2018, 14:13
  3. Using an incremental rotary encoder?
    By keithv in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 12th January 2016, 23:23
  4. New approach to Rotary Encoder
    By Ioannis in forum Code Examples
    Replies: 90
    Last Post: - 11th July 2013, 22:05

Members who have read this thread : 10

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts