## CREATING FIXED POINT SINE WAVE LOOPUP TABLE

26 posts / 0 new
Author
Message

Hi,

I want to create sine/cos wave lookup table from 0 to 90 with option of maximum number of point and max amplitude. I want to know how I can do this. Any formula or any free tool. I know online tool like "https://www.daycounter.com/Calcu..." but these tool not give option of different angle. So please help me for this.

One more thing I want to ask- Can I create these lookup table in microcontroller its self?

So I can create table as required and put it in to the ram and then use it.

Any python code is also helpful. So I can use it to generate lookup table for desired amp, size and angle.

Thanks

This topic has a solution.
Last Edited: Thu. Aug 4, 2022 - 03:56 AM

samic45mit1 wrote:
option of different angle

Do you means, angles from 90 to 180, or 360?

Sine wave is the most pure and most perfect mathematical form. Sine of 91= sine of 89.

You need a table for sin(0) to sin(pi/2).  Everything else can be derived from that.  You could write some code on a PC, or use a spreadsheet.

To create the table on the fly in the micro, you'll need enough RAM and processing power.

Last Edited: Sat. Jul 30, 2022 - 07:18 PM

samic45mit1 wrote:

I want to create sine/cos wave lookup table from 0 to 90 with option of maximum number of point and max amplitude. I want to know how I can do this. Any formula or any free tool. I know online tool like "https://www.daycounter.com/Calcu..." but these tool not give option of different angle. So please help me for this.

Any language that has Sin or similar trig can manage this in a simple loop.

I've used Assemblers with Sin(x) ability, and I've even used polynomial expansion sine tables in Assemblers without sine - those do take a while to run tho.

samic45mit1 wrote:

One more thing I want to ask- Can I create these lookup table in microcontroller its self?

So I can create table as required and put it in to the ram and then use it.

Of course, you just need a MCU able to run Sin(x)  and those without full trig engines will use a polynomial series for sine.

samic45mit1 wrote:

Any python code is also helpful. So I can use it to generate lookup table for desired amp, size and angle.

This example  creates a C table from python code.

If you want this to ultimately run in a MCU, you are best to generate an assembler or compiler include file

How 'live' do you want points and amplitude ?

You can create a few tables that can be simple choices, but at some point you run out of memory.

I've seen tables stored in external flash which allows larger table choices, but those need to be loaded into RAM

Or if you want complete user freedom to adjust points and amplitude, choose a MCU powerful enough to do that.

If you want to output this to a Analog voltage, then add a DAC to the feature list.

Haven't you heard of Excel? Make whatever you want.

For use inside the AVR, start looking up cordic  It is used for finding such things using simple calculations

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

samic45mit1 wrote:
Any formula
Ideally in one of your favored textbooks (an engineering undergraduate course like "Numerical Analysis")

samic45mit1 wrote:
Can I create these lookup table in microcontroller its self?
Yes by Embedded C fixed-point arithmetic though C++23 appears to have fixed-point math (arithmetic plus); Ada has fixed-point math.

Endowed MCU have available memory-safe computer languages.

An alternative is most MCU are connected to another machine; so, tablet/PC/workstation/server/gateway does the computation and transformation as input to a constructor on the MCU.

samic45mit1 wrote:
... and put it in to the ram and then use it.
Some MCU map non-volatile memory to volatile; some MCU map by a MPU or MMU.

Such reduces initialization duration as some system specifications greatly limit duration from power-on to operational (reasons : safety, operator awareness)

Numerical RecipesTM : The Art of Scientific Computing (likely chapter 5)

Jack-W.-Crenshaw-Math-toolkit-for-real-time-programming.9781929629091.35924.pdf

[page 112]

Chapter 5

Getting the Sines Right

[page 135, bottom]

The Integer Versions

Math Toolkit for Real-Time Programming [With CDROM] | IndieBound.org

Jack Crenshaw, Author at Embedded.com

Memory safe computer languages | AVR Freaks

