Files
udpscope/docs/USER-GUIDE.md
T

13 KiB

udpscope — user guide

A viewer for a UDPStreamer source: it connects, decodes the CONFIG, plots the signals you enable, and lets you freeze, measure and derive from them. This is the user guide; README.md documents what was built and why, and SPECS.md is the requirement document.

the main window

The main window with a source streaming: the header bar above (the window control — 2 s — first on the left), the plot, the badge bar under it with one badge per signal, the status line at the foot, and the dock on the right with the cursor and measurement readouts and the events block.

The window is a plot with three things around it:

  • the badge bar under the plot: a badge for each signal you have switched on, a + to add one (past six they fold into one N signals badge), and, on the right, Trigger and — only for a source with controls of its own — Source;
  • the side panel, which a badge opens over the plot's right edge, one page at a time: the trigger, a signal, the list of signals to add, the cursors, the measurements, the events, or a source's own controls. A second click on the badge, Esc, Close or a click on the plot closes it, and it never resizes the plot;
  • the dock on the right, which the dock button in the header bar (s) shows and hides: read-only Readouts of the cursors and of the measurements, each with an Edit button that opens its page, and an Events block.

1. Connecting

udpscope                                              # asks which source to open
udpscope --server 10.0.0.5 --port 8000                # connect straight away
udpscope --server 239.1.2.3 --port 8000 --multicast 239.1.2.3 --interface 10.0.0.9

With no --server the app shows a chooser: the sessions it has stored, each naming its source, plus a form for a new host. A source opened from the list reconnects to the multicast group and interface it was stored with.

A unicast source serves one client at a time. A second viewer's CONNECT displaces the first, and they take turns — the status line says so when it happens. Watching one source from several instances needs --multicast <group> with --interface <local address>.

Every launch is its own process, so running two scopes side by side is fine.

2. The status line

At the foot of the window, under the badge bar, it reads ● <state> · <rate> · <window>, and the ⓘ beside it opens the detail: packets, frames, gaps, per-channel sample counts, the buffer's span and its decimation.

  • The state word is one word from a fixed set: live, paused, armed, capturing, event held, disarmed. no data appears in the rate's place when nothing is arriving.
  • The rate is the stored rate, which is the wire rate only while the whole requested window fits in the buffer. A window wider than the budget allows is bought by averaging groups of samples, so the rate falls and the status line says so — that is the anti-alias filter doing its job.
  • connected, but no data is arriving appears after three seconds in which no frame arrived while connected: the usual cause is the unicast point above. It clears the moment data returns.
  • N reconnects is appended when the client has had to re-establish the session.

3. Signals

The + badge (or g) opens the Signals page, which lists what can be added: the signals the CONFIG described that are not acquired yet, each with a tick. Signals start disabled — ticking one is what starts acquiring it, and a signal nobody enables costs nothing. Its badge then appears in the badge bar. Drag the badge onto a plot row to add a trace; drag it again to another row to plot the same signal twice, or onto another badge to reorder the badges. The colour is per signal, so the same signal is the same colour wherever it appears.

Clicking a signal's badge opens its own page: the colour, Plot on buttons for the rows, and Calibrate — gain and offset, applied at ingest, so the measurements and the export carry the same numbers the plot shows.

4. The window and navigation

The header's window control (2 s) sets the time span on screen; the popover takes a number and a unit, with a decade stepper either side. The trigger's event window is a share of this span, so a window change moves the trigger with it.

  • Wheel zooms about the pointer; Shift+wheel on x only, Ctrl+wheel y only.
  • Ctrl + / - zooms x, Alt + / - y, about the plot centre.
  • Drag pans, right-drag too (the right button also grabs a cursor at the pointer).
  • Ctrl+drag frames x to a box, Alt+drag y.
  • Fit to data (menu) auto-scales both axes and frames the whole buffered range.

Each plot has its own right-click menu, in the same compact row style as the app's menu: Y axis: auto scale, Y axis: fixed range..., Fit X axis, Fit all (f), and Remove signal — which swaps the menu to one entry per trace on that plot plus All traces on this plot, with a Back row to return. That is how a trace comes off a row without going through the layout editor.

The view is bounded by the time window, not by the buffer: zooming out stops at the span you set, and panning stops where the data starts. When the buffer holds less than the window — right after a signal is enabled — the window is left empty on its left, which is what a scope that has just started should look like.

5. Trigger

a capture held

Single mode with a capture held: the axis is the event's own [-pre, +post], the trigger marker sits at the edge, and the status line reads event held.

The trigger button in the header bar (t) turns trigger mode on. The Trigger badge opens the trigger page, which has the signal, the condition, the edge, the pre/post split (as a share of the event span), Normal or Single, and Arm/Disarm. Selecting a signal for the trigger enables it.

  • While a capture fills the plot keeps drawing live data on the event's clock, so the post side fills in view; the axis does not move.
  • A held event is navigable within its own data — zooming in works, panning stops at the capture's edges — and it is never quietly replaced by live data.
  • Disarming mid-capture publishes what the capture got and holds that, so the picture on screen when you disarm is the picture you keep.
  • The event window is counted in stream seconds end to end, so a source whose clock advances in jumps still gets the window it asked for.
  • Events. With record events on (trigger page), each latch is stored. The dock's Events block lists them newest first and one click replays one; Manage opens the full list as a page, where a click selects, a double click replays, and Compare, Accumulate and Live act on the selection or go back to the stream. The block is dimmed until something is recorded.

