I am using the quarto to output a waveform at 16 us update intervals and I am seeing a strange voltage drop at the beginning and end of the signal. I did verify that the values computed by the quarto do not have these spikes. While verifying I noticed that adding a "delay" in the form of calling Serial2.printf("%d,%f", time, out); fixes my spike so I am unsure of what is going on.

Strange waveform (see spikes at beginning and end of waveform):

Normal waveform (uses call to Serial2):

Code:

// GLOBAL CONTROLS
#define DAC_UPDATE 16 // DAC update interval [us]
#define PERIOD 4000 // Period of control cycle [us]
#define TRAP_TIME 2000 // Time for trapping [us]


// Common objects
IntervalTimer Timer;
int time = 0;


// Update DAC function
void updateDAC() {
	if (time < PERIOD) {
	        float out = cosPower(TRAP_TIME, 1, 8);

		writeDAC1(out);
		writeDAC2(out);

		// Enabling this gets rid of the spikes seen at the start and end of the signal
		// Serial2.printf("%d,%f\r\n", time, out);

		time += DAC_UPDATE;
	} else {
		time = 0;
	}
}

float cosPower(int trap_time, float amplitude, int power) {
	float out;
	if (time < trap_time) {
		out = - amplitude * pow(cos(PI * time / trap_time), power) + amplitude;
	} else {
		out = 0;
	}
	return out;
}

void setup() {
	Timer.begin(updateDAC, DAC_UPDATE);
}

void loop() {
}

That is very strange. It's going to take a little time to dig to the bottom of what's going on. In the meantime, I have a few ideas for 'quick fixes' so you aren't waiting on a full / proper fix:

1) Can you try placing a small delay between the two DAC updates:

writeDAC1(out);
delayNanoseconds(100);
writeDAC2(out);
delayNanoseconds(100);

2) If that doesn't work, try pre-calculating the DAC update values. Here's a sketch of how to change your code to do that

const uint precalcSize = PERIOD / DAC_UPDATE;
float data[precalcSize];

void setup() {
  for (uint i=0; i<precalcSize; i++) {
    time = i*DAC_UPDATE;
    data[i] = cosPower(TRAP_TIME, 1, 8);
  }
  time = 0;
  Timer.begin(updateDAC, DAC_UPDATE);
}

void updateDAC() {
  if (time < PERIOD) {
    //float out = cosPower(TRAP_TIME, 1, 8);
    uint index = time / DAC_UPDATE;
    float out = data[index];
    writeDAC1(out);    
    writeDAC2(out);
  
    time += DAC_UPDATE;
  } else {
    time = 0;
  }
}

If neither of those work, please let me know.

Sorry for the bug and I appreciate your patience while we figure it and out and fix it.