Searching \ for 'calculate arcTan on a PIC' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'calculate arcTan on a PIC'.

Truncated match.
PICList Thread
'calculate arcTan on a PIC'
1999\04\13@190655 by Jason Wolfson

flavicon
face
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).

thanks
Jason Wolfson

1999\04\13@191520 by Dave VanHorn

flavicon
face
> What would be the best way to calculate
> an arcTangent with a PIC?

Me, I'd use a lookup table.

1999\04\13@200513 by wagnerl

picon face
A 200 bytes table would do it (2 bytes per entry), Intermediate values
could be easily calculated by interpolation with a minimum error between
each table entry. For example:

X/Y could be from 0 to 1, equivalent to 0 to 45¡
(from 45¡ to 90¡ is the same as ATan(Y/X).

Table entry 000 = 00000, representing 0¡
Table entry 100 = 45000, (AFC8h) representing 45¡.
(Table values means angle times 1000).

Considere X/Y = 0.167,
table entry 16 is "9090" (2382h) [9.090¡]
table entry 17 is "9648" (25B0h) [9.648¡]
so 9648-9090 = 558 (table step). [0.558¡]

The third decimal digit from the division x/y is 7, means 70% from 0.16
and 0.17, so the correspondent interpolation is 558 x 70% = 390.6
(multiplication routine rounds to 391) [0.391¡], that you need to add to
the 16th table entry "9090", so the result would be decimal 9481
(2509h),

Convert it (2509h) to decimal (9481) and let three digits after the
decimal point, resulting in 9.481¡. The real ATan(0.167) =
9.480903...¡, so a 0.001% of error in a 16 bits table is pretty good.  

Whenever Y > X, invert the formula, use Y/X instead and the result would
be 90¡ less the angle found.

To increase the resolution, increase the table entries from 100 to 200.

Wagner

Jason Wolfson wrote:
{Quote hidden}

1999\04\13@210607 by Gerhard Fiedler

picon face
At 19:02 04/13/99 -0400, 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).

like dave said, a table is probably the best. look at scott dattalo's sine
function for a 2-dim example. but you either have 3 dimensions (like
(x,y)->angle) or do a division first, and then you'd possibly have to cope
with a big range of possible values. depends on range/precision/resolution
requirements.

ge

1999\04\13@210614 by Scott Dattalo

face
flavicon
face
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

1999\04\14@060956 by Sebastián Dols

flavicon
face
>
>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).
>

If speed is a must or you do not want to spend a lot of time coding,  I
think that the best way is a lookup table, but memory space maybe will be a
problem, 100*100 values are 10.000 possible results. Perhaps if you discard
some (or a lot) not resolutive values (mostly around x/y ~ +-pi/2) and fill
the EEPROM of a PIC..

If space is a must, I think that the best approach is to implement the
Taylor series of  the arcTan(x/y), but surely this will be hard to code, or
at least not very easy. Sorry, I don't remember now the Taylor serie of an
arcTan, but you could find easily in a lot of calculus books.

Hope this help

1999\04\15@134123 by Kolesnikoff, Paul

flavicon
face
Jason,
I've looked into this, but never implemented it. However, the first thing
you need to do is determine the level of accuracy required. The method I'll
outline will give you accuracy to about a sixth of a degree. The tangent
like all trig functions repeats in absolute value through each quadrant. The
quadrant that you are in is determined by the sign of x and y. In addition,
in each quadrant, one end is asymptotic because the denominator approaches
0. However, you will find that the asymptotic half of each quadrant is the
inverse of the half that is less than one. Therefore, if you divide by the
greater of x or y, you can always have a well behaved output (no divide by 0
problems). Since this is an 8-bit processor, you can get a ratio up to the
range of 0-255 (scqle your division operation to produce this). If you use
this ratio value as an offset address into a look-up table, you can return a
angular value in the range 0 to 45 degrees.  Then you do a little
housekeeping.

Assuming the variable "angle" is in the range 0-45 degrees, then

If y>x then  angle = 90 - angle

if x<0 and y<0 then angle = angle +180

if x<0 and y>0 then angle = 180 - angle

if x>0 and y<0 then angle = 0 - angle

I notice that your x and y values are in the range 0-100. If this means that
all your angles are in the first quadrant, then you can skip the quadrant
selection process. If a value of 50 is your zero level, then adjust the
quadrant selection accordingly. Also, if you need less than 1/6 degree
resolution, then just use a smaller lookup table, and adjust your division
process accordingly. If you need more resolution, you have to go to 16 bits.


Since I have to actually implement this as soon as time allows, I'd
appreciate it if you let me know how the project went.
Good Luck,
Paul Kolesnikoff


             {Original Message removed}

1999\04\15@140209 by Jason Wolfson

flavicon
face
Paul,
The 8-quadrant, <1 X/Y method is what I have come to the
conclusion is best also. I only need 1 degree accuracy.
I will have to do a fixed point division to do an interpolation,
but it looks like it will work great with only a 25 element table.

I'll send an update as soon as I'm done and it's working.
thanks for all the help, especially Scott and Wagner who pointed me in this
direction!

thanks
Jason Wolfson...


{Quote hidden}

>               {Original Message removed}

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...