decoding quadrature encoders


Closed Thread
Results 1 to 40 of 94

Hybrid View

  1. #1
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Thank you for all your help.
    Theres a small problem though.

    The encoder program counts faster in one direction and slower in the other...

    is it because ...
    When im counting in one of the directions ,im utilizing the ADC[ADCIN and an IF statement]

    ..whereas in the other direction,im not.
    The program logic is the same as above.
    Last edited by ice; - 18th April 2005 at 09:38.

  2. #2
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    I don't understand.
    If you need help post your code.

    Luciano

  3. #3
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    before i go ahead with my code....ill explain wht i have to do

    I need to control the position of a DC motor[geared],using a potentiometer

    I have to first detect the endpoints of a gear assembly.
    say, i start with a count of 32500 and the count at one end of the gear assembly is 32600
    ..now i rotate it to the other side ,say the count at this point is 32400

    The above was just the calibration routine.Using the above values ,i have to
    scale the 200 counts[32600-32400] to a potentiometer value[0 to 255]

    How am i detecting the end points?
    ..im using the LMD18200T motor driver .Using the current sense feature of the chip,i detect wheteher the gear assembly has reached an end point.The current sense pin is connected to an ADC port..portA.1 namely


    my program flow...
    1> set counter to 32500
    2> move motor in one direction
    3> count pulses..if CW,increment.if CCW decrement
    ...say it is CW and counter increments to 32600 till the end
    4>counter_1 has 32600
    5>move the motor to the other side,count the pulses..it is decrementing now
    6>so counter_2 has 32400
    7>now i have to scale the gear assembly range to a potentiometer
    difference=counter_1-counter_2
    =32600-32400
    =200
    8> scale to a pot value
    pot_val holds the pot value connected to analog portA.0

    hence required count value=[difference/256]*pot_val+counter_2
    =[difference*pot_val]/256+counter_2 (rearranging)

    example...if potvalue in 128,then
    required count value=(200*128)/256+32400
    =32500

    now i dont know where to go from here..how do i get the motor to move to position 32500,when the pot is moved to 128

    ...this is a long post..but its the best i could do to explain wht im trying to do.
    -Gerry

  4. #4
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    If you are losing encoder counts, then use an interrupt service routine.
    Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange feature.
    Use two of these pins for the A/B encoder signals.

    Luciano

  5. #5
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    ok,heres my program ,using interrupts..

    the problems i'm encountering are below the code
    ..
    Code:
    DEFINE LOADER_USED 1
    
    
    led     VAR     PORTB.7
    old 			VAR BYTE
    new 			VAR BYTE
    direction_bit 	VAR BIT
    counter 		VAR WORD
    counter_1		VAR WORD
    counter_2		VAR WORD
    direction_store	VAR BIT
    adval			VAR	WORD				' Create adval to store result
    potval			VAR WORD
    servo_val		VAR	WORD
    difference		VAR WORD
    	
    
    counter=32500		
    	
        	HPwm 0,150,20000    
            OPTION_REG = $7f        
            ON INTERRUPT GoTo myint     ' Define interrupt handler
            INTCON = $90                     ' Enable INTE interrupt
    
    	
    
    loop:   High led                ' Turn LED on
    
    		LCDOut $fe,1,"count:"
    		LCDOut $fe,$c0,DEC counter
    		'Pause 10
    		
            GoTo loop               ' Do it forever
    
    
    
    
    		' Interrupt handler
            Disable                 ' No interrupts past this point
    myint:  Low led                 ' If we get here, turn LED off
           
           
    enc:    new= PORTB & %00000011
    
    
    start_1:
    		old=new & %00000011	
    		
    again:
    
    		new= PORTB & %00000011					'load new value of A/B channels into new by anding with HEX3
    			
    		
    	    'IF new=old Then again
    	    direction_bit=old.bit1 ^ new.bit0		'check direction 
    	
    		
    		IF direction_bit = 1 Then  
    		LCDOut $fe,1,"Last was CW"
    		counter = counter + 1				'increment counter
    		LCDOut $fe,$c0,DEC counter," ",BIN direction_bit
    	
    		Else
    			LCDOut $fe,1,"Last was CCW"
    			counter = counter - 1				'decrement counter
    			LCDOut $fe,$c0,DEC counter," ", BIN direction_bit	
    		
    		EndIF
    		Pause 10
    	   			
    
                  
    		INTCON.1 = 0           ' Clear interrupt flag
    	    Resume                 ' Return to main program
    	    Enable
    1>The interrupts are worng fine,however the code is still unable to distinguish between CW and CCW,because of which the counting goes awry..

    2>if i remove the "if then " statement for CW/CCW direction and only put a
    counter=counter+1,it works well


    The whole problem seems to be the direction decoding part..
    ..i cant seem to find a solution to it..
    Last edited by ice; - 3rd May 2005 at 14:00.

  6. #6
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Hi!

    1.
    You are using the wrong interrupt.
    Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange feature.
    Use two of these pins for the A/B encoder signals.

    2.
    Use assembly code for the interrupt.
    (See PicBasic Pro manual).

    3.
    In your code the variables "new" and "old" will have
    most of the time the same values.

    In your code you are doing that:

    new= PORTB & %00000011 'get encoder A/B
    old=new & %00000011 'old is now same as new
    new= PORTB & %00000011 'get encoder A/B again

    When you get A/B again, it is very likely that the encoder is
    still in the same position, therefore the variables new and old
    will have the same values.

    * * * *

    Did you try the code I posted the 12th April 2005, 11:00?
    Does it work if you turn the encoder slowly?

    Luciano

  7. #7
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Luciano,

    when i try the program u recommended [12th april] as below,
    there are alot of instances when the program gets confused with direction,
    so it sometime increments and decrements.Im not using interrupts

    when i move the motor slowly,the problem still persists.

    Code:
    old_val 		VAR BYTE
    new_val 		VAR BYTE
    direction_bit 	VAR BIT
    enc_counter 	VAR WORD
    adval			VAR	WORD				' Create adval to store result
    potval			VAR WORD
    servo_val		VAR	WORD
    difference		VAR WORD
    	
    TRISB=%11111111
    enc_counter=32500		
    HPwm 0,100,20000	
        
    	
    
    	new_val = PORTB & %00000011
    start:
    	old_val = new_val
    	
    	
    again:
    	new_val = PORTB & %00000011
    	'LCDOut $fe,1,"no move"
    	IF new_val = old_val Then again
    
    	direction_bit = old_val.bit0 ^ new_val.bit1
    	
    	IF direction_bit = 1 Then  
    	
    		LCDOut $fe,1,"Last was CW"
    		enc_counter = enc_counter + 1
    		LCDOut $fe,$c0,DEC enc_counter
    
    	Else
    		LCDOut $fe,1,"Last was CCW"
    		enc_counter = enc_counter - 1
    		LCDOut $fe,$c0,DEC enc_counter	
    	
    	EndIF
        	GoTo start
    Thank you for your responses
    Last edited by ice; - 4th May 2005 at 11:55.

Similar Threads

  1. Quick thoughts: DT Ints with encoders
    By kevlar129bp in forum mel PIC BASIC Pro
    Replies: 19
    Last Post: - 7th January 2010, 02:01
  2. PMDC SERVO MOTOR WITH quadrature encoder DRIVE ?
    By phoenix_1 in forum Schematics
    Replies: 37
    Last Post: - 22nd November 2009, 20:45
  3. 32-bit Quadrature Counter With Serial Interface
    By precision in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 10th June 2008, 03:49
  4. quad encoders
    By cpayne in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 13th March 2007, 18:49
  5. "momentary" IR decoding
    By sporker in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th June 2005, 02:53

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