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

    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 13:14.

  2. #2
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Hmmm..
    I got the program to compile and work with interrupts on portB<4:7>

    Ill try to implement the quadrature decoding in assembly now..

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


    Did you find this post helpful? Yes | No

    Default

    Example from:
    http://www.microengineeringlabs.com/...manual/9_0.htm

    Luciano

    Code:
    	' Assembly language interrupt example
    
    	led	 var	PORTB.1
    
    	wsave var	byte $20 system
    	ssave var	byte bank0 system
    	psave var	byte bank0 system
    
    
    	Goto start	' Skip around interrupt handler
    
    	' Define interrupt handler
    	define INTHAND myint
    
    	' Assembly language interrupt handler
    	asm
    	; Save W, STATUS and PCLATH registers
    	myint	movwf	wsave
    		swapf	STATUS, W
    		clrf	STATUS
    		movwf	ssave
    		movf	PCLATH, W
    		movwf	psave
    
    	; Insert interrupt code here
    	; Save and restore FSR if used
    
    		bsf	_led	; Turn on LED (for example)
    
    	; Restore PCLATH, STATUS and W registers
    		movf	psave, W
    		movwf	PCLATH
    		swapf	ssave, W
    		movwf	STATUS
    		swapf	wsave, F
    		swapf	wsave, W
    		retfie
    	endasm
    
    	' PICBASIC PRO™ program starts here
    	start: Low led	' Turn LED off
    
    	' Enable interrupt on PORTB.0
    		INTCON = %10010000
    
    	loop:	Goto loop	' Wait here till interrupted

  4. #4
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default

    Thanks Luciano,
    But it's the same program as in the datasheet...
    Im now trying to write the decoding program in assembly..

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


    Did you find this post helpful? Yes | No

    Default

    Rotary encoder in assembly for 16F84:
    http://emp.byui.edu/fisherr/EET255/encdr.asm

    Luciano

  6. #6
    ice's Avatar
    ice Guest


    Did you find this post helpful? Yes | No

    Default interrupts are interrupting LCDout

    Luciano,
    I added the code from the lin you posted..
    I'm using interrupt on INT0 connected to channel A..


    I'm able to count and detect directions..with 1 big problem

    i cannot monitor or dispaly the counts either using LCDout or software serial to hyperterminal.
    it's good for 2 seconds and then the whole LCD screen corrupts
    ...is it because the LCDout line is being interrupted by the encoder
    ...if i disable/enable interrupts within the LCDout line..i lose encoder counts


    in the code..i use 2 leds connected to portB.6,7 to show direction.
    LOOP is my main program

    my code is below
    Code:
    		GoTo start 					' Skip around interrupt handler	
    
    
    		DEFINE INTHAND display			' DEFINE INTERRUPT handler
    		Asm
    display 
    		movwf	wsave
    		swapf	STATUS, W
    		clrf	STATUS
    		movwf	ssave
    		movf	PCLATH, W
    		movwf	psave
    		
    	
    		;;;bsf _led 						; Turn on LED (for example)
    		;new=PORTB & %11000000
    
    		;Get intitial input from ENCODER & put the value in OLD.
         	movf	PORTB,W
         	movlw   _old
    
         	;Strip off all but the last  2 LSBs in OLD.
    		movlw	0x03				;Create bit mask for 2 LSBs (bits 6 & 7). 11000000
         	andwf	_old,F          	;Zero bits 0 thru 6.
    
    		;Read latest input from ENCODER & put the value in NEW.
        	movf    PORTB,W
         	movwf	_new
    
         	;Strip off all but the 2 LSBs in OLD.
    		movlw	0x03				;Create bit mask for 2 LSBs (bits 6 & 7). 11000000
         	andwf   _new,F     			;Zero bits 0 thru 6.
    
    
    
    
    
         	movf	_new,W				;Move the contents of NEW to TEMP and OLD to W
         	movwf   _temp      			;in order to compare them with XOR.
         	movf    _old,W     
         	xorwf   _temp,F    			;XOR previous inputs (in W) with latest inputs 
                             			;(in TEMP) to see if they are equal.
         	btfsc   STATUS,Z  			;Test result and skip next line if 0.
         	
         	GoTo	rtrn				;Result is 0.  Previous inputs equal latest 
                             			;inputs.  Rotary encoder did not move.  Return
                             			;to loop
         	
        	;Result is 1.  Rotary encoder moved.  Determine direction.
         	bcf		STATUS,C  			;Clear the carry bit in the status register and
         	rlf     _old,F     			;left shift it into OLD to align bit0 of OLD
                             			;with bit 1 of NEW.
         	movf    _new,W     			;Move the contents of NEW to W in order to XOR.
         	xorwf   _old,F    			;XOR previous inputs (in OLD) with latest
                             			;inputs (in W) to determine CW or CCW.
         	btfsc   _old,1     			;Test bit 1 of result (in OLD).  Skip next line
                             			;if it is 0 (direction is CCW).
         	GoTo    Up        			;Bit is 1 (direction is CW).  Go around Down
         	
         	
         	
    Down
         	;Decrements COUNTER because encoder moved CCW.
    
         	decf	_enc_counter,F 
         	bsf		_led
         	GoTo    rtrn  				;Branch around UP.
    
    Up
         	;Increments COUNTER because encoder moved CW.
    
         	incf    _enc_counter,F
         	bsf		_led2     	
                             			;and increment counter.
    
         	
    rtrn	bcf intcon.1				; clear interrupt flag 
    	    
    	    ; Restore PCLATH, STATUS and W registers
    		movf	psave, W
    		movwf	PCLATH
    		swapf	ssave, W
    		movwf	STATUS
    		swapf	wsave, F
    		swapf	wsave, W
    		retfie
    		EndAsm
     
    start:
    		
    		'SerOut PORTC.0,T9600,[#enc_counter,10,13]
    		TRISB=%00111111
    		TRISC=%00000000
    		Low led 	
    		Low led2				' Turn LED off
    		INTCON = %10010000		' Enable INTERRUPT ON portb INT0
    		option_reg=%01110000
          	
    loop: 	
    		'INTCON = %00000000
    		'LCDOut $fe,1,DEC enc_counter
    		'Pause 4
    		'INTCON = %10010000
    		Low led
    		Low led2
    		GoTo loop
    Last edited by ice; - 11th May 2005 at 11:41.

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


    Did you find this post helpful? Yes | No

    Thumbs down

    Hi!

    If you use INT0 you will lose encoder counts.
    See my Incremental quadrature encoder direction drawing.
    (File encoder.zip posted the 9th April 2005, 13:44).

    The two encoder signals A/B have to be connected to two of
    the PINs RB<7:4> which have an interrupt-onchange feature.

    * * *
    When I post a code sample, the code is well formatted and
    there are no dead commented statements.(I do my best).
    Do you think that people on this forum will spend time
    reading your code if it is not formatted?

    * * *

    See thread LCDOUT & interrupts.
    http://www.picbasic.co.uk/forum/show...dout+interrupt

    * * *

    Luciano

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