udpscope plots a live UDPStreamer source. One window holds up to eight rows of plots,
each with up to four traces, and every row shares one time axis, so the whole figure
scrolls together. Acquisition runs on its own thread and writes a ring buffer sized from
The stream is the clock. Every interval you read on screen is measured between timestamps the source sent, never your machine's, so a stalled source freezes the view instead of scrolling it — and a source whose clock steps still gets the window you asked for.
The time axis is relative to now. While streaming it is a fixed
[-window .. 0] with the newest sample at 0, so x reads as an age:
-1.5s is a sample a second and a half old. In trigger mode 0 is the event's
edge instead, and a paused view keeps the ages it was frozen with. The source's own clock
is still there when you need it — an export writes it as a second column.
One figure of three rows with three signals plotted, a badge for each in the badge
bar, the dock with its readouts and its events block, and the status bar reading
Start the app with a source
(
The signals arrive disabled. Nothing is acquired until you turn one on in the
signal list, and enabling is what starts acquisition — so a freshly opened scope with an
empty badge bar is working correctly, not failing to connect. For the same reason a start
that has enabled nothing prints no buffer allocated: line on stderr.
Over SSH with X11 forwarding the window may never appear, and the cure is
vkCreateSwapchainKHR() ... VK_ERROR_INITIALIZATION_FAILED warning is
GTK's default Vulkan renderer failing to make a swapchain and is what the option's
GSK_RENDERER=cairo answers; a window whose allocation stays zero
(window_button_w=0) means the plot's GL area has no context either, and
that is what its LIBGL_ALWAYS_SOFTWARE=1 answers. Both variables are
exported before GTK initialises, because they are read when the renderer and the GL
context are created.
See Choosing a source for the chooser and the multicast options in full.
Left to right: the time window (
Up to eight rows, each with its own y axis and up to four traces, all on one shared time axis. Right-click a row for its own menu (fit, add a signal, remove a trace).
The strip under the plot. On the left, one badge for each signal you have switched
on, then a
One panel, 360 px wide, slides over the plot's right edge and shows one page at a
time: the trigger, a signal's colour, calibration and rows, the list of signals to
add, the cursors, the measurements, the events, or a source's own controls. It closes
with a second click on the badge that opened it, with
The column on the right, which the dock button in the header bar (
The last line, under the badge bar — the state word, the stored sample rate and the window, and the ⓘ beside it for packets, gaps and the buffer's own figures. The second screenshot below is what a capture looks like: the trigger marker at the edge and the axis pinned to the event.
The trigger marker sits at x = 0 and the pre-trigger share of the window is drawn to its left.
Connect. With no
Enable a signal in the
Drag its badge onto a row. Drop a second signal on another row, or the same signal again for a second view of it. The colour is per signal, so it is the same one wherever it appears.
Set the window with the control in the header bar: type a number, pick a unit, or step a decade. The trigger's event window is a share of this span, so a window change moves it.
Pause (
Arm the trigger (
Measure it — press
Save the data with
A signal nobody enables costs nothing — no buffer, no socket work, no measurements.
The window remembers itself. Rows, traces, the time window, calibration, which signals were enabled, the math channels with their graphs, and the measurements are written per host and port, and reloaded the next time you open that source.
A very wide window on a fast stream is drawn from averaged groups of samples, so the rate in the status bar falls: that is the anti-alias filter, not a fault — striding would fold a fast signal back as a slow one, which looks entirely plausible on screen.
Every instrument the app computed — the trigger marker, the measurement marks — is locked to the pointer's reach. The cursors are yours to drag; those are not.
The manual is a help set the desktop viewer reads off disk, so
For a system-wide or packaged install:
For your own account, needing no root: