Sine wave burst on Arduino Giga R1 with AdvancedAnalog lib

Hi! I am trying to send 10 cycle burst of sine waves with DAC using AdvancedAnalog library on Arduino Giga R1. I need to generate this burst and then disable DAC (or send zeros). Then I do some processing and repeat the whole thing again.

The problem is, when I measure DAC output with an oscilloscope, the output is very inconsistent. Sometimes I get 10 cycles and sometimes 6 or 2, the interesting thing is that these exactly -4 or -8 are repeated errors. I tried to play with depth queue and other parameters, but nothing helps.

Here is minimal example and screenshots from oscilloscope:

#include <Arduino_AdvancedAnalog.h>

/* -------------------------------------------------------------------------- */
/*                                  Settings                                  */
/* -------------------------------------------------------------------------- */

#define DAC_PIN          	A12
#define DAC_SINE_FREQ     	32000                   // 32kHz
#define DAC_RESOLUTION    	AN_RESOLUTION_12        // 12bit
#define DAC_SAMPLE_RATE    	DAC_SINE_FREQ * 64      // ~2MHz
#define DAC_SAMPLES_PER_CH	sine_lut_size    	    // samples in each buffer (one sine wave)
#define DAC_QUEUE_DEPTH 	11                      // queue depth

AdvancedDAC dac0(DAC_PIN);

// how many LUT repeats for one DAC transfer
const uint16_t dac_cycle_num = 10;

// DAC transfered symbols
const uint16_t sine_lut[] = {
    0x0000,0x000a,0x0027,0x0058,0x009c,0x00f2,0x0159,0x01d1,0x0258,0x02ed,0x038e,0x043a,0x04f0,0x05ad,0x0670,0x0737,
	0x0800,0x08c8,0x098f,0x0a52,0x0b0f,0x0bc5,0x0c71,0x0d12,0x0da7,0x0e2e,0x0ea6,0x0f0d,0x0f63,0x0fa7,0x0fd8,0x0ff5,
	0x0fff,0x0ff5,0x0fd8,0x0fa7,0x0f63,0x0f0d,0x0ea6,0x0e2e,0x0da7,0x0d12,0x0c71,0x0bc5,0x0b0f,0x0a52,0x098f,0x08c8,
	0x0800,0x0737,0x0670,0x05ad,0x04f0,0x043a,0x038e,0x02ed,0x0258,0x01d1,0x0159,0x00f2,0x009c,0x0058,0x0027,0x000a
};
const size_t sine_lut_size = sizeof(sine_lut) / sizeof(sine_lut[0]);

/* -------------------------------------------------------------------------- */
/*                                    Setup                                   */
/* -------------------------------------------------------------------------- */
void setup() {
    Serial.begin(115200);
    dac0.begin(DAC_RESOLUTION, DAC_SAMPLE_RATE, DAC_SAMPLES_PER_CH, DAC_QUEUE_DEPTH);
}

/* -------------------------------------------------------------------------- */
/*                                    Loop                                    */
/* -------------------------------------------------------------------------- */
void loop() {
    for (uint16_t i = 0; i < dac_cycle_num; i++) {
        dac_output_sinewave(dac0);
    }
    dac_output_zero(dac0);
    
    // do something
    delay(100);
}

/* -------------------------------------------------------------------------- */
/*                                  Functions                                 */
/* -------------------------------------------------------------------------- */
void dac_output_sinewave(AdvancedDAC& dac_out) {
    while(!(dac_out.available()));

    SampleBuffer buf = dac_out.dequeue();
    for (size_t i = 0; i < buf.size(); i++) {
        buf[i] = sine_lut[i];
    }

    dac_out.write(buf);
}

void dac_output_zero(AdvancedDAC& dac_out) {
    while(!(dac_out.available()));

    SampleBuffer buf = dac_out.dequeue();
    for (size_t i = 0; i < buf.size(); i++) {
        buf[i] = 0;
    }

    dac_out.write(buf);
}

ezgif-6-4b02f5567e

Could it be that the refresh rate of your scope is playing tricks?

First I would check is to do it slower to see if all data is sent.
Then gradually speed up the signal to see what happens.

I think with 100ms delay I should have enough refresh rate (I use trigger with rising edge). I tried to increase to 1sec and the result is the same. I use Analog Discovery 2 with 100MHz sampling rate for reference.
I also tried to plot the DAC wave connecting it to ADC and plotting it in MATLAB via serial to confirm that it is probably not the scope fault. In MATLAB I saw the same missing cycles.

I tried to lower the frequency and this weird behavior happens less often!
(sorry for low res gifs)

#define DAC_PIN          	A12
#define DAC_SINE_FREQ     	32000                   // 32kHz
#define DAC_RESOLUTION    	AN_RESOLUTION_12        // 12bit
#define DAC_SAMPLE_RATE    	DAC_SINE_FREQ * 2       // 64kHz
#define DAC_SAMPLES_PER_CH	sine_lut_size    	    // samples in each buffer (one sine wave)
#define DAC_QUEUE_DEPTH 	11                      // queue depth

64kHz

Then I tried 32kHz and the problem disappears at all (I looked at scope for about 2 minutes)

#define DAC_PIN          	A12
#define DAC_SINE_FREQ     	32000                   // 32kHz
#define DAC_RESOLUTION    	AN_RESOLUTION_12        // 12bit
#define DAC_SAMPLE_RATE    	DAC_SINE_FREQ * 1       // 32kHz
#define DAC_SAMPLES_PER_CH	sine_lut_size    	    // samples in each buffer (one sine wave)
#define DAC_QUEUE_DEPTH 	11                      // queue depth

32kHz

The library example showed continuous wave at 32kHz*64 ~= 2MHz, so in the end I should have the option to achieve at least 1MHz.

as the buffer if filled the same over and over again.
maybe rewrite this - see below - and pass a parameter times => 10

void dac_output_sinewave(AdvancedDAC& dac_out, int times) {
    if (times < 1) times = 1;
    while(!(dac_out.available()));

    SampleBuffer buf = dac_out.dequeue();
    for (size_t i = 0; i < buf.size(); i++) {
        buf[i] = sine_lut[i];
    }
    for (int i = 0; i < times; i++) 
    {
      dac_out.write(buf);  //  is this an asynchronous call ?
      //  while(!(dac_out.available()));
     }
}

Can the "missing waves" also be reproduced with a square wave?

I think, I've tried every possible combination of parameters, loops and etc.
Even sent the whole 10 cycles in one go as single LUT. The result looked strange and the intended stable burst wasn't achieved.

If someone has the same issues, I've written basic custom lib for DAC:

GitHub - ShiegeChan/SensEdu: RADAR and Communication Development Shield

You can find examples for single, burst and continuous waves at

libraries\SensEdu\examples\Send_DAC_Single_Sine\
libraries\SensEdu\examples\Send_DAC_Burst_Sine\
libraries\SensEdu\examples\Send_DAC_Const_Sine\

Here is the demonstration for ultrasonic measurements with 10 cycles sine at 2MHz sample rate:
10cycleWaveSensEdu

Still, if someone would have a working example for stable burst wave with AdvancedAnalog lib, it would be nice to have here.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.