Generation of sine wave using arduino due

Hello all
I need to generate a sine wave using arduino due. I need a sine wave at different frequencies(250Hz,500Hz) with different amplitudes.

One place to start your journey would be to use your favorite search engine, with the phrase "Arduino DDS audio tone generation".

C++ can calculate the sine or you can make a table. A table is pretty common. And if you use a table you only need to store 90 degrees worth of data and then you can reverse and invert to get the full 360 degrees.

If you don't know how analog is digitized/quantized, the Audacity Website has a good introduction.

One of the "tricks" is to have a known sample rate. If the sample rate is wrong or unknown the frequency will be wrong.

Also note that the Due can't put-out negative voltages so the data & output will have to be biased (typically at half the DAC range). In the digital domain, bias is simply a fixed value added to each sample. The bias can be taken-out with a capacitor (a "high pass" RC filter).

There is also usually a low-pass "smoothing filter".

C++ uses radians (not degrees) for trigonometric calculations. But of course if you make a table you can use degrees.

The amplitude is scaled by multiplication of each sample... If you want to cut the amplitude/voltage in half, multiply all of the values by 0.5, etc.

didnt get u properly iam a new learner. Can you explain in simpler terms

Also, the FasLed library contains wave generation functions such as sine and other trig functions: FastLED: Fast trig functions

How to generate a sine wave using arduino due of variable frequency and amplitude. I want to view the sine wave in serial plotter

is this related to Timers in arduino due or Generation of sine wave using arduino due ?

please keep everything under one post.

Do yourself a favour and please read How to get the best out of this forum and post accordingly

➜ merging

You spent 9 days. What did you learn?
Where are you stuck?
What do you know?
-sample rate?
Do not expect us to do your work. Present your latest effort. Tell what it does and what it is supposed to do.
Take small steps.
Why not make a square wave first?


#include <cmath>
float time_period;
float sine;
float duration;
void sine_wave()
{
  time_period=1.0/160000;
  for(float i=0;i<=0.5;i=i+time_period)
  {
    sine=50*sin(2*M_PI*8000*i);
    Serial.println(sine);
    }
  }
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(DAC1,OUTPUT);
  sine_wave();
}

void loop() {
  // put your main code here, to run repeatedly:
}

And this the sine wave iam getting

Iam getting a sine wave but it is not correct because i need the sin wave to be generated in 0.5 seconds and i want the wave to be sampled for every 1/160000 seconds (If i try to take less than 160000 then the shape of the waveform is not correct). I request everyone to help me please i have been trying to do the same from many days back.

Great attempt. I will have a look at it...

You are adding a small number many times. Rounding errors will accumulate. The last decimal of 1/160000 does not fit in float variable..

So, let i be an integer.
We want to see a sine, so we might need 100 samples.
for (int i=0; i<100; i++){

Now:
We would like a full wave.

 sine[i]=sin(2.0*PI*i/100.0);

If you want to see 2 waves, replace 100 with 50.
You cannot really sample 160000 times because that would not fit in memory and also not on your screen.

where is frequency in that??. I need a sine wave of a particular frequency say 8KHZ.
My main aim is to produce a tone of particular frequency and i also need to change the loudness of the tone as my need. So to produce tone iam generating a sine wave of particular frequency and by using analogWrite to my DAC pin i will get a tone.By changing the amplitude of the sine wave i can change my loudness

How many samples per wave do you want? 8, 16 etc?
If you are happy with 8 samples per wave you have to run a timer at 64KHz. On each interrupt from the timer you must send a new value (representing voltage) to the DAC.
That value is selected from a sine table. The first value is sin(0) degrees, the next sin(45), sin(90) etc. You'll see it soon starts repeating. You multiply this value by you loudness factor.

can you give me a sample code for Arduino Due because i have no knowledge about timers.

Maybe this timer library works for you: arduino-timer - Arduino Reference
Try the simple example of blinking a led then scale it up to 64KHz.

This will not be easy...
If you want to set the pwm pin 64000 times per second, the pwm freq must be above that freq.
I do not know for due, but standard pwm freq is usually much slower.
So you will need to dive into register settings to increase pwm frequency. This may have consequences for built in functions that use the same timer (millis, micros).
Analogwrite tends to be slow. Maybe too slow. So again, you might have to write your output directly to the registers.
I also recommend to use a lookup table for sin values and to use integer math. Integer math is way faster than float math...

If you want to check if your function is fast enough, you need to record micros before and after calling the function.
You need to remove serial inside your for loop (that will take too much time).
You will need to store your data in an array, that you can print later (after final micros). Otherwise the compiler might optimize your function away...
...you might also add volatile to your declaration to protect it from optimization...

I'm not sure about this. The PWM frequency is, as far as I see, irrelevant here. Relevant is only the rate at which the timer generates interrupts. In the case of an 8KHz signal and 8 samples per wave that is 64KHz which is a relatively low frequency (but still probably too high for big calculations with high resolution trig functions) so the idea of using a lookup table is good. Since it all repeats, the table would, in the case of 8 samples, need only 8 entries, which are simply incrementally cycled through, once per call of the Interrupt Service Routine. Actually it is only an example and only 8 samples per wave would be a quite rough sine wave.
Since the sin value ranges from -1 to +1 an offset of say +1 has to be added to keep the values positive and then a multiplication factor to get the required output range (probably 0 to 3.3volts) to the DAC

OP mentions a DAC pin. I presumed that would be a PWM pin...
If OP has another DAC connected via i2c or whatever protocol then that communication needs to be sufficiently fast.

The two DAC pins on the Due have a true analog output (i.e. not simulated with PWM) when written to by analogWrite() at least, according to this: analogWrite() - Arduino Reference

There is no need for PWM here. We just set the DAC to a certain voltage level for a length of time, then change to the next voltage and repeat. Why not do what the experts do, and generate the sine wave at the max voltage possible and use an output attenuator?