6. Pause

Pause freezes the picture, not the acquisition: the producer keeps filling the buffer behind it, and the frozen view is a snapshot of the window that was on screen. Resuming shows the data that arrived meanwhile — there is no hole. A paused view is held like a held event, so zooming in works and panning does not walk it off its snapshot.

7. Cursors

The cursors toggle in the header bar (c) switches on two instruments per row:

  • vertical — two times, shared by every row;
  • horizontal — two rulers per row;
  • both — the two together;
  • mix — the two times, read off each trace where they cross it.

The dock reports each trace's values at the markers; Edit beside Cursors opens the page with the mode and Reset, which puts them back at the window's edges. Values read -- when a marker is past the newest sample and partial when only one marker is over data.

8. Measurements

A measurement is a statistic of the visible window of a signal: average, top, bottom, min, max, peak to peak, amplitude, pulse duration, period and frequency. m, or Edit beside Measurements in the dock, opens the page; its + adds one, a click on a row (in the page or in the dock) edits it, and show on plot draws its result as a ruler (levels) or markers (times). The dock shows each measurement's value.

top and bottom take a split as a share of the window's own range — the percentage travels between signals where a threshold in volts would not. period and frequency deliberately have no split: they count rising crossings of the mid level, one edge per cycle, and a split there is a setting you can only get wrong.

The values are refreshed on a cadence — at most every 100 ms while the window is scrolling, once when it stops, and once per mode change — so a live view cannot cost you frames. The cost is reported in the exit dump with the app's self-check.

9. Math channels

the math channel editor

The compact node editor: each node is a box, its inputs the squares on the left edge and its output the square on the right. The orange dot marks the node that carries the channel's value.

A math channel is derived from the others and is then an ordinary channel: enable it and it is acquired, plotted, measured and exported like a streamed signal, and another math channel can use it as a source. The Signals page lists them under a MATH heading whose + creates one; a math channel's own page has Edit graph and Delete.

Operations: channel (a source), gain + offset, abs, sqrt, clamp, low pass, high pass, band pass (biquads, corner in Hz against the stored rate), sum, difference, product, ratio.

  • Click a node to select it; its parameters appear in the form beside the canvas.
  • Drag from an output square to an input square to wire them. An input is only offered the nodes above it — the graph is a list walked in order, so a cycle cannot be drawn.
  • Drag a box to move it. add node, delete node and set as output are below the form.
  • The output is the last node of a graph you build top to bottom, and the orange dot says which; set as output changes it. A graph whose output is the source is valid and just passes the input through — that is the usual reason an operation "does nothing".
  • Save refuses an incomplete graph and says why: an unconnected input, no output, or a source that is not a channel the scope is acquiring.

The samples are produced at ingest, once per stored slot, so the filters carry real history — a low pass is the filter you asked for rather than a window recomputed every frame.

10. Sessions

Everything above is saved per source in ~/.config/udpscope/<host>_<port>.toml: the window, the rows and which signal each slot holds, the calibration, which signals were enabled, the math channels with their graphs and the measurements. Reopening the same source brings the scope back as you left it.

The file is plain TOML and safe to edit — a malformed line is skipped rather than refusing the whole file. Deleting it starts from the defaults.

11. Export

Export visible range… writes the plotted signals over the visible x range at the stored rate to .npy or .csv, picked by the file name's extension. The table is collected when you click, not when the chooser closes, so a live view cannot scroll under the dialog. The .npy is a 2-D array: one row per sample, time, stream_time, then one column per signal.

12. Keyboard

key action
space pause / resume
a arm / disarm the trigger
t enable / disable trigger mode
c enable / disable the cursors
m open or close the Measurements page
g open or close the Signals page (the + badge opens it too)
l show / hide the layout editor
s show / hide the dock
Esc close the slide-over page (the guided tour takes it first)
f fit to data (the plot's own key)
Ctrl+E export visible range
F1 open the manual
Ctrl+/ open the shortcut overview
Ctrl+T start the guided tour
Ctrl+H turn the contextual help on or off
Ctrl+Q quit

The plot also answers +/- (zoom both axes), Ctrl+plus/Ctrl+minus (zoom x only), Alt+plus/Alt+minus (zoom y only) and the arrow keys (pan). A keystroke is ignored while a text field has focus, so typing in the window control never arms the trigger.

13. Troubleshooting

symptom cause
connected, but no data is arriving another client holds a unicast source — use --multicast
the plot is empty, the status reads no data nothing is enabled: enable a signal in the panel
the trace is blank while the trigger is armed Waiting — armed and nothing latched yet
the axis has a margin at the right a capture is filling: the post side arrives as it is acquired
a math channel equals its input its output node is the source — see §9
a very wide window shows a low rate the ingest's anti-alias filter, not a fault
a level reads -- the measurement is invalid in this window (e.g. a period with one edge)