qControl Tutorial
The Quarto can generate a nice user interface via qControl to interact with the Quarto. To start, we will have the Quarto generate some data (sine wave with noise) and plot that data in qControl:
Plotting Generated Data
#include "qCommand.h"
qCommand qC;
IntervalTimer Timer;
const uint16_t dataPoints = 1000;
float dataArray[dataPoints];
SmartData<float*> Data(dataArray);
void setup() {
qC.assignVariable("Simulation Data", &Data);
Timer.begin(generateData,10); //generate new data point every 10 µs.
}
void loop() {
qC.readBinary(); // must be in loop to process data for qControl
}
void generateData(void) {
static float phase = 0;
phase += 2 * PI * 10 / dataPoints ; // increment phase each time, so sets frequency
long random_int = random(-500,500); // random number -500 through 500
float noise = random_int / 1000.0 * 5; // rescale random number into float for noise
float data = 8.0*sin(phase) + noise; // calculate sine wave plus random noise
Data.setNext(data); // store data in SmartData object
if (Data.isFull()) {
phase = 0; //reset phase when array is full.
}
}
This code uses SmartData for handling the simulated data array. Please see the SmartData Tutorial and the SmartData documentation for more details on using SmartData objects.
qControl uses WebUSB for communication and requires a compatible web browser, such as Chrome (recommended) or other Chromium-based browsers such as Edge or Opera.
With this code loaded on the Quarto, we can open up qcontrol.qnimble.com, select the Quarto device (if it isn't listed in the pull down menu, select 'Add new device' and give the browser permission to access the Quarto device) and see the simulated Data:
Editing Variables
In the example above, there are no adjustable parameters so qControl has no controls, just a graph. However, we could set the amplitude, frequency and noise amplitude to be adjustable. Here's a new example that sets three new variables, amplitude, frequency and noiseAmp that can be controlled through qControl.
#include "qCommand.h"
qCommand qC;
IntervalTimer Timer;
const uint16_t dataPoints = 1000;
float dataArray[dataPoints];
SmartData<float*> Data(dataArray);
float frequency = 10;
float amplitude = 8;
float noiseAmp = 5;
void setup() {
qC.assignVariable("Simulation Data", &Data);
qC.assignVariable("Frequency", &frequency);
qC.assignVariable("Amplitude", &litude);
qC.assignVariable("Noise Amplitude", &noiseAmp);
Timer.begin(generateData,10); //generate new data point every 10 µs.
}
void loop() {
qC.readBinary(); // must be in loop to process data for qControl
}
void generateData(void) {
static float phase = 0;
phase += 2 * PI * frequency / dataPoints ; // increment phase each time, so sets frequency
long random_int = random(-500,500); // random number -500 through 500
float noise = random_int / 1000.0 * noiseAmp; // rescale random number into float for noise
float dataPoint = amplitude*sin(phase) + noise; // calculate sine wave plus random noise
Data.setNext(dataPoint); // store data in fakeData SmartData object
if (Data.isFull()) {
phase = 0; //reset phase when array is full.
}
}
Controlling the Layout
The size and placement of the variables controls (also called widgets) may not be where you want them. When you click
it puts qControl in a mode for editing the user interface. You can move and resize the different widgets and each displayed variable will have two icons in the middle of the section:
Click on the
to bring up a dialog to set how the variable is displayed. You can set the step size for incrementing / decrementing the variable and, if desired, setAuto Update to have the variable update automatically when changed without pressing the icon.
See the video more and get more details on the qControl Page.