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

    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 10:55.

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


    Did you find this post helpful? Yes | No

    Default

    Hi!

    I need more info.

    The version of the PIC used. (16F628, 16F628A, ...).

    If you are using a commercial board for the PIC, I need
    the URL where I can see the board.

    The brand and model number of the encoder and the URL where I can
    download the data sheet.

    I also need to know how you have connected the encoder to
    PORTB.0 and PORTB.1. (Pull-up resistors? If yes, values).


    Luciano

  3. #3
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Luciano,

    The version of the PIC used. (16F628, 16F628A, ...).
    im using the PIC16F873A

    If you are using a commercial board for the PIC, I need
    the URL where I can see the board.
    I made my own dev board..has an LCD,A/D..the usual features..
    works on a 4Mhz crystal..
    The board works perfectly as i have run accelerometers,D/A converters from the same board


    The brand and model number of the encoder and the URL where I can
    download the data sheet.
    Maxon 22578
    500 counts per turn
    http://www.maxonmotor.com/docsx/Down...f/05_238_e.pdf

    I also need to know how you have connected the encoder to
    PORTB.0 and PORTB.1. (Pull-up resistors? If yes, values).
    Pull up resistors
    with value 1.8K


    Thanks for all your help
    Last edited by ice; - 5th May 2005 at 07:39.

  4. #4
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default progress

    ok,a little progress,
    seems like i'm loosing counts ,because of the LCDout commands

    if i make my code tighter[remove the LCDcommands],i am able to monitor direction ,but a bit of interference still persists.
    I'm on a 4Mhz..i'll switch to a 20Mhz tomorrow and post my progress

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


    Did you find this post helpful? Yes | No

    Default

    When you try the example code with the LCD, turn the encoder very slowly
    with your fingers.(About 1 degree per second).The example is just to see
    that the decode technique works.

    For the real code you need to use the interrupt-onchange feature, and the
    code has to be written in assembly otherwise you will lose encoder counts.
    (Read the PicBasic Manual about interrupts in Basic and assembly).

    The encoder and pull-up resistors are OK.

    Luciano

  6. #6
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    yes works beautifully at 3 degrres per second,im using PWM thru a motor driver...the decode program works well

    ill have to work on the interrupts..it will take time...
    is there an example or "guide" code in assembly..it's a bit confusing in assembly,.
    Ill try it anyway,will keep you posted.

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


    Did you find this post helpful? Yes | No

    Default

    Hello,

    Probably you already know that.An interrupt in PicBasic
    language will not work for the rotary encoder.
    You must use an interrupt in assembly.

    The assembly code for the interrupt will be simple.
    In addition of what you have to save and restore
    for the correct functioning of PicBasic, the assembly
    code for the rotary encoder is just detect its direction
    and increase or decrease the counter variable and maybe set
    a flag for the direction if you need this info in the basic program.
    The rest is done by the basic program once you exit the assembly
    interrupt routine.

    Read section 29 Instruction Set of the Mid-Range MCU Family Reference Manual.
    http://ww1.microchip.com/downloads/e...Doc/33023a.pdf

    To do:

    Understand the differences between interrupts in PicBasic and
    interrupts in assembly and understand why you need an assembly
    interrupt for your rotary encoder. (PicBasic Manual).

    How to declare a variable in basic and use
    it in the interrupt assembly code. (Share variables
    between basic and assembly, see PicBasic Manual).

    Understand what you need to save and restore when
    you enter and exit the assembly interrupt. (PicBasic Manual).

    In PicBasic language, try first the interrupt-onchange feature.
    The A/B signals of the encoder will be connected of two of
    these PINs that have the interrupt-onchange feature.
    (This is not the interrupt on RB0).
    Once the interrupt-onchange feature works in basic then
    you will be ready to implement that in assembly.

    RB<7:4>, have an interrupt-onchange feature.

    Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange
    feature. Only pins configured as inputs can
    cause this interrupt to occur (i.e., any RB<7:4> pin configured
    as an output is excluded from the interrupt-onchange
    comparison). The input pins (of RB7:RB4) are
    compared with the old value latched on the last read of
    PORTB. The “mismatch” outputs of RB7:RB4 are
    OR’ed together to generate the RBIF interrupt (flag
    latched in INTCON<0>).

    INTCON = %10001000 'Enable RBIE
    INTCON.0 = 0 'Clear Port Change Interrupt Flag bit

    Read section 8 of the Mid-Range MCU Family Reference Manual.
    http://ww1.microchip.com/downloads/e...Doc/33023a.pdf

    AN566 - Using the PORTB Interrupt on Change as an External Interrupt.
    http://ww1.microchip.com/downloads/e...tes/00566b.pdf

    Best regards,

    Luciano

  8. #8
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Thanks Luciano,
    Im read up the pbp manual and others for interrupts...
    ..however my test program isnt compiling..

    Code:
    		wsave 	VAR BYTE $20 system				'bank0
    		wsave1 	VAR BYTE $a0 system				'bank1
    		'wsave2 	VAR BYTE $120 system		'bank2
    		'wsave3 	VAR BYTE $1a0 system		'bank3
    		ssave 	VAR BYTE bank0 system
    		psave 	VAR BYTE bank0 system
    		led 	VAR PORTB.1
    		
    		GoTo start_0 					' Skip around interrupt handler	
    
    
    		DEFINE INTLHAND myint			' DEFINE INTERRUPT handler
    		Asm
    myint:	bsf _led 						; Turn on LED (for example)
    		bcf intcon.0
    				
    		retfie
    		EndAsm
        
    	
    		
    										' Assembly language INTERRUPT handler    
    		
    
        
    start_0:
    		
    		TRISB=%11111101	
    		Low led 						' Turn LED off
    		INTCON = %10001000				' Enable INTERRUPT ON PORTB.0
            
    	
    loop: 		GoTo loop 						' Wait here till interrupted
    1> compile error "DEFINE INTHAND myint"
    ....undefined symbol myint
    however if i relpace it with DEFINE INTLHAND myint,(which is only for th 18x series),it complies ok..

    2>im using a 16F873A,which has a 4K flash,meaning 4 banks...
    according to the PBP manual, i have to define wsave,wsave1,wsave2,wsave3...
    it takes in wsave and wsave1...but when i declare wsave2 and wsave3..it gives a RAM_END 255 error

    3>i cannot get the LED to blink either by using the int0 or the Interr On change<4:7>
    Last edited by ice; - 6th May 2005 at 12:14.

Similar Threads

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

Members who have read this thread : 4

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