Arduino Due Sine Wave Generator with Adjustable Frequency

 If you're looking for a simple way to generate a sine wave signal with adjustable frequency, the Arduino Due might be just what you need. In this Arduino Due tutorial, we'll cover what the Arduino Due is and the advantages of using it as a signal generator. We'll also explain the code used to generate a sine wave with adjustable frequency.

What is Arduino Due?

Arduino Due is a microcontroller board based on the Atmel SAM3X8E ARM Cortex-M3 CPU. It has 54 digital input/output pins, 12 analog inputs, 4 UARTs (hardware serial ports), a 84 MHz clock, and an Ethernet port. The board is compatible with most Arduino shields and can be programmed using the Arduino software.

Advantages of using Arduino Due as signal generator

The Arduino Due has several advantages when it comes to generating a sine wave signal with adjustable frequency. First, it has a built-in digital-to-analog converter (DAC), which allows it to output analog signals with high precision. Second, the board has a fast clock speed of 84 MHz, which allows it to generate sine wave signals with high frequency resolution. Finally, the Arduino Due is easy to program using the Arduino software, which makes it accessible to beginners and experienced programmers alike.

Programming Arduino Due for Sine Wave Generator with Adjustable Frequency

Below is the Arduino Due program to generate sine wave with potentiometer controlled frequency.

    #define N 120

    static int sinewave[N] = {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
    0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
    };

    int x = 0;
    int potPin = A3; // Analog input pin for the potentiometer

    void setup() {
    analogWriteResolution(12);
    }

    void loop() {
    // Read the analog value from the potentiometer
    int potVal = analogRead(potPin);

    // Map the potentiometer value to the frequency range of 100Hz to 2KHz
    double frequency = map(potVal, 0, 1023, 100, 2000);

    // Calculate the sine wave sample for the current time
    double sample = sinewave[x] / 2047.5;
    sample = sample * 2047.5 * 0.75; // Scale the output to 75% of the maximum output voltage

    // Write the sample to the DAC output
    analogWrite(DAC1, sample);

    // Calculate the time for the next sample based on the desired frequency
    double time = 1.0 / frequency;
    delayMicroseconds((int)(time * 1000000));

    // Move to the next sample in the sine wave array
    x++;
    if(x == N)
    x = 0;
    }

Now let's take a closer look at the code.

The code starts by defining a sine wave array sinewave with 120 values. These values represent the amplitude of the sine wave at each point in time. The array is defined as static because we want to store the values in memory permanently, rather than creating a new instance of the array each time the loop() function is called.

Next, the x variable is initialized to 0 and the potPin variable is set to the analog input pin for the potentiometer.

In the setup() function, we set the analog write resolution to 12 bits. This means that we will have 4096 possible values for the output voltage (0-4095).

In the loop() function, we first read the analog value from the potentiometer using the analogRead() function. The map() function is used to map the potentiometer value to the frequency range of 100Hz to 2KHz. The resulting frequency is stored in the frequency variable.

Next, we calculate the sine wave sample for the current time using the value of x to index into the sinewave array. We scale the output to 75% of the maximum output voltage to avoid overloading the DAC output. The resulting sample value is stored in the sample variable.

We then write the sample to the DAC output using the analogWrite() function.

Finally, we calculate the time for the next sample based on the desired frequency and delay for that amount of time using the delayMicroseconds() function. We increment x to move to the next sample in the sine wave array. If x reaches the end of the array, it is reset to 0 to start again from the beginning.

Below is the Arduino Due sine wave generator circuit diagram.

arduino due sine wave circuit

 In conclusion, the Arduino Due is a powerful microcontroller that can be used as a signal generator with the ability to adjust the frequency of the generated signal. The code provided above shows a simple example of generating a sine wave with adjustable frequency using the DAC output of the Arduino Due. With some modifications, this code can be adapted to generate other types of signals or to interface with other circuits or devices.

References and Further Readings

[1] Arduino DDS(Direct Digital Synthesis)

[2] Arduino Variable Frequency Function Generator  

[3] Arduino Signal Generator with ISR

[4] Arduino Frequency Counter

Post a Comment

Previous Post Next Post