Efficient Fixed-Point Trigonometry For PIC16F


Closed Thread
Results 1 to 13 of 13

Hybrid View

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


    Did you find this post helpful? Yes | No

    Default

    Carefull when using Banksel and PBP, i would suggest you to replace all BANKSEL for CHK?RP

    CHK?RP is to PBP what BANKSEL is to ASM.

    Using BANKSEL will make weird things and lost compiler because he don't know where he was before etc etc... i understand why... i just can't explain it correctly.

    Darrel could you shed some lights and explain it in english
    Steve

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

  2. #2
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    Thanks a lot mister_e,

    I added your suggestion, which will probably help in the long run. However, I still get the same result for Cos(x) = 71 no matter what I give as x. When edited out of some of the lines that had "global" in them, as suggested in an earlier post, was I supposed to replace "global" with something else? Here are some of the lines I deleted from various places in the program:

    GLOBAL X_L, X_H, Y_L, Y_H, Z_L, Z_H, SHIFT
    GLOBAL ATAN
    GLOBAL SINCOS
    GLOBAL Shifter

    I don't really understand what these lines did in the original assembly code.
    I also wonder if I defined any of the variables wrong. RV, Dir, _C, and _Z are defined inside the assembly code, and the other variables are named in the pbp code. Strange that the ATAN functions great, just the SINCOS having difficulties.

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    The Input to SINCOS is the Z variable. (Not X)

    I've got it working here, but it seems like it's not right.
    Input range is from -256 to +255.

    I've plotted the results. Does it look right to you?

    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2133&stc=1&d=119533895 6">
    <br>
    Attached Images Attached Images  
    DT

  4. #4
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    Actually, it is perfect!!!!
    They do something weird to signify the angle. For actual angle z, degrees = z * 90/256, or z/2.844444444444 = degrees. Output/1000 = the fractional result.

    Attached is part of their excel spread sheet showing inputs and outputs vs actuals.
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2134&d=1195310172">
    Many thanks for your time,

    Walter
    Attached Images Attached Images  
    Last edited by ScaleRobotics; - 17th November 2007 at 16:17.

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    For actual angle z, degrees = z * 90/256
    That helps! Now the SIN and COS results all fall into place.

    But, still having problems with the ATAN function.
    Can't seem to get anything meaningfull out of it.
    And that spreadsheet won't run for me, so I can't tell what it's supposed to do.

    Do you have any examples for that too?
    <br>
    DT

  6. #6
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    I have another excel example that I will post (when I get to my other computer).This one can't look at it either. But basically, it works like this:

    Enter X and Y co-ordinates like x = 12631 and y = 11881, then perform atan.

    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2136&d=1195349246">

    The accuracy shows that when either x or y is really low, that errors in the way it simplifies the equation are a bit large. But with higher numbers, the accuracy is within one degree or so.

    Result pops out as Z. Z is the angle to the co-ordinates. (if I remember right the answer was 134?), but it is in the same weird format. Z * 90 / 256 gets you back to a readable degree format, which if I remember right give you about 47 degrees. You will have to know what quadrant you are in to figure out if you add 90 degrees to result by figuring out if x or y or both are positive or negative.

    I made the 20 mhz PIC do 10,000 of these calculations, and it took less than 5 seconds. Over 2000 per second! Pretty cool!
    I wish I got this excited about trig 22 years ago, when I was taking the class ......
    Attached Images Attached Images  
    Last edited by ScaleRobotics; - 18th November 2007 at 02:35.

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


    Did you find this post helpful? Yes | No

    Default

    looking at the asm... i'm aware that my asm skills sucks, but, i don't understand why they used the line in red...
    Code:
    ATAN
    	banksel	   _Z_H				; Z_H & Z_L is loaded with 0x0000
    	movlw		0x00				; Y & X is the input
    	movwf		_Z_H				; X(i+1)	=	Xi - Yi*_Di*2^-i
    	movlw		0x00				; Y(I+1)	=	Yi + Xi*_Di*2^-i
    	movwf		_Z_L				; Z(i+1)	=	Zi - _Di*ATAN(2^-i)
    	banksel	   _Di					; _Di		=	1 if Yi < 0 ELSE _Di	=	0
    	bsf		      RV					; Set Vectoring Mode
    	goto		CORDIC_Alg		
    
    SINCOS
    	banksel	   _Y_L				; Z_H & Z_L is the input
    	movlw		0x00				; Y_H & Y_L is loaded with 0x0000	
    	movwf		_Y_L				; X_H & X_L is loaded with 6070 (1/An constant)
    	movlw		0x00			
    	movwf		_Y_H			
    	movlw		LOW .6070	
    	movwf		_X_L				; X(i+1)	=	Xi - Yi*_Di*2^-i
    	movlw		HIGH .6070		; Y(I+1)	=	Yi + Xi*_Di*2^-i
    	movwf		_X_H				; Z(i+1)	=	Zi - _Di*ATAN(2^-i)
    	banksel	   _Di					; _Di		=	0 if Zi < 0 ELSE _Di	=	1
    	bcf		      RV					; Set Rotational Mode
    w already hold 0x00 and they reload it again for the next MOVWF? BTW i would use CLRF instead... no big deal, it remove 4 instructions... long run, it may decrease a little bit the calculation latency. OK OK no big improvement, but... i couldn't resist. maybe i'll find something else?

    so, once modified, the above code section should look like...
    Code:
    ATAN
    	CHK?RP	_Z_H		; Z_H & Z_L is loaded with 0x0000
    				; Y & X is the input
    	clrf	_Z_H		; X(i+1) = Xi - Yi*_Di*2^-i
    				; Y(I+1) = Yi + Xi*_Di*2^-i
    	clrf	_Z_L		; Z(i+1) = Zi - _Di*ATAN(2^-i)
    	CHK?RP	_Di		; _Di	 = 1 if Yi < 0 ELSE _Di	= 0
    	bsf	RV		; Set Vectoring Mode
    	goto	CORDIC_Alg		
    
    SINCOS
    	CHK?RP	_Y_L		; Z_H & Z_L is the input
    				; Y_H & Y_L is loaded with 0x0000	
    	clrf	_Y_L		; X_H & X_L is loaded with 6070 (1/An constant)
    				
    	clrf	_Y_H	
    	movlw	LOW .6070
    	movwf	_X_L		; X(i+1) = Xi - Yi*_Di*2^-i
    	movlw	HIGH .6070	; Y(I+1) = Yi + Xi*_Di*2^-i
    	movwf	_X_H		; Z(i+1) = Zi - _Di*ATAN(2^-i)
    	CHK?RP	_Di		; _Di	 = 0 if Zi < 0 ELSE _Di	= 1
    	bcf	RV		; Set Rotational Mode
    But yeah, i think we're not at the optimization stage yet
    Last edited by mister_e; - 18th November 2007 at 03:34.
    Steve

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

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