Skip to main content

Troubleshooting Guide

I can't upload new code (Quarto crashed)

Sometime the code Quarto executes will prevent it from handling the USB connection. When this happens, often you will get a pop-up message from the operating system that it is no longer able to communicate with serial port the Quarto is set to. When this happens, the only solution is to reboot the Quarto. This can be done in two ways:

  • Disconnect and reconnect power to the device
  • Press and a hold the front-panel button (left side of the Quarto) for 5 seconds. The blue power LED should turn off. Then release the button and press the button again for 2 seconds the blue LED should turn back on and the device will boot1.

When the unit reboots, it will go into the bootloader and the status LED will flash white for ~3 seconds. After this period, the Quarto will try to load the application code. If you do not want this to happen (the application code crashes the Quarto), press the front-panel button once while the Quarto is in the bootloader (it is flashing the status LED white) and the Quarto will stay indefinitely in the bootloader. When the button is pressed, the status LED should change to flashing red instead of white.

You can now load a different application code

Why is my Quarto crashing?

If you cannot reprogram the Quarto, is not responding to USB requests. Generally this is because an interrupt with a higher priority than USB is taking up all of the processor's time. For this reason, high priority interrupts such as those handling ADC data should not do much or execute functions that may be slow. Here's an example for code that will crash the Quarto:

Code that will crash the Quarto
void setup(void) {  
configureADC(1,1,0,BIPOLAR_1250mV,getADC1); // Have ADC take measurement every 1us, ±1.25V range
}

void getADC1(void) {
double newdata = readADC1_from_ISR(); //read ADC voltage
writeDAC(1,newdata);
Serial.println(newdata);
'Just and Example. Do not Run!'
}

The getADC1 interrupt is running every 1μs (the first argument, fire_every_us, is set to 1 in configureADC). Because this interrupt is handling incoming analog data, it has a higher priority than USB. If the function getADC1 takes over 1μs to execute, then new ADC data comes in while it is still executing. If this happens, as soon as getADC1 is finished, it will run again to handle this new data and again and again... and the processor will never respond to USB and it will appear to have crashed.

The solution to keep slow functions like Serial.print() out of high priority interrupts. One approach is to move the printing of the ADC data to the main loop:

Solution A (Main Loop)
volatile double adcdata;

void setup(void) {
configureADC(1,1,0,BIPOLAR_1250mV,getADC1); // Have ADC take measurement every 1us, ±1.25V range
}

void getADC1(void) {
adcdata = readADC1_from_ISR(); //read ADC voltage
writeDAC(1,adcdata);
}

void loop() {
static unsigned long lastrun = 0;
if (millis() > lastrun) { //Run once every 1000ms
lastrun = millis() + 1000;
toggleLEDGreen();
Serial.println(adcdata);
}
}

In the above example, the main loop is responsible for running the Serial.print() function, so it can get preempted by the ADC interrupt when necessary. While this example only prints the ADC data once per second, that isn't what is preventing the crash. If the loop were simply:

void loop() {
Serial.println(adcdata);
}

the Quarto would not crash as the the USB (and ADC) interrupts can preempt the loop function, so no matter how long loop() takes to run, the Quarto can respond to USB and ADC data.

If you want to have more controlled timing than a simple loop can provide, we can use a timer. By default the timer runs with a low priority so it too will get interrupted by the ADC or the USB, and this will prevent the Quarto from crashing.

Solution B (Timer)
volatile double adcdata;
IntervalTimer printTimer;

void setup(void) {
configureADC(1,1,0,BIPOLAR_1250mV,getADC1); // Have ADC take measurement every 1us, ±1.25V range
printTimer.begin(debug, 100); // run debug() every 100 microseconds
}

void getADC1(void) {
adcdata = readADC1_from_ISR(); //read ADC voltage
writeDAC1(adcdata);
}

void loop() {
static unsigned long lastrun = 0;
if (millis() > lastrun) { //Run once every 1000ms
toggleLEDGreen();
lastrun = millis() + 1000;
}
}

void debug() {
Serial.println(adcdata);
}

  1. If you have an evaluation unit, then there are two buttons on the front panel, but only the button on the right (closest to the BNC connector) should be used. Additionally, the blue LED will not turn off when the Quarto is powered down. After holding the button for >5 seconds, release the button and press it again for >2 seconds and the device should boot again.