how to read ky40 mechanical encoder ?


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    Join Date
    Jun 2008
    Location
    Varese , Italy
    Posts
    326


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    I did capture the output of the terminal printout for a better check.
    There are about 200 changes of the cnt obtained by "manually" turning the encoder knob on my control panel. Probably sometims cw and ccw.
    I noted very few spikes : I am not shure if they are due to the time required for the serial port output or to the encoder software.
    Any improvement to the program is very much appreciated.
    I am really searching for a good solution.
    Thanks
    regards,
    Ambrogio

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,631


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    I do it this way

    enc pins must be sequential and on same port
    both enc pins must be able to generate an interrupt (ioc on neg and pos edge is best , ioc, rac,rbc on neg or pos edge will work as will int0 int1)
    enc pins must be pulled up (10k) and have 0.1uF filter caps

    I have an asm version that's 100 bytes smaller and has about 1 tenth of the irq latency and is much faster too


    Code:
    '****************************************************************
    '*  Name    : rotary encoder.BAS                                *
    '*  Author  : richard                                           *
    '*  Notice  : Copyright (c) 2013                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 9/4/2013                                          *
    '*  Version : 1.0    16f1825                                    *
    '*  Notes   :  enca porta.2 encb porta.3                        *
    '*          :   note mclr disabled ,full quad decode            *
    '****************************************************************
      
    #CONFIG
                 __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_ON  &  _PWRTE_ON  &  _MCLRE_OFF  & _CLKOUTEN_OFF
                  __config      _CONFIG2, _PLLEN_ON & _LVP_OFF
    #ENDCONFIG
      
     
    include "dt_ints-14.bas"
    include "REENTERPBP.bas"
     
    asm
    INT_LIST macro
          INT_HANDLER IOC_INT, _enc_isr,pbp,NO
          endm
     INT_CREATE
    ENDASM    
     
    DEFINE OSC 32
     
     
     
     
       OSCCON=$70
       ANSELA=0
       
       OPTION_REG.6=0
     
       ev    VAR BYTE bank0
       cnt   VAR WORD bank0
       TMP   VAR BYTE bank0
       enca  VAR porta.2 
       encb  VAR porta.3
       TRISA = 111110
      
       lata.0=1
       IOCAP=12    ;enca porta.2 encb porta.3  pos edge trigger
       IOCAN=12    ;enca porta.2 encb porta.3  neg edge trigger
        
        
       pause 4000 
       
       serout2 PORTA.0,84,[ "ready",13,10]
       IOCAF=0
       
       INTCON=$C8
       
       
       
    mainloop:  
     
     serout2 PORTA.0,84,[13,10, "C",#CNT]
     pause 1000
     
     goto mainloop
        
     
        
     
    enc_isr:
        
    
    ev=ev<<2              ;shift last reading into position
    ev=ev|((porta&12)>>2)  ;read enc pins 2,3  mask off others then  combine this reading with last reading
    LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],tmp ;lookup the decision matrix
    if tmp then         ; decide to inc , dec or ignore 
     if tmp.7 then
       cnt=cnt-1
     else
        cnt=cnt+1
     endif
    endif
    intcon.0=0                   ; clean up and exit
    iocaf=0
    @ INT_RETURN

  3. #3
    Join Date
    Jun 2008
    Location
    Varese , Italy
    Posts
    326


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    Thanks Richard for the code.
    I am just a little bit busy on these days and so I plan to try your code on next days.
    As you have seen I am using pic18f452: Is your code applicable to this micro ?
    If no, what should I modify or adapt ?
    Thanks
    Regards,
    Ambrogio

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,631


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    for a pic18f452 you need to use RBC_INT for best results and pins portb.4,5 or portb.6,7 or portb.5,6

    this line needs to match chosen p1ns

    ev=ev|((porta&12)>>2) ;read enc pins 2,3 mask off others then combine this reading with last reading
    for pins portb.4,5 it would be

    ev=ev|((portb&48)>>4)
    Code:
    INT_LIST macro
          INT_HANDLER IOC_INT, _enc_isr,pbp,NO
          endm
     INT_CREATE
    would be
    Code:
    INT_LIST macro
          INT_HANDLER RBC_INT, _enc_isr,pbp,NO
          endm
     INT_CREATE
    IOCAP=12 ;enca porta.2 encb porta.3 pos edge trigger
    IOCAN=12 ;enca porta.2 encb porta.3 neg edge trigger
    IOCAF=0
    INTCON=$C8
    would be
    dummy_var = portb
    INTCON=$C8

    any references to IOCAF need to be deleted , trisb must be appropiate

  5. #5
    Join Date
    Jun 2008
    Location
    Varese , Italy
    Posts
    326


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    Hi Richard,
    I am going to modify my previous program with your indications.
    Probably I did something wrong and it is not working.
    I am attaching the full code : could you please have a look of it ?
    Thanks again for the assistance
    regards,
    Ambro
    Attached Files Attached Files

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,631


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    I would do it like this

    Code:
    '****************************************************************
    '*  Name    : pic controlled power supply                       *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 11/09/2015                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : pic18f452 10mhz x 4 pll = 40 MHZ                  *
    '****************************************************************
    ';Program Configuration Register 1H
    @  __CONFIG    _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H      
    ';Program Configuration Register 2L
    @  __CONFIG    _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L
    ';Program Configuration Register 2H
    @  __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
    ';Program Configuration Register 3H
    @  __CONFIG    _CONFIG3H, _CCP2MX_OFF_3H
    ';Program Configuration Register 4L
    @  __CONFIG    _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
    ';Program Configuration Register 5L
    @  __CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L 
    ';Program Configuration Register 5H
    @  __CONFIG    _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
    ';Program Configuration Register 6L
    @  __CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L 
    ';Program Configuration Register 6H
    @  __CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    ';Program Configuration Register 7L
    @  __CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
    ';Program Configuration Register 7H
    @  __CONFIG    _CONFIG7H, _EBTRB_OFF_7H
    ' ***************************************************************************
     
    DEFINE OSC 40                 ' XTAL= 10 MHZ   CLOCK= 40 MHZ
    INCLUDE "MODEDEFS.BAS"
    include "dt_ints-14.bas"
    include "REENTERPBP.bas"
     
    
    CNT VAR WORD                   ' COUNTER TO BE DISPLAYED ON TERMINAL
    CNT= 32000
    CNTOLD VAR WORD
    CNTOLD=32000
    counter VAR WORD
    counter= 32000
    ' DEBUG INTERFACE  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    '' Set Debug pin port   ________________________________________
    DEFINE DEBUG_REG PORTD
    '' Set Debug pin bit   _________________________________________ PIC_PIN_30
    DEFINE DEBUG_BIT 7
    '' Set Debug baud rate _________________________________________
    DEFINE DEBUG_BAUD 115200
    '' Set Debug mode: 0 = true, 1 = inverted ______________________
    DEFINE DEBUG_MODE 1
    DEBUG 13,10,13,10, " PROGRAM IS STARTING...", 13, 10, 13, 10                         
    ADCON1=7                      ' all digital !
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    RBC_INT,  _enc_isr,   PBP,  NO
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
      
    '@   INT_ENABLE   RBC_INT     ; enable external (INT) interrupts
       ev    VAR BYTE BANK0
       TMP   VAR BYTE BANK0
       enca  VAR portb.4 
       encb  VAR portb.5
       TRISA = 255
      
       lata.0=1
       tmp = portb  ;; read portb to establish pin change status
       INTCON=$C8  ; enable RBC_INT and clear rbcif
    Main:
      PAUSE 1000
      gosub get_cnt:
      IF counter <> CNTOLD THEN
         DEBUG DEC CNT,13,10
         CNTOLD=counter  ENDIF
      
    GOTO Main
    enc_isr:
        
    ev=ev<<2              ;shift last reading into position
    ev=ev|((portb&48)>>4)  ;read enc pins 4+5  mask off others then  combine this reading with last reading
    LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],tmp ;lookup the decision matrix
    if tmp then         ; decide to inc , dec or ignore 
     if tmp.7 then
       cnt=cnt-1
     else
        cnt=cnt+1
     endif
    endif
    intcon.0=0                   ; clean up and exit
    @ INT_RETURN
    
    
    
    get_cnt:       ;  cnt is not atomic   this is needed to avoid rollover miss reads
    intcon.3=0
    counter=cnt
    intcon.3=1
    return

  7. #7
    Join Date
    Jun 2008
    Location
    Varese , Italy
    Posts
    326


    Did you find this post helpful? Yes | No

    Default Re: how to read ky40 mechanical encoder ?

    Thanks Richard,
    Your program compiles well.
    I do have the follwing :

    PROGRAM IS STARTING...

    32009
    32005
    32009
    32013
    32017
    32021
    32033
    32042
    32073
    32113
    32153
    32173
    32197
    32209
    32233
    32257
    32221
    32199
    32161
    32129
    32101
    32065
    32061
    32057
    32053
    32045
    32041
    32040
    32037
    32013
    31999
    31997

    I have changed the encoder too but not working...
    Thanks
    Ambro

Similar Threads

  1. Question about mechanical relay
    By Megahertz in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 1st October 2012, 10:37
  2. Mechanical question
    By muddy0409 in forum mel PIC BASIC Pro
    Replies: 20
    Last Post: - 11th October 2011, 05:41
  3. Probe to read quadrature encoder with DT_INT need help
    By phoenix_1 in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 31st August 2009, 20:43
  4. Mechanical question
    By selbstdual in forum Off Topic
    Replies: 10
    Last Post: - 8th February 2008, 14:34
  5. Replies: 6
    Last Post: - 14th October 2005, 19:41

Members who have read this thread : 1

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