How do sine Look up tables actually work?

hey all, i need to make 3 sine waves out of phase by 120 degrees. whats more is then i need to top end it so i only have the positive waves of the sine waves then invert them for the negative sides giving me 6 outputs so i can run a 6 transitor bridge to run a motor!!!

but right now i have no idea how a sine look up table actually works and how i can change the internal timers for the PWM pins on an arduino mega 2560 so i can change the frequency?

any help is appreciated :slight_smile:

It's very simple. The table part anyway.

Sry to send you off to google, but get comfy and poke around a bit

 sine lookup table c

You can pre-compute the values of the sin function or go all the way and have the table hold the values you actually need, shifted or constrained or w]however you would have been doing it old school calling sin() and maths.

a7

I’ve been trying to use tables with numbers pre written

I.e int sineTable[] {

1,2,3 etc..

};

I’ve got some codes that make the signal using this but I just don’t understand how the values in the array are used

You'll have to make a choice about resolution, like how big the table you want to use.

No table

x = sin(theta);

You can feed floating point numbers 0 to 6.28… for a complete cycle.

Table

 x = sinTable[(int) (theta * 100 / 6.28…)];

if your table had 100 entries and represented a full cycle. Write a program to calculate the table entries. Floats here, but you can do integer tables if you use the values differently. Google.

In case not obvious, 6.28… was as much of 2 π as I cared to type.

I'm leaving out details better not presented by some random guy in a forum, google and read from someone who was paid or otherwise motivated to go into detail. Better than I can.

a7

Hello samba3305
Initiliaze a table, sized by your needs, with values using the sin() function during the setup() call.
Have a nice day and enjoy coding in C++.

You'll have to post the code you are using, but typically the sine table values are used to set some output duty cycle.


static const unsigned int lookup[] {
180,183,186,189,193,196,199,202,
205,208,211,214,217,220,224,227,
230,233,236,239,242,245,247,250,
253,256,259,262,265,267,270,273,
275,278,281,283,286,288,291,293,
296,298,300,303,305,307,309,312,
314,316,318,320,322,324,326,327,
329,331,333,334,336,337,339,340,
342,343,344,346,347,348,349,350,
351,352,353,354,355,355,356,357,
357,358,358,359,359,359,360,360,
360,360,360,360,360,360,360,359,
359,359,358,358,357,357,356,355,
355,354,353,352,351,350,349,348,
347,346,344,343,342,340,339,337,
336,334,333,331,329,327,326,324,
322,320,318,316,314,312,309,307,
305,303,300,298,296,293,291,288,
286,283,281,278,275,273,270,267,
265,262,259,256,253,250,247,245,
242,239,236,233,230,227,224,220,
217,214,211,208,205,202,199,196,
193,189,186,183,180,177,174,171,
167,164,161,158,155,152,149,146,
143,140,136,133,130,127,124,121,
118,115,113,110,107,104,101,98,
95,93,90,87,85,82,79,77,
74,72,69,67,64,62,60,57,
55,53,51,48,46,44,42,40,
38,36,34,33,31,29,27,26,
24,23,21,20,18,17,16,14,
13,12,11,10,9,8,7,6,
5,5,4,3,3,2,2,1,
1,1,0,0,0,0,0,0,
0,0,0,1,1,1,2,2,
3,3,4,5,5,6,7,8,
9,10,11,12,13,14,16,17,
18,20,21,23,24,26,27,29,
31,33,34,36,38,40,42,44,
46,48,51,53,55,57,60,62,
64,67,69,72,74,77,79,82,
85,87,90,93,95,98,101,104,
107,110,113,115,118,121,124,127,
130,133,136,140,143,146,149,152,
155,158,161,164,167,171,174,177,
};
void setup() {
  // put your setup code here, to run once:
    pinMode (8,OUTPUT);
    int x;
    Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  for (int x=0; x<=360; x++) {
     Serial.println(x);
  analogWrite(8,lookup[x]);
  }
}

this is code ive written quick to try and turn my PWM pin 8 to a sine wave. im using a low pass filter after it to see but this is not close at all :(.
i dont know if im accessing the array right

Analogwrite takes a number from 0 to 255, some of your values are greater than that.

ahhh now its a sine wave but very noisy, so im guessing x is incrementing by 1 which by that point is a new position in the array?

What are you using it for? Will you be able to understand that, whatever it is? Like putzing around with hardware timers?

i need to make 3 sine waves with 120 degree phase shift apart for now basically using the PWM on a arduino mega 2560

Is it a school assignment?

yes but the classes have no coding help so im just trying to understand the concepts right now

I don't believe that is possible. Then the entire class would fail.

well this is a nice thought aha

Your code produces a warning. There is no element 360 in your array. Arrays are zero indexed and your indexes run 0-359.

ive noticed this when i change the lookup table size so ive done this good spot

Generally one would keep the PWM frequency constant and change the increment value to get the desired sine wave frequency. Your table has 360 values, each representing one degree change in the sine wave, but the increment doesn't have to be 1 degree per step. You could increment by 2, 3, etc. You can even increment by non integer amounts and round to the nearest look-up-table index.

The link below describes "Direct Digital Synthesis" (DDS) implemented in hardware, but the procedure in software is essentially the same: https://www.analog.com/en/analog-dialogue/articles/all-about-direct-digital-synthesis.html

so do you mean increase the number of points on my lookup table??

You will need to do something about the timing between each analogWrite, at the moment that is limited by the Serial output buffer, which will vary with different number of digits in the numbers being printed. It also makes little sense to change the output more often than a single cycle of the pwm frequency.