Quad encoder problems


Closed Thread
Results 1 to 40 of 52

Hybrid View

  1. #1
    Join Date
    Sep 2006
    Posts
    22

    Default Quad encoder problems

    Hey all,

    I am trying to get a couple of quad encoders to work in Picbasic
    pro. I know the basics of how they work and simple programing
    abilities. Here is what I have:

    Qty 2 quad encoders with 36 slots each
    Pic 16F628-20p
    parallel lcd

    I want to be able to return a value of 1-36 from each encoder so I
    know the exact position of each.

    The code I wrote is very simple using if then statements and reading
    the ports to see if it is high or low. It kinda works but only if
    the encoder is turned extremly slow and even then I get glitching.

    From the information I have been able to find, it looks as if I need
    to do it in assembly but like I said before, I only know simple
    Basic programing.

    Can anyone help??

    Thanks,
    Smitty

  2. #2
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    If you do not need to determine the direction of the encoders, use TMR1 in counter mode instead of a PORT.

    In this case, the TMR1 as counter can work in the background while you do other things in foreground.

    However, if you have to use a PORT to read the encoder (mostly for direction), then you need to make sure that there is no "Pause" in your code. Any Pause will give you missing counts since the encoder is encoding the ticks faster then the "Pause" you have. This may explain why slow speed creates no problem in your case.

    Since you have LCD, you probably have a Pause to match the refresh rate.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  3. #3
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    Hi sayzer,

    Thanks for the reply.

    Dont I need direction if I want to know the exact position? 36 slots = 10deg per slot for a total of 360deg. I need it to count up to 36 in one direction until one revoluton where it returns to 1. And count down to 1 in the other direction until one revolution where it returns to 36.

    In other words I need a value between 1 and 36 corosponding to the exact slot it is currently on.

    Smitty

  4. #4
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by smitty505000
    ...I need it to count up to 36 in one direction until one revoluton where it returns to 1...
    Smitty
    As you know, usually in rotary encoders, it won't return to 1. It will always give you ticks as long as it rotates and you count the ticks. You need to use "Reference" signal out of the encoder which gives you a single tick only at the exact same point per revolution. When you get this tick then you know that "one revolution" is complete.

    As you see, you need to also count or check this tick. The safest way, I think, would be to use TMR0 to count reference signal, and TMR1 to count one of the other signals (this is where you do not need to know the direction). The reason why I point out Timer modules is that they work in the background.


    If you had a choice in which your encoder turned one direction and it was enough for you, then you could solve your problem here. But, you say you need both directions. In this case, you will have to use a PORT to read the encoder.

    I added some links to some posts in this forum. Pls check them and see what kind of problems others encountered and how they approach to the similar issues.

    1. http://www.picbasic.co.uk/forum/show...rotary+encoder
    2. http://www.picbasic.co.uk/forum/show...rotary+encoder
    3. http://www.picbasic.co.uk/forum/show...rotary+encoder
    4. http://www.picbasic.co.uk/forum/show...rotary+encoder

    mister_e has a clever approach to a similar encoder issue (Item 4).


    Regards.


    Edit: What you say kind a sounds that you may actually not need the direction.


    ------------
    Last edited by sayzer; - 9th September 2006 at 20:03.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  5. #5
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    Thanks for the info sayzer! Not sure I explained what I am doing very well. I did some more searching and found out I have 2 bit encoders, not quad. I am using them with a weight attached to one side so they are always parallel to the ground. What I want to do is use them as attitude sensors for pitch and roll in a telemetry system I am building.

    They have 36 slots each and return a code of 00 01 11 10 in one direction and 10 11 01 00 in the other. I have it working but it seams to bounce or glitch. I think the 16f628 at 20mhz isnt fast enough to keep up.

    Here is what I have so far.
    Val should return a value from 2 to 145. Its for 36 slots * 4 states per slot.


    INPUT PORTB.4
    INPUT PORTB.5
    LCDOUT $FE, 1
    VAL VAR WORD
    VAL = 2

    MAIN:
    LCDOUT $FE, 1
    LCDOUT $FE, $80, #PORTB.4, #PORTB.5
    LCDOUT $FE, $C0, #VAL
    IF PORTB.4 = 0 AND PORTB.5 = 0 THEN Q00
    IF PORTB.4 = 0 AND PORTB.5 = 1 THEN Q01
    IF PORTB.4 = 1 AND PORTB.5 = 1 THEN Q11
    IF PORTB.4 = 1 AND PORTB.5 = 0 THEN Q10
    GOTO MAIN
    Q00:
    IF PORTB.4 = 0 AND PORTB.5 = 1 THEN VALADD
    IF PORTB.4 = 1 AND PORTB.5 = 0 THEN VALMINUS
    GOTO Q00


    Q01:
    IF PORTB.4 = 1 AND PORTB.5 = 1 THEN VALADD
    IF PORTB.4 = 0 AND PORTB.5 = 0 THEN VALMINUS
    GOTO Q01


    Q11:
    IF PORTB.4 = 1 AND PORTB.5 = 0 THEN VALADD
    IF PORTB.4 = 0 AND PORTB.5 = 1 THEN VALMINUS
    GOTO Q11


    Q10:
    IF PORTB.4 = 0 AND PORTB.5 = 0 THEN VALADD
    IF PORTB.4 = 1 AND PORTB.5 = 1 THEN VALMINUS
    GOTO Q10

    VALADD:
    VAL = VAL + 1
    IF VAL > 145 THEN VAL = 2
    GOTO MAIN

    VALMINUS:
    VAL = VAL - 4
    IF VAL < 2 THEN VAL = 145
    GOTO MAIN

  6. #6
    Join Date
    May 2006
    Location
    Del Rio, TX, USA
    Posts
    343


    Did you find this post helpful? Yes | No

    Default Use Interrupts!!

    Smitty,

    Go to Darrel Taylor's Instant Interrupt Site and download DT_INTS-14.bas and ReEnterPBP.bas

    In the DT_INTS-14.bas file, comment out the Highlighted line below, as shown.

    Code:
    '****************************************************************
    '*  Name    : DT_INTS-14.bas                                    *
    '*  Author  : Darrel Taylor                                     *
    '*  Version : 0.93 BETA                                         *
    '*  Date    : JAN 29, 2006                                      *
    '****************************************************************
    '* Rev 0.93  Fixed CMIF and EEIF problem with older PIC's       *
    '*           that have the Flags in PIR1 instead of PIR2        *
    '* Rev 0.92  solves a "Missed Interrupt" and                    *
    '*           banking switching problem                          *
    '****************************************************************
    DEFINE  INTHAND  INT_ENTRY
    
    wsave       var byte    $20     SYSTEM      ' location for W if in bank0
    ;wsave       var byte    $70     SYSTEM     ' alternate save location for W 
                                                ' if using $70, comment out wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ---------------------------- 
    '       Comment them out to fix the problem ----
    ' -- It depends on which Chip you are using, as to which variables are needed --
    wsave1      var byte    $A0     SYSTEM      ' location for W if in bank1
    wsave2      var byte    $120    SYSTEM      ' location for W if in bank2
    'wsave3      var byte    $1A0    SYSTEM      ' location for W if in bank3
    ' ------------------------------------------------------------------------------
    Below is a bit of untested code (I don't have a 16F628 nor 2 Available Rotary Encoders) I threw together to get you started. It did compile without errors (if you made the change to DT_INTS-14.bas above), just can't actually try it in a PIC (let alone your setup). This code should allow you do keep track of both the rotary encoders regardless of what else your program is doing.


    Code:
    Old_Bits       VAR BYTE
    New_Bits       VAR BYTE
    RotEnc1_val    VAR BYTE  'Connected to PORTB<4:5>
    RotEnc2_val    VAR BYTE  'Connected to PORTB<6:7>
    TRISB = %11110000
    RotEncDir      VAR BIT
    '************************
    ' SETUP YOUR LCD HERE!!!
    '************************
    
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,         Label,  Type, ResetFlag?
            INT_Handler    RBC_INT,  _Rot_Encoder,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @    INT_ENABLE   RBC_INT     ;RB Port Change Interrupt
    
    Old_Bits = PORTB & (%11110000)
    Main:
         LCDOUT $FE, 2,"ROT1:", DEC2 RotEnc1_val,"ROT2:", DEC2 RotEnc2_val
         pause 10     
    GOTO Main
    
    '---[RBC - interrupt handler]---------------------------------------------------
    Rot_Encoder:
         New_Bits = PORTB & (%11110000)
         IF (New_Bits & %00110000) = (Old_Bits & %00110000) then No_Change_Rot1
         RotEncDir = New_Bits.5 ^ Old_Bits.4
         if RotEncDir = 1 then
              RotEnc1_val = RotEnc1_val + 1
              if RotEnc1_val = 36 then RotEnc1_val = 0
         ELSE
              RotEnc1_val = RotEnc1_val - 1
              if RotEnc1_val = 255 then RotEnc1_val = 35
         ENDIF
    No_Change_Rot1:
         IF (New_Bits & %11000000) = (Old_Bits & %11000000) then DoneRotEnc
         RotEncDir = New_Bits.7 ^ Old_Bits.6
         if RotEncDir = 1 then
              RotEnc2_val = RotEnc2_val + 1
              if RotEnc2_val = 36 then RotEnc2_val = 0
         ELSE
              RotEnc2_val = RotEnc2_val - 1
              if RotEnc2_val = 255 then RotEnc2_val = 35
         ENDIF
    DoneRotEnc:
         Old_Bits = New_Bits
    @ INT_RETURN
    A couple of items to mention. It assumes the you have connected your rotary encoders with the "A" Pins on PORTB.4 and 6, and "B" Pins on PORTB.5 and 7. Also, you have to have pull-ups on all 4 lines. If it "sort-of" works, try switching the lines on the encoders to the opposite pins.

    I assumed you will configure you lcd on you own as needed.

    Also make sure the files downloaded from Darrel Taylor are in the some directory as the main program file.

    HTH,
    Steve B

  7. #7
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    WOW! Thanks Steve!

    Makes my code look like a 5 yo did it. LOL

    Ok, did what you said and commented out the line you highlighted.
    Then put both "DT_INTS-14.bas" and "ReEnterPBP.bas" into the same folder as your code.

    "DT_INTS-14.bas" had to be renamed because it downloaded as "DT_INTS-14[1].bas.txt"

    "ReEnterPBP.bas" had to be renamed because it downloaded as "ReEnterPBP.bas[1].bas.txt"

    When I try to compile it in PBP I get some errors. I am not used to asm includes so I might be doing something wrong.

    It is unable to load both include files and 3 other errors.

    See attached screencap

    Thanks,
    Smitty
    Attached Images Attached Images  

  8. #8
    Join Date
    May 2006
    Location
    Del Rio, TX, USA
    Posts
    343


    Did you find this post helpful? Yes | No

    Default

    Smitty,
    Try this on your cmd line:

    pbpw -p16f628 -ampasmwin yourfilename

    The trouble is actually two fold.
    1) PBP is DOS based, and does not like long file names. PBPW is ok with them.
    2) You need to use the MPASM assembler. So make sure it is installed before you run the above line! It is needed for the Macros, as well as if you make the switch to the 18F series.

    Out of curiosity, why not use MicroCode Studio?

    Good Night,
    Steve B

    EDIT: Use the name for your file on the above cmd line
    Last edited by SteveB; - 10th September 2006 at 14:18.

  9. #9
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by SteveB
    Smitty,
    .....
    Out of curiosity, why not use MicroCode Studio?
    .....
    Hi Smitty,

    As Steve B also asks about it here, is there a particular reason why you are not using MicroCode Studio?

    Also, for the encoder , don't you think that you can do what you need with one direction?

    If you think you can, then I can give you some piece of code for TMR1 and TMR0 so that you can set it up for reading the encoder, and suggest some ways of having the missing counts minimized.

    In your case, as much as I understood it, the degrees needed are wide enough to cover the missing counts.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  10. #10
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    After 5 hours trying to get things to work I am at a loss.

    And a bit hungry. LOL

    I dl and installed mplab and the plugins for pbp. I followed the instructions for setting it all up.

    I tried to compile from dos "pbpw -ampasmwin -p16f628" and also from mplab and get the same error "unable to execute mpasm".

    I set the path as directed for xp and have rechecked it.

    Even though everything I read said do not put mpasm.exe into the pbp directory, I tried it and it then got past unable to execute mpasm.

    Now I get about 117 errors starting off with cannot find 16f628.inc file. This file is in the same directory!

    Not sure what to try next.

    PBP v2.44
    MPlab v7.42

    Thank you for your help

    Smitty

  11. #11
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    I just did a little more testing and found that the photodiode reciever has a ramp up and a ramp down on the voltage. If turned to fast the voltage stays high. I do not think it is as easy as on/off pulses. That could explain the eratic behavior. If this is correct then I need to measure freq along with the change right? Or am I going in the wrong direction.

    I am looking at another alternative. A pair of mems 360deg inclinometers with spi output. Here:
    http://www.analog.com/en/prod/0%2C28...6203%2C00.html

    I ordered a couple of the pcb samples

    I love samples

    I have a couple of 16f876 lying around and they have spi.

  12. #12
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    if you don't need a 360 degree, a simple POT may do the job.
    A mechanical or optical encoder will work as well.
    Some photo detector (taken in VCR, Tape deck or else) like GPIA70R (if my memory is good) have to work AS-IS
    Last edited by mister_e; - 11th September 2006 at 04:46.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Quadrature encoder and ASM Interrupts. questions..
    By godfodder in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 17th March 2013, 14:45
  2. Instant Int and encoder (Elect. Gearing)
    By boroko in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 29th November 2009, 02:29
  3. encoder HEDL 5540
    By kutsi in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 11th June 2007, 14:00
  4. quad encoders
    By cpayne in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 13th March 2007, 17:49
  5. encoder wowes
    By wallaby in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 6th December 2005, 21:56

Members who have read this thread : 0

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