Sine & Cosine Calculator

Tips, Tricks and methods for programming, learn ways of making your programming life easier, and share your knowledge with others.

Moderators: Benj, Mods

User avatar
JohnCrow
Valued Contributor
Valued Contributor
Posts: 1367
Joined: Wed Sep 19, 2007 1:21 pm
Location: Lincolnshire
Has thanked: 381 times
Been thanked: 715 times
Contact:

Sine & Cosine Calculator

Postby JohnCrow » Fri Apr 13, 2012 6:48 pm

Flowcode for 8bit pics does not have a function for calculating sines and cosines.
This means the use of either a 16bit device, or calculating the value by some method.

This is one of several ways of doing it. This only needs the basic float calculation functions. (fmul, fdiv, fadd, fsub)

It is quite easy to calculate a reasonable approximation of the value by means of the attached program.

I have written in FC4 so as to make it available to as many users as possible.

Sine-Cosine Calculator.fcf
(11 KiB) Downloaded 602 times


The value for the angle to be calculated is entered in the first calculation icon in either sine or cosine macro. The program takes care of conversion to radians.
Decimal angles can be used.

It is not as accurate as a calculator etc, and will fall off in accuracy after about 4 or 5 places.
It also only seems to work for angles <= 180 degrees
These users thanked the author JohnCrow for the post (total 4):
JonnyW (Fri Apr 13, 2012 9:22 pm) • medelec35 (Fri Apr 13, 2012 9:28 pm) • Enamul (Fri Aug 17, 2012 3:47 pm) • Benj (Tue Aug 21, 2012 10:19 am)
Rating: 21.05%
 
1 in 10 people understand binary, the other one doesn't !

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 64 times
Been thanked: 306 times
Contact:

Re: Sine & Cosine Calculator

Postby JonnyW » Fri Apr 13, 2012 9:30 pm

Very nice. We hope in future versions of Flowcode to standardize the functions available as its a shame the PIC does not have the functions available on other platforms. It would be nice to use something like this as a start!

The function only works for angles up to 180deg as the curve has only 2 turning points and these are at PI/2 and -PI/2. To make it work from 0 to 360 subtract 360 from 'deg' if it is over 180 degrees:
deg = deg - 360 * (deg >= 180)

Jonny
These users thanked the author JonnyW for the post (total 3):
medelec35 (Fri Apr 13, 2012 10:45 pm) • JohnCrow (Sat Apr 14, 2012 8:44 am) • Enamul (Mon Aug 20, 2012 6:31 pm)
Rating: 15.79%
 

User avatar
Enamul
Posts: 1772
Joined: Mon Mar 05, 2012 11:34 pm
Location: Nottingham, UK
Has thanked: 271 times
Been thanked: 814 times
Contact:

Re: Sine & Cosine Calculator

Postby Enamul » Mon Aug 20, 2012 6:37 pm

Hi John,
I am actually working with sine, cosine, tangent and arc of all these for a project. I was looking through code and Jan's code for sine and cosine. Both of them are great and useful. Although your code is pretty easy to understand and can be easily modified to have better accuracy and can be modified for other trigonometric functions.
Thanks for the nice post. I have added two terms in your program for more accuracy and degrees up to 360 Jonny's suggestion.

I am working on tangent and arc..I will post those as well.
Attachments
Trignometry Calculator.fcf
Tested in ECIO-40
(29.37 KiB) Downloaded 355 times
These users thanked the author Enamul for the post (total 2):
medelec35 (Mon Aug 20, 2012 8:01 pm) • JohnCrow (Mon Aug 20, 2012 8:03 pm)
Rating: 10.53%
 
Enamul
University of Nottingham
enamul4mm@gmail.com

User avatar
Enamul
Posts: 1772
Joined: Mon Mar 05, 2012 11:34 pm
Location: Nottingham, UK
Has thanked: 271 times
Been thanked: 814 times
Contact:

Re: Sine & Cosine Calculator

Postby Enamul » Tue Aug 21, 2012 12:50 am

