Quad encoder problems


Closed Thread
Results 1 to 40 of 52

Hybrid View

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

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

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

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

  5. #5
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default 7 hours and still trying

    I just tried microcode studio and get the same errors. Cant find 16F628.inc

    This file is in the pbp directory, I do not understand.

    sayzer, Thanks for the offer but I do need both directions to be able to tell if it is a right or left roll ,an up or down pitch and how far for both.

    Microcode studio is pretty sweet I must say. Thanks for recommending it.

    Smitty

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


    Did you find this post helpful? Yes | No

    Default

    You did restart your computer, right? Well, if we don't have any success going that route, there are alternatives.

    Look at the code in the Interrupt Handler. Put this in your main loop, so it repeatedly checks PORTB for changes. Like This:

    Code:
    '************************
    '  DEFINE your OSC 
    '  and any other
    '  configuation items
    '************************
    
    
    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!!!
    '************************
    
    Old_Bits = PORTB & (%11110000)
    
    Main:
         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
         
         LCDOUT $FE, 2,"ROT1:", DEC2 RotEnc1_val,"ROT2:", DEC2 RotEnc2_val
    GOTO Main



    Let's walk before we run and get this working.

    Steve

  7. #7
    Join Date
    Sep 2006
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    Steve,
    Yup, restarted pc many times. LOL. I would really like to know what the problem is. I guess I will have to look into it further.

    You said "Look at the code in the Interrupt Handler. Put this in your main loop"

    Did you mean to compile just the code you listed or to add it to one of the others? If you meant by itself then it compiled just fine.

    I tried it out and had some strange readings. It starts with Rot1:00 and Rot2:35. When I rotate the encoders nothing happens.

    To test and see if it was the encoder or the program, I unpluged the a & b chanels from encoder 1 and alternately touched them to ground and the numbers changed. This makes me think something is wrong in the encoder circuit. I played arround with different values on the resistors to no avail. The encoders output a positive voltage between ~1.85 and 5 and I have 4.7K resistors pulled to ground on each channel.

    I did notice if I was under a bright light and held the encoders at just the right angle the numbers changed but they were jumping arround and not going 1.2.3.4~.

    Man I didnt think encoders were so tough.

    Smitty

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


    Did you find this post helpful? Yes | No

    Default

    Smitty,

    You said "Look at the code in the Interrupt Handler. Put this in your main loop"

    Did you mean to compile just the code you listed or to add it to one of the others? If you meant by itself then it compiled just fine.
    Just use the "new code" in the last post by itself (I did the moving for you).

    It starts with Rot1:00 and Rot2:35
    Add something like this just below the variable declarations to give an initial starting value.

    RotEnc1_val = 0
    RotEnc2_val = 0


    OK. Do you have the datasheet for the encoders? I assumed (always bad) that they where mechanical encoders, similar to the one shown here. Hook-up as per the nice diagram.

    If they are not mechanical encoders, then they are optical. If so, they will have a Vcc, GND, ChA, and ChB. Also, no pull-ups (or downs) required.

    At least it looks like the code is working. More info please.

    Steve

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by smitty505000
    The encoders output a positive voltage between ~1.85 and 5 and I have 4.7K resistors pulled to ground on each channel.
    So it's never 0V? @1.85 you're probably sometimes in-between Low and High logic Level. You may need to 'filter' it a little bit to avoid oddity.

    1.Use the internal voltage comparator, set the threshold and use their interrupt to increment the counter.
    OR
    2.try something like...
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1067&stc=1&d=115794620 6">
    maybe one diode could be enough... maybe not
    HTH
    Attached Images Attached Images  
    Last edited by mister_e; - 11th September 2006 at 04:54.
    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