user87161: Good Morning to everyone,
I am a PhD Student in experimental fluid mechanics at the University of Naples "Federico II", Italy. I am working on Arduino Due card and i am novel in applications using it. First, I need to generate a sine wave with variable frequency and amplitude. I tried to download several codes which are able to generate sine waves with a pre-defined frequency, but I would like to change this value of frequency at the beginning of the execution of the code. How could i do this ?
Second, I would like to change, in real-time, the output voltage of Arduino DAC0 or DAC1 at high speed to generate an arbitrary waveshape.. Is it possible?
Thank you in advance for your answers.
Dr. Alessandro Scala

user7508: The formula commonly used to represent a sinusoidal signal is
V = A cos(ωt)
where A is the amplitude and ω is the angular frequency. This formula
should cope well with a variable amplitude. It is, however, not suitable
for a signal with variable frequency, because a discontinuity of the
frequency is not supposed to create a discontinuity in the signal.
The correct formula for a signal where both the amplitude and the
frequency can vary is
V = A(t) cos(φ(t))
where the phase is computed as
φ(t) = ∫ ω(t)dt
In terms of code, this means you need a static variable to keep track of
the current phase, and you have to update it periodically in order to
perform the numerical integration.
Here is a tentative implementation. I have qualified some variables as
extern only to hint that you are responsible for managing them. You
can remove the qualifier if you integrate this into your own code:
// Defined and updated elsewhere.
extern const uint8_t output_channel;
extern float angular_frequency;  // in rad/us
extern float amplitude, offset;  // in ADC steps

// Call this as often as practical.
void update_output()
{
    // Compute the time delta.
    static uint32_t time_of_last_update;
    uint32_t now = micros();
    uint32_t dt = now - time_of_last_update;
    time_of_last_update = now;

    // Update the phase.
    static float phase;
    phase += angular_frequency * dt;
    while (phase >= 2 * M_PI) phase -= 2 * M_PI;  // unwrap

    // Output the signal.
    float output = offset + amplitude * cos(phase);
    analogWrite(output_channel, round(output));
}

Regarding the second part of the question (about arbitrary waveshapes),
it is, of course, feasible. You just have to pass arbitrary values to
analogWrite().

87161: <p>Good Morning to everyone,
I am a PhD Student in experimental fluid mechanics at the University of Naples &quot;Federico II&quot;, Italy. I am working on Arduino Due card and i am novel in applications using it. First, I need to generate a sine wave with variable frequency and amplitude. I tried to download several codes which are able to generate sine waves with a pre-defined frequency, but I would like to change this value of frequency at the beginning of the execution of the code. How could i do this ?
Second, I would like to change, in real-time, the output voltage of Arduino DAC0 or DAC1 at high speed to generate an arbitrary waveshape.. Is it possible?
Thank you in advance for your answers.</p>
<p>Dr. Alessandro Scala</p>
 7508: <p>The formula commonly used to represent a sinusoidal signal is</p>
<p>V = A cos(ωt)</p>
<p>where A is the amplitude and ω is the angular frequency. This formula
should cope well with a variable amplitude. It is, however, not suitable
for a signal with variable frequency, because a discontinuity of the
frequency is not supposed to create a discontinuity in the signal.</p>
<p>The correct formula for a signal where both the amplitude and the
frequency can vary is</p>
<p>V = A(t) cos(φ(t))</p>
<p>where the phase is computed as</p>
<p>φ(t) = ∫ ω(t)dt</p>
<p>In terms of code, this means you need a static variable to keep track of
the current phase, and you have to update it periodically in order to
perform the numerical integration.</p>
<p>Here is a tentative implementation. I have qualified some variables as
<code>extern</code> only to hint that you are responsible for managing them. You
can remove the qualifier if you integrate this into your own code:</p>
<pre class="lang-cpp prettyprint-override"><code>// Defined and updated elsewhere.
extern const uint8_t output_channel;
extern float angular_frequency;  // in rad/us
extern float amplitude, offset;  // in ADC steps

// Call this as often as practical.
void update_output()
{
    // Compute the time delta.
    static uint32_t time_of_last_update;
    uint32_t now = micros();
    uint32_t dt = now - time_of_last_update;
    time_of_last_update = now;

    // Update the phase.
    static float phase;
    phase += angular_frequency * dt;
    while (phase &gt;= 2 * M_PI) phase -= 2 * M_PI;  // unwrap

    // Output the signal.
    float output = offset + amplitude * cos(phase);
    analogWrite(output_channel, round(output));
}
</code></pre>
<p>Regarding the second part of the question (about arbitrary waveshapes),
it is, of course, feasible. You just have to pass arbitrary values to
<code>analogWrite()</code>.</p>
