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,612


    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.

  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

    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

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    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.

  4. #4
    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  

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Hi,
    Now we're getting somewhere - that looks like it might work.
    The keypad routine has nothing to do with reading the encoder. Put the GOSUB Encoder in the mainloop, before GOSUB check obviously....

    And again, if it doesn't work then remove the keypad routine untill you get the encoder routine working - THEN try to make the two coexist. There's no guarantee that the encoder code works, I just posted it as one possible idea of how to read that kind of "encoder".

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


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    No matter what I do, portb.1 goes high and low .... portb.0 don't change ....
    Code:
    TRISB = 000000
    PORTB = 000000 
    
    oldState VAR BYTE
    newState VAR BYTE
    DIR VAR BIT
    
    UP CON 1
    DN CON 0
    
    oldstate = (porta & 000111)
    
    Main_Loop: 
    
    gosub Encoder
    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 = 1
        pause 100
        newState = (porta & 000111)
    portb.5 = 0
    If newState <> oldState THEN        ' Changed from last time?
      Select Case oldState
        Case 1
        If NewState = 4 THEN dir=up         
        If NewState = 2 THEN dir=dn
      
        Case 2
        If NewState = 4 THEN dir=up        
        If NewState = 1 THEN dir=dn
      
        Case 4
        If NewState = 1 THEN dir=up        
        If NewState = 2 THEN dir=dn
        
      END SELECT
    
    oldstate=newstate
    endif
    Return
    Attached Files Attached Files

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: New approach to Rotary Encoder

    Hi,
    Since you have the inputs pulled high and the wiper "grounding" each input as it cycles thru them you can't use 1, 2 and 4 as the states since that "looks for" a '1' on the individual pins. You need to use 3, 5 and 6 instead.

Members who have read this thread : 3

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