New approach to Rotary Encoder


Closed Thread
Results 1 to 40 of 91

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Hi,
    I don't have any experience with that routine but provided everything else works the way you want why don't you just set the pin which is common to the encoder (RB5 ?) high, read the port, and return the pin low.

    GOSUB ScanMatrix 'Or whatever
    PortB.5 = 1
    GOSUB Encoder
    PortB.5 = 0

    Finally, in the first code you posted you had the encoder to RB7-5 so I based my code on that. Now, in your latest schematic, you have it on RB2-0 which means that my code (if that's what you're trying) definitely won't work without modifying it since it expects the three "switches" in the encoder to be on RB7-5.

  2. #2
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    What I do wrong ?!
    I adapted "keypad.bas" to my hw :
    Code:
    KB_ROW        = 3                                      ; 3 ROW keypad
    KB_ROW_PORT   = PORTB                                  ; Keypad ROW on PORTB
    KB_ROW_BIT    = 3                                      ; ROW0 = PORTB.3
    KB_COL        = 3                                      ; 3 COL keypad
    KB_COL_PORT   = PORTB                                  ; Keypad Col on PORTB
    KB_COL_BIT    = 0                                      ; COL0 = PORTB.0
    DebounceDelay = 0x80                                   ; debounce delay 41mSec
    SINGLE_SCAN   = 0                                      ; Scan ;till a key is pressed   
    KEYPAD_AUTOREPEAT = 1
    and I wrote this pice of code :
    Code:
    @ DEVICE pic16F628A, XT_OSC, WDT_OFF, PWRT_ON, BOD_OFF, MCLR_ON, LVP_OFF
    
       Define   OSC 4           ' 4MHz 
       CMCON = 7                ' Disable on-chip comparator, PORTA in digital mode
    
    include "alldigital.pbp"
    include "C:\PBP\enc_KEY.BAS" 
    
    TrisA = %00000000
    PortA = %00000000
    PortB = %00111000
    TrisB = %00011000
    
    oldState VAR BYTE
    newState VAR BYTE
    Q_Count VAR WORD
    DIR VAR BIT
    
    UP CON 1
    DN CON 0
    
    
    Main_Loop:  
    newState = (PortB & %00111000)  
    
    portb.5 = 1  
    gosub encoder
    portb.5 = 0
    
    if dir = up then 
    porta.0 = 0
    porta.1 = 1
    endif                           
    if dir = dn then 
    porta.0 = 1
    porta.1 = 0
    endif
    goto Main_Loop
    
    
    encoder:
    If newState <> 0 THEN
    If newState <> oldState THEN        ' Changed from last time?
      Select Case oldState
        Case 32
        If NewState = 128 THEN          ' Was 1 now 4 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                          ' Was 1 now 2 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      
        Case 64
        If NewState = 32 THEN        ' Was 2 now 1 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                           ' Was 2 now 4 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      
        Case 128
        If NewState = 64 THEN        ' Was 4 now 2 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                       ' Was 4 now 1 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      END SELECT
    
      oldState = NewState 
    
    ENDIF
    ENDIF
    Return
    ..but no change in porta.0 or porta.1 state ...

  3. #3
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Update code :
    Code:
    Main_Loop:  
    gosub keypadscan
    newState = (PortB & %00000111) 
    gosub encoder
    gosub check
    goto main_loop
    
    Check :
    if dir = up then 
    porta.0 = 0
    porta.1 = 1
    endif                           
    if dir = dn then 
    porta.0 = 1
    porta.1 = 0
    endif
    return
    
    
    encoder:
    If newState <> 0 THEN
    If newState <> oldState THEN        ' Changed from last time?
      Select Case oldState
        Case 32
        If NewState = 128 THEN          ' Was 1 now 4 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                          ' Was 1 now 2 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      
        Case 64
        If NewState = 32 THEN        ' Was 2 now 1 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                           ' Was 2 now 4 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      
        Case 128
        If NewState = 64 THEN        ' Was 4 now 2 = Up
          Q_Count = Q_Count + 1
          DIR = UP
        ELSE                       ' Was 4 now 1 = Down
          Q_Count = Q_Count - 1
          DIR = DN
        ENDIF
      END SELECT
    
      oldState = NewState 
    
    ENDIF
    ENDIF
    Return
    but no matter what M (1,2 or 3) I push, porta.0 goes high and stay so.

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


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Hi,
    In the first code you posted you read the status of PortB before driving the the common pin for the encoder so there probably won't be any signals comming in.
    In the second, updated example, you never drive the common pin for the encoder at all.
    You need to set the "common pin" high (or low depending on hardware) and THEN read the port otherwise you won't get anything back.


    You really need to sit back and think the problem thru, not just cut and paste pieces of code together without understanding what they do and how the hardware they're intended to interface to is supposed to work.

    Think it thru.... The "encoder" has a "wiper" which "cylces" thru the different contacts. Depending on which contact the wipers is positioned at you'll get a signal out on a certain pin. In order to get that signal out the "wiper" must be "powered" in one way or another. If the inputs from the "contacts" are pulled up then wiper must be grounded so that it pulls the contact (and signal LOW). Likewise if the inputs from the contacts are pulled down then the "wiper" must be high in order to pull the inputs high.

    If the inputs are pulled up with resistors then you'll get a "walking zero" across the three pins, if the inputs are pulled down you'll get a "walking one" across the inputs. You must adapt the code to match.

    My suggestion, for now, is that you ditch the matrix routine untill you get the encoder working - and understand how it works.

    /Henrik.

  5. #5
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Thanks for support !
    "In the second, updated example, you never drive the common pin for the encoder at all."
    But ..."keypadscan" don't do this ? Proteus show how "0" walk through portb 3,4,5.
    Attached Files Attached Files

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Hi,
    Like I said earlier, I don't have any experience with that piece fo code but if I'd venture I guess (and I'm pretty certain I'm right) it scans the pins once each time you GOSUB the routine. This means it does NOT scan the pins during the time you GOSUB the encoder routine.

    Does Proteus show that walking zero across the pins at the same time as you do newState = PortB & %00000111 - I'd say no.

    If your inputs are pulled up with resistors then the common/wiper of the encoder must be LOW at the time you read the status of the port. You must understand and remember that the PIC executes the code sequentially, one instruction after another.

  7. #7
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Step-by-step I think I begin to understand ...
    The correct hardware it's this.
    The software can be this :
    Code:
    @ DEVICE pic16F628A, XT_OSC, WDT_OFF, PWRT_ON, BOD_OFF, MCLR_ON, LVP_OFF
    
       Define   OSC 4           ' 4MHz 
       CMCON = 7                ' Disable on-chip comparator, PORTA in digital mode
    
    include "alldigital.pbp"
    include "C:\PBP\enc_KEY.BAS" 
    
    TRISB = 000000
    PORTB = 000000 
    
    oldState VAR BYTE
    newState VAR BYTE
    DIR VAR BIT
    
    UP CON 1
    DN CON 0
    
    Main_Loop: 
    portb.5 = 1
    gosub keypadscan
    gosub check
    goto main_loop
    
    Check :
    if dir = up then 
    portb.0 = 1
    pause 1000
    portb.0 = 0
    endif
    if dir = dn then
    portb.1 = 1
    pause 1000
    portb.1 = 0
    endif
    return
    
    encoder:
    portb.5 = 0
        newState = (porta & 000111)
    If newState <> oldState THEN        ' Changed from last time?
      Select Case oldState
        Case 2
        If NewState = 4 THEN          ' Was 1 now 4 = Up
          DIR = up
        ELSE                          ' Was 1 now 2 = Down
          DIR = dn
        ENDIF
      
        Case 4
        If NewState = 1  THEN        ' Was 2 now 1 = Up
          DIR = up
        ELSE                           ' Was 2 now 4 = Down
          DIR = dn
        ENDIF
      
        Case 1
        If NewState = 2 THEN        ' Was 4 now 2 = Up
          DIR = up
        ELSE                       ' Was 4 now 1 = Down
          DIR = dn
        ENDIF
      END SELECT
    
      oldState = NewState 
    endif
    portb.5 = 1
    Return
    The question is : where to put "gosub encoder" ? Inside the "enc_key.bas" (it's keypad.bas addapted to 2 row/3 cols) ???
    Attached Images Attached Images  

Members who have read this thread : 5

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