Live UI Dashboard
Live UI Dashboard
The Live UI tab displays a real-time interactive dashboard driven entirely by your running firmware. Your firmware sends URL-encoded commands over the Active Debug Port channel, and the Live UI tab renders them as visual widgets, gauges, LEDs, text readouts, progress bars, and a battery indicator, that update live as data arrives.
This gives your embedded firmware a rich graphical display on your PC with no GUI framework, no RTOS dependency, and no display hardware on the embedded side. Just a few calls to ACTIVEText() or ACTIVEprintf().
How It Works
The Live UI is driven by special URL-encoded command strings embedded in your firmware's Active Debug Port output. When your firmware calls ACTIVEText(channel, "?cmd=gauge1&color=blue"), the application detects the URL-encoded command format, parses it, and configures that channel to display as a gauge widget with blue coloring.
After the widget type is configured, subsequent ACTIVEValue() calls on the same channel update the widget's displayed value (for gauge / progress / battery / slider widgets). For text-based widgets, subsequent ACTIVEText() calls with plain (non-command) strings update the displayed text. For LED widgets, resending the ?cmd=led&color=... string changes the color.
Widget state is recorded. Live UI widget states are captured in the timeline alongside all other data. When you open a saved capture and move the Current Cursor to a past point in time, the Live UI tab reflects what the dashboard looked like at that moment.
Accessing the Live UI Tab
Click the Live UI tab in the right-side panel, or use View > Show Live UI from the menu bar. During live capture, the tab updates in real time. During navigation of a saved capture, the tab shows the widget state at the Current Cursor position.
Firmware Command Reference
Widget Type Configuration Command
All widget type and color configuration is done by sending a URL-encoded string as the text on an Active Debug Port channel. The format is:
?cmd=<widget_type>&color=<color>
Send this string once to configure the channel as a specific widget type. The application remembers the widget type for that channel for the entire capture session.
The recognized widget type tokens are:
led1, led2, led3, led4, led5,
text1, text2, text3, text4, text5,
gauge1, gauge2, gauge3, gauge4, gauge5,
progress1, progress2, progress3, progress4, progress5,
battery.
A bare ?cmd=led (no digit) is a different feature: it controls the colour and blink rate of the physical RGB LED on the front of the pod, not a screen widget. See the LED system command covered later in this chapter.
Any ?cmd= value other than the widget tokens above and the system commands label, beep, stop, restart, zoomall, email, led (covered later) is ignored.
Example in C firmware:
ACTIVEText(0, "?cmd=gauge1&color=blue"); // Configure channel 0 as gauge style 1
ACTIVEText(1, "?cmd=led1&color=green"); // Configure channel 1 as LED style 1
ACTIVEText(2, "?cmd=text1&color=orange"); // Configure channel 2 as text style 1
The whole query string is folded to lowercase before lookup, so ?cmd=LED1&color=Blue and ?cmd=led1&color=blue behave identically. The lowercase forms above are preferred for clarity.
Numeric Widget Types (Updated with ACTIVEValue)
These widget types display a numeric value. Update them by calling ACTIVEValue(channel, value).
Gauges, gauge1 through gauge5
Five gauge styles are available, each with a different background and color scheme:
| Widget cmd | Visual style | |
|---|---|---|
gauge1 |
Default black background, black needle, white value text | |
gauge2 |
White background, default-color needle, black value text | |
gauge3 |
White background, default-color needle, black value text (alternate face) | |
gauge4 |
Black background, white needle, white value text | |
gauge5 |
White background, default-color needle, black value text (alternate face) |
Each gauge displays the needle position, the current numeric value, and the minimum and maximum values seen so far. Gauges auto-scale, the range is automatically set to the smallest and largest values received on that channel. There is no need to pre-set a range.
Example:
ACTIVEText(3, "?cmd=gauge1&color=red"); // Initialize once
// In control loop:
ACTIVEValue(3, motor_speed_rpm);
Progress Bars, progress1 through progress5
Horizontal progress bar displays. The value is shown as a percentage fill from 0 to 100.
| Widget cmd | Fill color | Text color | ||
|---|---|---|---|---|
progress1 |
dark blue | white | ||
progress2 |
light grey | black | ||
progress3 |
dim grey | white | ||
progress4 |
yellow | black | ||
progress5 |
lime green | black |
Example:
ACTIVEText(4, "?cmd=progress1&color=blue");
ACTIVEValue(4, battery_percent); // 0.0 to 100.0
Battery Indicator, battery
A battery-shaped indicator showing a percentage fill (0-100).
Example:
ACTIVEText(5, "?cmd=battery&color=green");
ACTIVEValue(5, battery_percent);
Text Widget Types (Updated with ACTIVEText)
These widget types display a text string. Configure them with a ?cmd=... string, then send subsequent plain text strings to update the displayed text.
Text Labels, text1 through text5
Five text display styles, each with a progressively larger font size:
| Widget cmd | Font size | |
|---|---|---|
text1 |
8 pt, bold | |
text2 |
10 pt, bold | |
text3 |
12 pt, bold | |
text4 |
14 pt, bold | |
text5 |
16 pt, bold |
The text is rendered right-aligned in the value color you set via the &color=... parameter; the channel label is rendered left-aligned in the default theme text color.
Example:
ACTIVEText(6, "?cmd=text2&color=cyan"); // Initialize once
ACTIVEprintf(6, "STATE: %s", state_names[current_state]); // Update during operation
LED Indicator Types (Updated with ACTIVEText)
Named LED Styles, led1 through led5
Five LED image styles. The LED visually illuminates in the colour given by the most recent plain text sent to that channel, not the &color= parameter on the ?cmd=ledN configuration (which is ignored for LEDs). Configure the widget once with ?cmd=ledN, then drive the colour by sending a plain colour name as text. Any string QColor can parse is accepted (red, lime, #FF8800, ...). If no text has been sent or the string is not a valid colour, the LED renders green.
Example:
ACTIVEText(7, "?cmd=led3"); // Configure once
ACTIVEText(7, "green"); // Initial colour
// Change colour later:
ACTIVEText(7, fault_active ? "red" : "green");
There is no
?cmd=ledwidget. The bare?cmd=ledtoken is a system command that drives the physical RGB LED on the front of the pod, not a screen widget. It is covered in the next section under Label and System Commands.
Channel Label Command, label
Sets the display name (label) of an Active Debug Port channel. Equivalent to calling ACTIVELabel() in the firmware library.
?cmd=label&label=<channel_name>
Example:
ACTIVEText(0, "?cmd=label&label=Motor Speed");
System Commands
These commands trigger actions in the application from your firmware.
| Command | Description | |
|---|---|---|
?cmd=beep |
Plays a system beep on the PC. Useful as an audible alert when a fault or threshold is crossed. | |
?cmd=stop |
Stops the current capture. Use this for firmware-driven triggered capture, stop automatically when the bug appears. | |
?cmd=zoomall |
Zooms the waveform display to show all captured data. | |
?cmd=restart |
Stops the current capture and immediately starts a new one. | |
?cmd=email&to=<address>&msg=<text> |
Sends an email alert. Requires email configuration in the application. |
Physical LED Command, led
Drives the RGB LED on the front of the pod (not a screen widget). The lookup is hardcoded, so colours outside the list below are ignored.
?cmd=led&color=<named_color>[&blink=<interval_ms>]
Available named colors: red, orange, yellow, green, blue, cyan, magenta, white, black. The optional blink parameter is an interval in milliseconds, omit it for steady illumination.
Example:
ACTIVEText(0, "?cmd=led&color=green"); // Solid green
ACTIVEText(0, "?cmd=led&color=red&blink=500"); // Blinking red at 500 ms
The channel number in ACTIVEText is irrelevant for ?cmd=led, the command affects the pod LED regardless of which channel it arrives on.
?cmd=stopvs. the trigger system: Both stop the capture from inside the captured data. Use?cmd=stopwhen your firmware is the authority on what counts as the "bug" and can detect it directly. Use the Buffer & Triggers tab when the condition is best expressed in terms of signals (analog edges, pulse widths, decoded text patterns) and you want the configurable pre / post-trigger window plus the ability to step between recorded triggers.
Complete Widget Setup Example
A typical firmware initialization sequence configures all widgets once at startup:
void active_debug_init(void)
{
ACTIVEText(0, "?cmd=label&label=Motor RPM");
ACTIVEText(0, "?cmd=gauge1&color=blue");
ACTIVEText(1, "?cmd=label&label=Supply V");
ACTIVEText(1, "?cmd=gauge2&color=green");
ACTIVEText(2, "?cmd=label&label=Status");
ACTIVEText(2, "?cmd=text2&color=white");
ACTIVEText(3, "?cmd=label&label=Fault");
ACTIVEText(3, "?cmd=led3");
ACTIVEText(3, "green");
ACTIVEText(4, "?cmd=label&label=Battery");
ACTIVEText(4, "?cmd=battery&color=green");
ACTIVEText(5, "?cmd=label&label=CPU Load");
ACTIVEText(5, "?cmd=progress3&color=grey");
}
void active_debug_update(void) // Call once per control loop
{
ACTIVEValue(0, motor_rpm);
ACTIVEValue(1, supply_voltage);
ACTIVEprintf(2, "STATE: %s", state_name);
ACTIVEText(3, fault_active ? "red" : "green");
ACTIVEValue(4, battery_percent);
ACTIVEValue(5, cpu_load_percent);
}
Tips
One widget per channel. A channel can only display one widget type at a time. If you send a new ?cmd=... configuration on a channel, the widget type changes immediately.
The color parameter is parsed as a QColor, so it accepts named colours (blue, red, lime, ...) and hex values like #FF8800. For led1-led5 widgets the &color= parameter is ignored, send the colour as a plain text string after the configuration command instead.
Live UI vs. graphed values: A gauge shows the current value as a needle position; an ACTIVEValue() graphed channel shows the value as a line chart over time. They are independent, the same channel can drive a Live UI widget AND be graphed on its waveform row, because the Live UI tab observes the value stream while the graph captures the time series.
Recall historical state: Because Live UI widget updates are timestamped and stored in the capture, scrolling the waveform back to an earlier time updates every widget on the Live UI tab to reflect what your firmware was reporting at that moment. This is useful when reviewing a stored capture and you want to see "what did the dashboard look like at the time of the fault?"