View previous topic :: View next topic |
Author |
Message |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
Question about time need for sinus calculation |
Posted: Wed Feb 29, 2012 5:32 am |
|
|
I'll create PWM waves using the PWM module of the controller. The frequency must be around 16kHz. This means 50-60us per impulse. I need to know, if my oscillator is running on 20MHz, is this time of 50-60us enough for calculation of sin function(for example sin(i*2*3.14/n)*150). How much time approximately it should take???
I need to know if the controller should calculate the next value before the time out.
Thanks! |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Feb 29, 2012 5:47 am |
|
|
for continuous sine/cosine generation, its faster to use the finite difference equations as these only use simple +/- and *.
These are especially good for creating sine tables for FFTs, where you can create two quadrants of a cycle at once, and reflect them to get the rest.
This is from a C# test app I did that generated a quadrature pair for testing side by side bargraphs:
Code: |
float Sine = 0.0f,
float Cos = 1.0f; // Or whatever amplitude you want.
....
// Co-generate sine and cosine by finite differences.
float temp = Sine * .99802672842827156195233680686345f + Cos * 0.062790519529313376076178224565631f;
Cos = Cos * 0.99802672842827156195233680686345f - Sine * 0.062790519529313376076178224565631f;
Sine = temp;
|
The constants are sin(Theta) and cos(Theta) where Theta is the angle, in radians, between one step and the next. I used way more precision on the constants than I needed: they came straight from Windows calculator. The values above are for 100 steps in a cycle, or every 3.6 degrees. This needs far less processor time than doing sin() for every value. Its the way Babbage would have done it...!
Another method is to only compute one cycle in advance and out it into a table. Then read it out ouver and over, only re-calcuating the table when the frequency needs to change.
RF Developer. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Feb 29, 2012 6:45 am |
|
|
You should take the time to cut a small program to test a few ways to do it.
Start with your basic equation sin(i*2*3.14/n)*150 and time it for a few vaules of i and n.Say min,max and 3 points inbetween, each.
Then replace 2*3.14 with 6.28 and see what happens.
There's also 'resolution' . How many signifigant digits to the right of the decimal point do you really need???
ie: Pi=3.14159265.... , you've shown 3.14 and 355/113 is much closer.
Integer math is a lot faster, perhaps part of your math can be replaced ?
Also perhaps a lookup table might be quicker,again depending on .nnn or .nnnnnnnnnnnnnnnnnnn required ? |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Wed Feb 29, 2012 7:55 am |
|
|
There is a problem when I'm using a lookup table. It becomes too big for the controller capacity.
If I use a single array it takes too much time for calculation of all values in it and this causes a big time interval through the output generation.
Could it be a problem if I use only + and - operations. For example if I calculate the duty cycle as I start from 60 (for example) and for each next pulse I just add 5 (for example) and when I reach the max just start to -5??? Can this destroy the shape of the output sinusoidal signal??? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Feb 29, 2012 8:05 am |
|
|
You might google 'magic sine waves' and see if you can use part of it.
WRT the lookup table, it only has to be 90* worth of data,90 entries if 1* is acceptable.... |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Look up tables |
Posted: Thu Mar 01, 2012 5:18 pm |
|
|
You don't say whether you want to change the amplitude or not.
For a fixed amplitude you could consider a look up table.
Suppose you've got a sine table as an array in ROM.
Look up index zero to get first PWM value. Then increase index by a fixed step-size, for each new PWM value. Wrap round when you reach the end of the table.
Altering the step-size changes the frequency.
To get finer frequency steps you either use a bigger table, or some means of creating fractional steps (say to get 8.7 your step size is three lots of 8 and seven lots of 9 interleaved) You should be able to do it all in integer maths.
Worth a try?
Mike |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Mar 02, 2012 6:53 am |
|
|
Most often a lookup table and perhaps some interpolation is the fastest.
Then again there is the COORDIC.
It was used for space exploration it has the advantage of arbitrary precision...you know like hitting a bullseye at 100,000 kilometers. I posted code in the CCS library....In a nutshell it is the equivalent of notating angles in binary where the tangent of 45 deg is notated as binary one...the angles whose tangent is 1/2 is notated as 0.1 binary etc. Once the angles can be notated in binary they can be manipulated quickly. Sine and cosine are computed simultaneously by simple shift and add/subtract operations it also generates the sqrt(x^2+y^2) the radial distance to the target.
Other trig functions can be calculated as well as transforms to polar coordinates. Care needs to be taken to stay within the quadrant 0..90 though simple transforms will extend it to 360 deg...there are mathematical issues as you get very close to 90 degs ..this avoided by stipulating the sine of 90 is 1 and the cos of 90 is 0. To convert back to base ten notation of angles for human readability a constant of proportionality is needed so a multiplication is required....of course a robotic probe doesn't need human readable notation so the multiplication can be avoided. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Look up table |
Posted: Sat Mar 03, 2012 4:28 am |
|
|
I've slept on it.
The method I outlined before is a sort of DDS approach.
Using MPLAB SIM, I tried three ways of implementing it for a 10 bit PWM, 20MHz clock, and a 360* lookup table.
(1) Advance the index by an int16 for each step. This took ~12us per loop, and a little longer for a wrap round. Problem here is limited number of possible frequencies.
(2) Use a float value index, but only use integer part to feed PWM. This took ~80us per step and >100us at wrap round. Too slow!
(3) Split index into two int16s, one for the units and one for fractional part. Then increase both index sections and increment unit part when fractional part overflows. This took ~16us with the fractional overflow and a little longer at wrap round.
Version (3) is not much slower than (1) and has loads more resolution. I've no reason to believe that the timings won't be too far out (they're in accord with my expectations). If you want to use a 90* look up table, you'll need a bit more time. I don't think it should be a show stopper.
Mike |
|
|
|