Arduino Giga Advanced Analog Library Problem for DAC

Hi all,

We tried to produce 1 kHz in loop for a process. We use Arduino Giga and using Arduino_AdvancedAnalog.h for DAC. But some problems, that we dont undestand, blocks DAC 1 kHz generation and while we measure it on multimeter, we get different frequency values. Sample code like this :

(Original sample : [https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-audio#waveform-generation-with-the-giga-r1-dacs](https://ARDUINO GIGA DAC Sample))

// This example outputs an 8KHz square wave on A12/DAC0.
#include <Arduino_AdvancedAnalog.h>

AdvancedDAC dac1(A12);

void setup() {
    Serial.begin(9600);

    while (!Serial) {

    }

    if (!dac1.begin(AN_RESOLUTION_12, 2000, 32, 64)) {
        Serial.println("Failed to start DAC1 !");
        while (1);
    }
}

void dac_output_sq(AdvancedDAC &dac_out) {
    if (dac_out.available()) {

        // Get a free buffer for writing.
        SampleBuffer buf = dac_out.dequeue();

        // Write data to buffer.
        for (int i=0; i<buf.size(); i++) {
            buf.data()[i] =  (i % 2 == 0) ? 0: 0xfff;
        }

        // Write the buffer to DAC.
        dac_out.write(buf);
    }
}

void loop() {

    dac_output_sq(dac1);

    /*****************/
    //The following part causes corruption for creating and measuring 1 kHz frequency
    int i = 0;

    for(i=0; i<10000; i++)
    {
      Serial.println(i);
    }
    /*************************/
}

The original example and the above example that was written by us, can work perfectly as we just write dac_output_sq(dac1); in loop function. But while we add other parts of our code, the frequency value, that we want as 1 kHz, is started to be freak values in multimeters.

How can we solve this problem ? Do you have any algorithm or code advices ? Or we use something in wrong places ?

Thanks a lot for your helps

Yes what else do you expect? This is what will happen.

Adding a delay in the loop function like this is not the way to ensure that the loop executes at constant speed.

You either need to use the micros timer to make a note of the time when you started the last DAC output. And then compare when the micros timer minus the start time to see if 1mS has elapsed.

Or you need to set a timer to cause an interrupt every 1mS and in the interrupt service routine do the output to the DAC.

Thanks a lot for your answer, sorry we are beginner so we can ask low level questions. For loop function can we write like this ?

int last_millis = 0;

void loop()
{
if(millis() - last_millis < 1)
{
dac_output_sq(dac1);
}

.........

//Then our other outside functions, IOT communications etc.
}

We tried it but no success. Please show us how can do this ? By the way we cannot find anything about using timers for Giga...

Again so sorry for beginner question, but we try to learn something

Last millis variable should be an unsigned long type, an int variable can not hold the size of numbers you need.
Also I said to use the micros counter not the millis counter.

Also when you send out the A/D reading you should make the lastWhatEver variable equal to the current micros count.

Thanks a lot, we will try this.

Also both millis and micros return whole numbers so saying < 1 is when you don't want to send anything not when you do.