I need to sample a sine wave in order to create a lookup table. I know the Shannon theorem but I still don't understand how to apply it. I want to have 256 discrete samples of the sine wave that will have to be output with a frequency of 100Hz. I know that the formula to calculate the samples is: amplitude*sin(2 * pi_g * sample_rate * t) with t that varies from 0 to a certain number. Can you explain me how to calculate the samples in order to have the possibility to output a sine wave with a frequency of 100Hz? In order to obtain a continous function, t has to vary from 0 to what number?

  • 1
    \$\begingroup\$ My first step would be to implement a generic sine function or lookup table sin(x) without involving time or sample rate. Think also about linear interpolation for your lookup table (also: the samples of the lookup table don't have to be evenly spaced). The next step is then to read up on Shannon once again and to calculate how many updates per second your software has to do in order to output a somewhat clean sine wave (hint: more than just 2*100). If you are familiar with Excel/Matlab you can prototype the last part to get an idea. \$\endgroup\$ – 0x6d64 Feb 22 '18 at 11:14
  • \$\begingroup\$ The data in the table has nothing to do with the final sine frequency. All you need to store is 1/4 cycle. You get the other three 1/4 cycles by flipping the index and/or flipping the result. I go into lots more detail in the answer to the question linked above as being a duplicate. \$\endgroup\$ – Olin Lathrop Feb 22 '18 at 11:59
  • 2
    \$\begingroup\$ I don't think that this question is a duplicate of the one that it was closed for. \$\endgroup\$ – Andy aka Feb 22 '18 at 16:29

One full cycle of a sine wave "maps" to a circle turning through 360 degrees: -


Source: https://www.electronics-tutorials.ws/accircuits/phasors.html

So, at an angle of 30 degrees, if you calculate sin(30) on your computer or calculator you get 0.5 i.e. the sine amplitude is 0.5. At 60 degrees it's 0.866 (or \$\sqrt{0.75}\$ if you did the math/trigonometry).

At 90 degrees it's 1.

If your computer or calculator uses radians (rather than degrees) then 360 degrees is \$2\pi\$ radians.

I want to have 256 discrete samples of the sine wave that will have to be output with a frequency of 100Hz

If you want 256 samples over a period of 10 ms (a frequency of 100 Hz) then you need to calculate every 39.0625 micro seconds (about every 1.406 degrees).

You can of course use RLC output filters and dramatically reduce the number of samples you need to calculate. Here is a picture of a filter used to convert a basic square wave to a sine wave using an RLC low pass filter: -

enter image description here enter image description here

The picture shows: -

  • Top - square wave in (red) and sine wave out (blue) i.e. the transient response
  • Middle - the bode plot of the filter used
  • Bottom - the circuit used

Bear in mind this was for converting a 500 kHz square wave into a 500 kHz sine wave so to make this work at 100 Hz needs considerable value changes. I'd use sallen key filters instead at 100 Hz.

  • 2
    \$\begingroup\$ Note, you only need to store samples for a quarter wavelength, everything else can be garnered from that. \$\endgroup\$ – Colin Feb 22 '18 at 11:23
  • \$\begingroup\$ @Colin__s absolutely! \$\endgroup\$ – Andy aka Feb 22 '18 at 11:30
  • \$\begingroup\$ @Andyaka I don't need an RLC filter because I'm going to use the DAC port of the arduino. What you are suggesting is to output the each value of the lookup table every 39.06 microseconds? \$\endgroup\$ – Antonio Iannacci Feb 22 '18 at 15:04
  • \$\begingroup\$ @AntonioIannacci it's not a suggestion, it's a fact based on what you said in your question - if you want to make a cycle of sine from 256 points then each point occurs every 256th of a cycle and if a cycle lasts 10 ms (for a 100 Hz sinewave) then each point must be outputted every 10 ms/256 = 39.06 us. Don't rule out filtering - you could reduce the number of points to just a few with decent filtering as I showed in the filter example I gave. \$\endgroup\$ – Andy aka Feb 22 '18 at 16:24
  • \$\begingroup\$ Do you know how to convert the frequency in a value that can fit into the counter of Arduino in order to output each value of the sine wave every 39.06? \$\endgroup\$ – Antonio Iannacci Feb 23 '18 at 9:01

sin_fkt = amplitude * sin(2 * pi * 100 * t)

t_start = 0

t_end = 10ms

Go in steps of dt = 10ms/256 = 39.06us

  • \$\begingroup\$ Could you explain me how you can reach that formula? Moreover I should output a value every 39.06 micro seconds, right? \$\endgroup\$ – Antonio Iannacci Feb 22 '18 at 15:19
  • \$\begingroup\$ The equation is simply y=sin(omega*t). This is how I did it once. You output a value every 39.06us (I synchronized to a reference signal to keep the frequency of 100Hz constant - I don't know if this is a requirement for you). The value which you output is given by the equation (I precalculated it and wrote it into a table). So, you calculate the sin_fkt-value for t=0, t=1*39.06u, t=2*39.06u, t=3*39.06u...., t=256*39.06u. And then start at t=0 again. \$\endgroup\$ – UweD Feb 22 '18 at 19:43
  • \$\begingroup\$ You can use this link to see how to present mathematical equations and expressions in a readable way in your answers -- math.meta.stackexchange.com/questions/5020/… \$\endgroup\$ – Mitu Raj Feb 22 '18 at 20:39

To obtain a continuous function straight from a sampled system, you need an infinity of samples spaced infinitely closely.

Methinks you are asking the wrong question. To obtain a continuous function from a sampled data system plus a reconstruction filter, you need a sample rate and number of samples appropriate to the reconstruction filter you have chosen. Or choose a filter appropriate to your choice of sample rate.

You can choose any sample rate you want between the Nyquist criterion and infinity - that's up to you. Then calculating the number of samples you need, and their values, is trivial.


Not the answer you're looking for? Browse other questions tagged or ask your own question.