Skip to main content

Pulsed Arbitrary Output Waveform

The Quarto can act an arbitrary waveform generator. But more than that, its output can be externally controlled. In this example, the Quarto outputs 10 periods of a 10 kHz sine wave whenever trigger signal goes high.

Setup

We will use a timer to set the update frequency on the analog output signal (DAC). We will instantiate this IntervalTimer object at the top of our code (and not inside a function) so it is accessible by any function. Additionally we will create another global variable, DACcounts to keep track of where in the waveform cycle the program is currently. This can be done with:

IntervalTimer DAC_Timer; //IntervalTimer object called DAC_Timer
int DACcounts = 0;

In the setup function, we configure trigger 1 as an input (this isn't strictly necessary since all digital signals start as inputs) and we configure the function start_pattern to run whenever there is a rising edge on trigger 1.

void setup() {
triggerMode(1, INPUT); // Set trigger1 as input
enableInterruptTrigger(1,RISING_EDGE,&start_pattern); //On rising edge, run start_pattern
}

Main Code

Now we define the function start_pattern that gets run on the rising edge of trigger 1. We want it to begin the sequence of updating the DAC with our analog output pattern. So we want to reset the DACcounts variable and enable the DAC_Timer.

void start_pattern() {  
DACcounts = 0; //reset DACcounts
DAC_Timer.begin(updateDAC, 1); //start timer to run every 1μs and call updateDAC
}

So, now whenever trigger 1 goes high, we will set DACcounts to 0 and start a timer to run the function updateDAC once per 1μs. The function updateDAC writes to the DAC and stops the timer when the sequence is complete.

void updateDAC() {
float value = 2.5 * sin(DACcounts * 2 * PI/100 ) ; //generate sin wave at 10kHz
writeDAC(1,value); //write value to DAC
DACcounts++; // increment DACcounts by one.

if (DACcounts == 1000) { // after 1000 data points (10 periods) stop
DAC_Timer.end();
}
}

Final Code

Putting this altogether (and code to pulse the LED every second), we have:

IntervalTimer DAC_Timer; 
unsigned int DACcounts = 0; //store how many DAC updates have been complete

void setup() {
triggerMode(1, INPUT); // Set trigger1 as input
enableInterruptTrigger(1,RISING_EDGE,&start_pattern); //On rising edge, run start_pattern
}

void start_pattern() {
DACcounts = 0; //reset DACcounts
DAC_Timer.begin(updateDAC, 1); //start timer to run every 1us and call updateDAC
}

void updateDAC() {
float value = 2.5 * sin(DACcounts * 2 * PI/100 ) ; //generate sin wave at 10kHz
writeDAC(1,value); //write value to DAC
DACcounts++; // increment DACcounts by one.

if (DACcounts == 1000) { // after 1000 data points (10 periods) stop
DAC_Timer.end();
}
}

void loop() {
static unsigned int lastrun1;
if (millis() > lastrun1 + 500) {
lastrun1 = millis();
toggleLEDGreen();
}
}

Data

Using this code, if when you send trigger 1 high, you'll get 10 cycles of a 10 kHz sine wave as shown below.

img