Efficient web server technology for resource-constrained microcontrollers - Embedded.com ("heavy lifting" in operator's web browser by a web app (JavaScript/TypeScript), WebSocket server on MCU)

edit :

https://github.com/micropython/micropython/blob/master/py/modmath.c#L136

micropython/ports at master · micropython/micropython · GitHub

"Dare to be naïve." - Buckminster Fuller

Last Edited: Sun. Jul 31, 2022 - 02:07 AM

Here is a good example of using the cordic method to generate the sine values, it is very fast and the code is provided as well.

https://en.wikipedia.org/wiki/CO...

CORDIC was conceived in 1956by Jack E. Volder at the aeroelectronics department of Convair out of necessity to replace the analog resolver in the B-58 bomber's navigation computer with a more accurate and faster real-time digital solution. Therefore, CORDIC is sometimes referred to as a digital resolver.

... Jack Volder, a researcher at Convair’s aeroelectronics department, tackled this problem and developed a method he dubbed CORDIC (COordinate Rotation DIgital Computer) for calculating trigonometric functions using only adds and shifts (significantly, CORDIC computations do not require a multiplier, which consumes many gates).

http://www.hp9825.com/html/the_9...

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. Jul 31, 2022 - 02:28 AM

from #1

but these tool not give option of different angle

What do you mean by this?

they will do 0-360 (0- 2pi) so if you only need 0-90 then make the table 4 times bigger than needed and then only use the first 25% of the numbers.

Note if you want to make 0-360 from the small table make sure that you don't have the value for both 0 and 90 deg in the table because then there will be an error when you mirror and negate.

(there are basically 2 ways to do it [0..90[ or make the double amount of steps and then only use the number in the odd places)

samic45mit1 wrote:
I know online tool like "https://www.daycounter.com/Calcu..." but these tool not give option of different angle.

Indeed; it always does the full 360° but you don't have to copy ALL the entries into your code. You could ask for 360 entries and use only the first 90.

NB: Because the full 360° is generated that tool outputs signed integer values.

Hi, Thanks All,

As per your suggestions. I make a small python code for the look up table in Python but result are not exactly same as generated by "daycounter". So any correction or improvement, please suggest.

from matplotlib import pyplot as plt
import numpy as np
import math as m

max_amp=4000                 #Maximum amplitude

no_of_point=64                  #No of point required in table

DC_offset=0000                 #DC offset, if required

x=np.arange(0,angle,angle/no_of_point)

y=max_amp*np.sin(x)

r=DC_offset+np.round_(y)

#Print the value of XY on console

print(x)
print(r)

#Print the table on console

s=np.size(x)
print(s)

#Plot the graph

plt.plot(x,r)
plt.grid(True);
plt.show()

I make a small python code

Why?

This is exactly what Excel or Open Office is for....you don't need any code at all.   Much more ready to use and many tools for your formatting and you can save your spreadsheet and do many things with the table.  In fact, the table is right in front of you where you can immediately view it, sort it, base other column on it, convert to other bases, copy/paste values into your program, etc.

Just fill in the yellow blanks and the result pop up When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. Jul 31, 2022 - 02:14 PM

samic45mit1 wrote:

As per your suggestions. I make a small python code for the look up table in Python but result are not exactly same as generated by "daycounter". So any correction or improvement, please suggest.

There are two differences.

1. the range that daycounter uses is 0 to 2*pi. Your range is half of that. But there's a more subtle difference too. Numpy ranges include the first point but not the last. For example, if you ask Numpy for integers from 0 to 5 it will return 0, 1, 2, 3, 4. This is not a bug, but a known detail of the way it works.

2. daycounter adds half the 'amplitude' as a DC offset. If you change your python code to include all of 0 to 2*pi, you'll find that the second half is negative numbers. To get the same numbers as daycounter you need to cut your max amplitude in half (2000) and then add 2000 to every element in the array.

Brian Fairchild wrote:

It's at this point that we really do need the OP to come back and engage with us. So many questions..........

avrcandies wrote:

I make a small python code

Why?

This is exactly what Excel or Open Office is for....

I used Octave. You wanna fight about it?

```numpts = 64
max_amp = 4000
angle = 2*pi
x = 0:angle/numpts:angle
y = round(sin(x)*max_amp/2 + max_amp/2)
disp(y.')```
```   2000
2196
2390
2581
2765
2943
3111
3269
3414
3546
3663
3764
3848
3914
3962
3990
4000
3990
3962
3914
.....```

Brian Fairchild wrote:

It's at this point that we really do need the OP to come back and engage with us. So many questions..........

Last Edited: Sun. Jul 31, 2022 - 04:23 PM

I used Octave.

Octave is a pretty good clone of Matlab, at the right price.  If there were some complicated logic/iterations beyond the calculations it would be the choice.  In this case, we are dealing with just straight calculations, so doesn't really compare very well to Excel's or Open Office's polished capabilities (without going through a lot of effort to duplicate them).

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

eugene the jeep wrote:

I used Octave. You wanna fight about it?

Using Octave IS the fight. It's not the program I turn to much at all because I found myself having to google almost every command.

I promised myself to investigate sometime this Jupyter Notebook thing that Visual Studio Code keeps telling me about.

Software Application Development | CryptoAuth Trust Platform User's Guide

[second paragraph]

The Microchip Trust Platform Design Suite of use case tools are based on Jupyter Notebooks and Python programs to allow a developer to quickly define and develop applications for the Trust Platform products.

"Dare to be naïve." - Buckminster Fuller

One last question on this. What is the use of interpolation in this and how to implement it?

The tools like "daycounter" and octave use it or not?

Last Edited: Mon. Aug 1, 2022 - 03:59 AM

What is the use of interpolation in this

Your question makes zero sense as far as the resources---where was it mentioned they use interpolation??

Of course YOU can interpolate between points to estimate others ...so between sin(30) = 0.5 and sin(34) = 0.5591929...   you could have a midpoint, 10 different points, even a million points (30.000004, 30.000008, 30.000012 ...

You could use the simplest/worst, linear interpolation, or a quadratic, cubic interpolaton, etc.  Since you KNOW the function is sin, you can even make use of that information for a better interpolation.

Probably linear or quadratic are fine for most/many needs.

By the way, did you look carefully at the CORDIC information in #7.  That is a form of interpolation, using iterative steps & code is already avail for the AVR.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Surely those tools are just calculating/reporting the value of the sine at discrete intervals, probably one degree from earlier comments? No interpolation there; they're just numbers.

When you use the values, you can interpolate as much as you need; there are a number of levels of increasing sophistication and accuracy. Note that if you want to generate audio output, the human ear is *very* good at hearing poor interpolation choices; it will sound pretty grim.

DDS can be implemented by calculating a phase angle between subsequent samples, adding that to a running total, and using a modulo (size of sine table) to select a value from the table. Odds are very likely that you're not going to hit an exact integer result, so you can interpolate - in increasing order of 'niceness' and complexity:

• take the integer below your calculated fractional value
• take the integer nearest to your calculated fractional value
• use the integer below and the integer above and interpolate linearly across that value
• use more integers and a more complex interpolation - perhaps cubic - to get a better approximation... and so on

Note that there's no point in an interpolation which produces a more accurate result than the original estimation to the sine wave; if your sine is specified in eight bits, for example, it's only going to be accurate at a couple of points in the cycle. With sixteen bits, it'll be accurate at the same points (zero, thirty, and ninety degrees, off the top of my head) but it'll be a lot closer everywhere else. In general, the more points on your sine table and the more bits of precision, the nicer the output will be - but as always, it depends on your requirements.

Neil

This reply has been marked as the solution.

samic45mit1 wrote:
I make a small python code for the look up table in Python but result are not exactly same as generated by "daycounter"
When I write Python I simply write what appears to be most simple and obvious (perhaps it's writing Python coming from a mainly C background?). So when I wanted some sine values and to plot them I wrote this...

https://www.avrfreaks.net/commen...

The core of the sin() calculation in that is nothing but a for loop:

```for x in range(320):
y = 120 * math.sin(2 * math.pi * x / 320.0)```

and the 320/120 in that is simply because I set the canvas size I was drawing on to be 320x240 (and 120 is half way up the 240)

Last Edited: Mon. Aug 1, 2022 - 08:15 AM

Following Clif's link in #20 I noticed that departed freak,

Paulvdh wrote:
Because I already have GNU Octave installed I searched the web for an example.

This made me smile. At least there's someone else who struggles with remembering GNU Octave stuff.

samic45mit1 wrote:
... and how to implement it?
one MAC

Jack-W.-Crenshaw-Math-toolkit-for-real-time-programming.9781929629091.35924.pdf

[page 112]

Chapter 5

Getting the Sines Right

[mid page 148]

Table 5.13 Entry numbers for table lookup.

[last sentence of last paragraph]

This trick [second table is slope] reduces the interpolation to a single multiply and add, yielding a very fast implementation.

[page 149, last two sentences of last paragraph]

The end result [of BAM] is an algorithm that is blazingly fast — far more so than the power series approach. If your application can tolerate accuracies of only 16 bits or so, this is definitely the way to go.

16 bits is 5 decimal digits; 8 bits (2.5 digits) is enough for a significant number of processes.

Math Toolkit for Real-Time Programming [With CDROM] | IndieBound.org

Jack Crenshaw, Author at Embedded.com

"Dare to be naïve." - Buckminster Fuller

For interpolation remember that the derivative of sine is cosine :) so you have the slope by loading the value 90 deg away

The way crlibm (correctly rounded libm) does it is small angle formulas and trig addition formulas:

sin(big + small) = sin(big)*cos(small) + cos(big)*sin(small)

cos(big + small) = cos(big)*cos(small) - sin(big)*sin(small)

sin(big) and cos(big) come from tables.

sin(small) and cos(small) come from small angle formulas.

A similar possibility is to use two tables,

say 0 to 90 by 3 and 0 to 3 by 0.1 .

OP seems to want something he can automate.

Copy and pasting from a spreadsheet would not seem to qualify.

I expect that given an existing spreadsheet,

getting its values into code could be automated

I'm more used to Python,

so if I were putting this into my build process,

I'd use Python.

To me, having the code generate the values seems like not all that good an idea.

Having the code perform some consistency checks would be more practical.

Edit:

Note that if one rounds instead of truncates (crlibm code does), small can be negative.

0 to 3 by 0.1 could be 0 to 1.5 by 0.1 .

-1.5 to 0 can be obtained from symmetry.

Depending on ones desire's, 0.1 might or might not be the best step size.

Moderation in all things. -- ancient proverb

Last Edited: Tue. Aug 2, 2022 - 05:21 PM

samic45mit1 wrote:

One last question on this. What is the use of interpolation in this and how to implement it?

This is sounding like homework ?   What are you actually trying to achieve here ?   End use examples ?

Interpolation is useful when you are resource limited. On a PC, you just calculate all the points you need.

On a MCU you may be RAM or table limited, so in your example above 64 table size is small, but might be chosen for highest Sine generation speed.

At lower output frequencies 64 steps may be too coarse to be well filtered, so a designer would choose to interpolate points - simplest is a straight line linear interpolate.

Of course, these days, we have the luxury of just choosing a MCU with enough resource to do it simplest. Decades ago, someone might have done a 90 degree table and managed the quadrants manually.

These days, you might make (or run time calculate) a full cycle, and use DMA to DAC to playback.

I've also seen designs where more than one cycle was done in a table, and other designs where a table size is varied - this allows finer frequency control at fixed time playback rates.

DDS designs tend to use a binary sized table, indexed by the upper bits of the adder.

The nature of the DDS adder, means table points are skipped as the frequency increases, and at very low frequencies some are duplicated.