Hi,
I have made one calculator which can calculate all basic trigonometry functions using the two main function sinx and cosx. As we all know tanx=sinx/cosx, cotx =cosx/sinx, secx=1/cosx and cosecx = 1/sinx.
In all the functions I have used independent macro and so they can be used for different x values. Though the idea is pretty simple, but I think it will be useful. I am although interested in calculating tanx, cotx, secx and cosecx using Taylor expansion series not just simple above expression so that we don't need to depend on sinx and cosx. I am working on that. I will post whenever I can finish it. The problem is the series I got by goggling is just upto 3 or 4 terms but I am looking for more precision. So I have to calculate Bernoulli numbers of my own to generate the expression..which actually taking the time.
Attachments
Trigonometry Calculator.fcf
Tested in ECIO-40
(54.57 KiB) Downloaded 332 times
Enamul
University of Nottingham
enamul4mm@gmail.com

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 64 times
Been thanked: 306 times
Contact:

Re: Sine & Cosine Calculator

Postby JonnyW » Tue Aug 21, 2012 10:34 am

Hi.

I don't know if there is a good approximation for what you need but you might look into cubic Bezier curves for approximating sections of repeating functions such as sine or tan. It all depends on how accurate you want things but it is possible to use pure 32-bit fixed-point maths with Bezier curves to get good approximation, then convert to a float to return from the macro. Because floats on the pic are so slow this may be faster than Taylor expansion.

Jonny

User avatar
Enamul
Posts: 1772
Joined: Mon Mar 05, 2012 11:34 pm
Location: Nottingham, UK
Has thanked: 271 times
Been thanked: 814 times
Contact:

Re: Sine & Cosine Calculator

Postby Enamul » Tue Aug 21, 2012 12:14 pm

Hi Jonny,
Are you talking about the following approximation to generate sine function?
http://www.tinaja.com/glib/bezsine.pdf
I was wondering how could that be easily implemented in PIC. Can you please give some hints?
Enamul
University of Nottingham
enamul4mm@gmail.com

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 64 times
Been thanked: 306 times
Contact:

Re: Sine & Cosine Calculator

Postby JonnyW » Wed Aug 22, 2012 10:14 am

Hi. Yeah, that looks like the kind of thing. Also see:
https://ece.uwaterloo.ca/~dwharder/Maplesque/Bezier/BestFittingBezierCurves.ppt

Essentially what your PDF is showing is a 24-element LUT, but instead of having discrete values or linearly interpolated steps it uses a series of Bezier curves (a spline) to smooth out the curve.

You would want to implement this using 32-bit signed integers with 8-bit fixed point. It simplifies things to use floats but it will also be slower, so best to avoid this.

A cubic bezier curve is a curve with two fixed end points (anchors) and two control points that define the curve. A variable that is in the range 0-1 (usually called t) defines how far along the curve you are from the start point when t=0 to the end point when t=1. The formula for a Bezier curve is (where ^ is 'to the power of'):

Code: Select all

v = P0 * (1 - t)^3
  + P1 * 3 * (1 - t)^2 * (t)
  + P2 * 3 * (1 - t) * (t)^2
  + P3 * (t)^3


For the first curve the control points are at: 0, (2*sqrt(2) - 1) / 7, 2 * (2*sqrt(2) - 1) / 7, sqrt(2) / 2.

In 8-bit fixed point this means:

Code: Select all

P0 = 0
P1 = 67
P2 = 133
P3 = 181

To calculate t (in 8-bit FP), we know the range of the segment of the line for this 1/8th of the curve is PI/4, so t = 256 * angle / (PI/4)

Code: Select all

t = 256 * angle / 0.78539816
i = 256 - t
tsq = (t * t) >> 1     // 15-bit fixed point t^2
tcu = tsq * t          // 23-bit fixed point t^3
isq = (i * i) >> 1     // 15-bit fixed point (1-t)^2
icu = isq * i          // 23-bit fixed point (1-t)^3

// Now calculate the point on the curve
y = (0 * icu)
y = y + (67 * (3 * isq * t))
y = y + (133 * (3 * i * tsq))
y = y + (181 * (tcu))
// y is now a 31-bit fixed point value representing sin(angle) where 0 <= angle <= PI/4


Of course, all this work only calculates the first 1/8th of the curve.

You have two choices now. The first is to look at the first PI/2 of the sine curve and produce an if statement for the two curves, then tweak the values depending on the angle sector, and the second is to create a look up table of all the points, get the curve segment, multiply by 4 and use the Bezier points starting at that index (LUT[ix], LUT[ix+1], LUT[ix+2], LUT[ix+3]).

This is an example of the first possibility, because not requiring look-ups saves memory overhead, which would need to be 16-bit entries, so 48 bytes of LUT (and also an ugly global variable).

