On Tue, 13 Apr 1999, Jason Wolfson wrote: > OK, now I'm starting to spin my wheels, > > What would be the best way to calculate > an arcTangent with a PIC? > > I have 2 values, x and y, values are 0-100, > I need to find an angle by taking the > arcTan of (y/x). I don't have the arctan(y/x) function, but I've got the arcsin which is pretty close (epecially for small angles). It's attached below. It's a look up table with first-order (linear) interpolation solution. You see other examples here: http://www.interstice.com/~sdattalo/technical/software/pic/picsine.html and http://www.interstice.com/~sdattalo/technical/software/pic/piclog.html for sin(x) and log(x) solutions. ;---------------------------------------------------------- ; ;arcsine ; ; The purpose of this routine is to take the arcsine of an ;8-bit number that ranges from 0 < x < 255/256. In other ;words, the input, x, is an unsigned fraction whose implicit ;divisor is 256. ; The output is in a conveniently awkward format of binary ;radians (brads?). The output corresponds to the range of zero ;to pi/2 for the normal arcsine function. Specifically, this ;algorithm computes: ; ; arcsine(x) = real_arcsine(x/256) * 256 / (pi/2) ; ; where, real_arcsine returns the real arcsine of its argument ;in radians. ; ; The algorithm is a table look-up algorithm plus first order ;linear interpolation. The psuedo code is: ; ;unsigned char arcsine(unigned char x) ;{ ; unsigned char i; ; ; i = x >> 4; ; return(arcsin[i] + ((arcsin[i+1] - arcsin[i]) * (x & 0xf))/16); ;} ; ; ; The accuracy is reasonable for x<150 or so. After that, the ;relatively steep arcsine severly deviates from a straight line ;approximation. The maximum error is around 5. arcsine SWAPF x,W ANDLW 0xf ADDLW 1 MOVWF temp ;Temporarily store the index CALL arc_sine_table ;Get a2=asin( (x>>4) + 1) MOVWF result ;Store temporarily in result DECF temp,W ;Get the saved index CALL arc_sine_table ;Get a1=asin( (x>>4) ) SUBWF result,W ;W=a2-a1, This is always positive. SUBWF result,F ;a1 = a1 - (a1-W) = W CLRF temp ;Clear the product CLRC BTFSC x,0 ADDWF temp,F RRF temp,F CLRC BTFSC x,1 ADDWF temp,F RRF temp,F CLRC BTFSC x,2 ADDWF temp,F RRF temp,F CLRC BTFSC x,3 ADDWF temp,F RRF temp,W ADDWF result,F RETURN arc_sine_table ADDWF PCL,F RETLW 0 RETLW 10 ;asin(1/16) = 3.583deg * 256/90 RETLW 20 RETLW 31 RETLW 41 RETLW 52 RETLW 63 RETLW 74 RETLW 85 RETLW 97 RETLW 110 RETLW 124 RETLW 138 RETLW 154 RETLW 173 RETLW 198 RETLW 240