#### Do you have a question? Post it now! No Registration Necessary

Re: sine routines

Sine? Not quite...

You can generate a square function - not a square wave but an x^2

function. Imagine x^2 between 0 and 1. It looks a bit like a quarter

cycle of sine.

You can generate an arbitrary amplitude and frequency wave in real

time by stringing together four such sections with appropriate

manipulation. The result is slightly 'fatter' than a sinusoid to look

at on a 'scope, but the difference can only really be seen with a

direct comparison.

I've used this for controlling hydraulic machinery from almost 0 to

100Hz with great success - it really depends on your application. I

don't know if your processor is up to it, but it's much easier than a

real sine and more flexible than a LUT.

Unless of course your application allows you to pre-calculte a LUT

before sending it to the DAC.

--

Syd

Syd

Re: sine routines

You should have stated this in your first posting.

You might get away with a phase accumulator and a look-up-table even

without interpolation between the steps. The truncation errors will on

some output frequencies contribute with wide band noise at the DAC

output, while on other frequency settings all the noise power is

concentrated in discrete sidebands.

Depending your requirements for the signal to noise ratio and the

maximum level allowed for discrete tones, the size of the LUT can be

determined. Also the situation is simpler if all the generated

frequencies are well below the sampling frequencies.

Most literature about numeric controlled oscillators (NCO) also

evaluates the size of the phase accumulator vs. steps size, the number

of address bits into the sin(x) table and the number of DAC bits and

the spurious levels.

If a simple table look up is not accurate enough, some very simple

interpolation with shifts and one or two adds should do the trick. Use

a spreadsheet to evaluate the error between the interpolated value and

the "exact" 64 bit double precision value and select your table size

and interpolation strategy to minimise the number of clock cycles

required for the calculations.

Paul

Re: sine routines

If your hardware design is not set in stone at this point, add two 27512 64Kx8

EPROMs, and a handful of glue logic. Feed the address pins with two 8-bit

latches that can WRITE from the 8051. Use some glue logic to take a pulse from

the processor, do a read cycle on the EPROMs, and latch the results into two

other 8-bit latches that you can READ from the 8051.

Now burn the EPROMs with sin(address), and you have a dedicated hardware sin(x)

lookup table that will be scary fast compared to any algorithm for computing

sin(x).

It works something like this:

poke(msb(x), SIN

___TABLE___ADDR_MSB);

poke(lsb(x), SIN

___TABLE___ADDR_LSB);

pulse(SIN

___TABLE___TRIGGER);

sinx = peek(SIN

___TABLE___DATA

___MSB) << 8 | peek(SIN___TABLE

___DATA___LSB);

This is basically how the Yamaha DX7 synthesizer generated frequency-modulated

audio sinewaves.

The trick is realizing that you can hook EPROM (and RAM, for that matter)

address pins to other things besides microprocessor address pins.

Re: sine routines

64Kx8

from

two

sin(x)

computing

Nice idea, but you also need a DA converter.

Now go take a look at the AD9833: A full DDS capable of outputting DC to

12.5MHz in 0.1Hz steps, sine, square and triangle. And if you clock it with

'only' 1MHz, you get DC to 500kHz in 0.004Hz resolution.

And all this in a 10 pin package for a whopping $9.30 at Digikey....

Meindert

Re: sine routines

You can use a Taylor series. And if your angles are small you can get away

with a limited number of terms, depending on the required precision. You may

do it with integer math and the approprate scaling.

For example, for small angles, sin(x)=x (in radians)

The next refinement: sin(x) = x - x*x /2 For angles below 1 radian this may

be sufficient.

Wim

Re: sine routines

Sorry, no such animal. The fastest way to calculate sines is table

lookup and interpolation. Also think 'octents' rather than quadrants to

preserve accuracy.

-- Regards, Albert

----------------------------------------------------------------------

AM Research, Inc. The Embedded Systems Experts

http://www.amresearch.com 916.780.7623

----------------------------------------------------------------------

Re: sine routines

Fastest I've seen was look-up with linear interpolation on a

twice-folded (at pi and pi/2) table of numerators for a fraction

with denominator 65535. All of the processing was performed in

integer math except the final division. Accuracy was pretty good

and the code was completely portable (the application wasn't for

an 8052).

--

Morris Dovey

West Des Moines, Iowa USA

Morris Dovey

West Des Moines, Iowa USA

We've slightly trimmed the long signature. Click to see the full one.

Re: sine routines

thank

This is a very fast but quite imprecise method of generating a sine-like

wave. I guess whether it is suitable depends what you want to use for. I

used it years ago on a PIC in conjunction with a software PWM and decay

function to generate a pleasing bell-like tone. I tried it out just now on

C++Builder, so I'll just paste the code and let you play with it to see if

it works for you. I seem to remember it may decay over time by itself due to

rounding errors:

void

______fastcall TForm1::FormCreate(TObject *Sender)

{

int s=Image1->Height/4;

int c=0;

for( int x=0; x<Image1->Width; x++ )

{

c = c+s/16;

s = s-c/16;

Image1->Canvas->Pixels[x][s+Image1->Height/2]

=(TColor)0x00FF0000;

}

}

Peter.

Re: sine routines

thank

I am sorry, terribly busy, but you can get there from here (I had to)

circles ( and sines, fit for your purpose) using only add and subtract

X = 100: y = 0

FOR i = 1 TO 1000

PRINT X, y

X = X - y / 256

y = y + X / 256

NEXT

If you cannot do it I will dig out the Scamp (INS8060) code, eventually.

David F. Cox

Re: sine routines

very

in context: I had to drive a stepper motor around 1 metre diameter circles

with an accuracy of 0.1 mm using a 2K EPROM

========

original post:

I am sorry, terribly busy, but you can get there from here (I had to)

circles ( and sines, fit for your purpose) using only add and subtract

X = 100: y = 0

FOR i = 1 TO 1000

PRINT X, y

X = X - y / 256

y = y + X / 256

NEXT

If you cannot do it I will dig out the Scamp (INS8060) code, eventually.

David F. Cox

======

#### Site Timeline

- » Atmel STK500 beginner Flash mem verification problem
- — Next thread in » Embedded Programming

- » is locked 8051 copy protected
- — Previous thread in » Embedded Programming

- » Use of soft float?
- — Newest thread in » Embedded Programming

- » arm-gcc: avoid calling other system functions
- — Last Updated thread in » Embedded Programming

- » how to enable VNC Clipboard
- — The site's Newest Thread. Posted in » Raspberry Pi Group

- » Domanda su cloni arduino
- — The site's Last Updated Thread. Posted in » Electronics Hobby (Italian)