Code: Select all

angle = angle / 0.78539816     // Divide by sin(PI/4): Integer part is the sector, decimal part is the range 0-1
sector = floor(angle)
t = 256 * (angle - sector)

if (sector & 2) // Then between PI/2 and 3*PI/2
  sector = sector ^ 1
  t = 256 - t

i = 256 - t
....... tsq, tcu, .....

if ((sector & 1) == 0)
  // Bezier curve part 1 (use values above)
else
  // Bezier curve part 2

if (sector & 4) // Then between PI and 2*PI
  y = -y

result = y / 2147483648.0  // Convert 31-bit FP to a float, 0-1


This completely avoids floating point and should get the result required. I haven't tested this though, and have worked solely from your PDF.

What I would suggest is to use simulation in Flowcode to test any routine like this, and draw on the GLCD component to display the results.

I hope this is enough to go on. Cheers,

Jonny
These users thanked the author JonnyW for the post:
Enamul (Wed Aug 22, 2012 11:25 am)
Rating: 5.26%
 

User avatar
Enamul
Posts: 1772
Joined: Mon Mar 05, 2012 11:34 pm
Location: Nottingham, UK
Has thanked: 271 times
Been thanked: 814 times
Contact:

Re: Sine & Cosine Calculator

Postby Enamul » Wed Aug 22, 2012 11:25 am

Hi Jonny,
Excellent. I will go through that and hopefully spoil some more of your valuable time. :D
Enamul
University of Nottingham
enamul4mm@gmail.com

User avatar
Enamul
Posts: 1772
Joined: Mon Mar 05, 2012 11:34 pm
Location: Nottingham, UK
Has thanked: 271 times
Been thanked: 814 times
Contact:

Re: Sine & Cosine Calculator

Postby Enamul » Wed Aug 22, 2012 12:56 pm

Hi,
Although Jonny suggest me to use Bezier curves and I am working on that. Meanwhile I have made an FC for all basic functions including arcs which I can't accommodate in ECIO-40 even. I have to move to large memory PIC like 18f4680..But I think no-one will need all function altogether rather couple of those. So I think can accommodate in moderate memory PICs..
Now we can calculate sinx,cosx,tanx,cotx,secx,cosecx and arcsinx,arccosx,arctanx,arccotx,arcsecx and arccosecx... :D
Attachments
Trigonometry Calculator_v2.fcf
(106.42 KiB) Downloaded 350 times
These users thanked the author Enamul for the post (total 2):
Benj (Wed Aug 22, 2012 3:45 pm) • JonnyW (Wed Aug 22, 2012 11:10 pm)
Rating: 10.53%
 
Enamul
University of Nottingham
enamul4mm@gmail.com

viki2000
Posts: 188
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: Sine & Cosine Calculator

Postby viki2000 » Wed Jul 26, 2017 10:58 pm

Actually even for 16bit PICs as PIC24, using fixed point math to generate the sine is a very good approach. It is faster than LUT and elegant with less memory size in case we want some thousands of samples per period of sine/cosine. I have used Taylor series polynomial approximation of 3rd and 5th order to make a sine. Then to be faster the coefficients of the polynomial must be calculated to be power of 2. That helps a lot when we implement it in ASM, which requires only few lines of code.
Here is a part of the job that I have done:
viewtopic.php?f=7&t=19068
If we use a real DAC to make a sine signal, then probably using DMA with SPI the result is even better, but I did not get yet to that point:
viewtopic.php?f=7&t=19055

alanwms
Posts: 48
Joined: Tue Sep 16, 2008 2:09 pm
Location: Minnesota USA
Has thanked: 3 times
Been thanked: 17 times
Contact:

Re: Sine & Cosine Calculator

Postby alanwms » Mon Nov 20, 2017 5:36 am

I'm presuming that the use for this is to produce digital a sine output with ports connected to d/a converters? Another way to produce a sine is to use a 2r2 resistor network connected to the port(s). Then a simple triangle wave (linear increase and decrease) will produce a nice sine wave with an adjustable frequency. Simply ramp the port up and down. 8 bit resolution shows the steps up on the scope but with a little filtering, that could be accomodated
Would most likely be faster since math is not involved. I did try this, and found that a 20mhz PIC ran a max output of around 4khz.

Available in chip formats
I hope that has some value....
R2R.jpg
R2R.jpg (12.37 KiB) Viewed 3749 times