Skip to content

Concepts

A Typical Sketch Outline

Most sketches follow the same shape:

#include <ViewPoint.h>

void setup() {
    view.begin();
    // Optional configuration here
}

void loop() {
    view.addData("Signal", analogRead(A0));
    view.send();
}

The usual pattern is:

  1. include the library,
  2. call view.begin(...),
  3. optionally configure the plot,
  4. add data in loop(),
  5. call view.send().

A handful of terms recur through the rest of this document and through every example sketch. Each one maps to a single object or enum in the library. The sections below are a brief overview — see the Recipes for in-depth examination with screenshots.

view

view is the global Plotter instance — the single entry point for every sketch. Including <ViewPoint.h> brings it into scope. Sketches call view.begin(), view.addData(...), view.send(), and the rest of the configuration API on this one object.

#include <ViewPoint.h>

void setup() { view.begin(); }
void loop()  { view.addData("A0", analogRead(A0)); view.send(); }

Trace

A trace is a named series of float samples drawn inside a plot. A trace can carry single values (addData("A0", value)) for Cartesian plotting, or paired values (addData("Orbit", x, y)) for Scatter and Polar plotting. Traces are created on first reference by label; numeric ids can also be used. A sketch can stream multiple traces in the same send() cycle.

Plot

A plot is one panel in the plot area (canvas): a pair of axes, the traces drawn inside, an optional title, and optional grid styling. A session starts with one plot. Calling view.setNumberOfPlots(n) adds more. Per-plot configuration is reached through view.plot(i), which returns a Plot& exposing the same axis, title, units, display-mode, and reference-line calls available on view itself. When a sketch defines multiple traces and multiple plots without explicit mapping, the desktop app auto-maps traces to plots in index order — first trace to the top plot, last trace to the bottom plot.

Mode

A sketch streams data in one of two modes.

Mode Behavior Good for
Mode::Continuous each send() appends one point per trace live telemetry, scrolling sensor streams
Mode::Frames each send() replaces the whole frame FFTs, windowed analysis, fixed-size blocks

Continuous mode is the default. Frames mode is selected with view.begin(frames, packetSize) or view.setMode(frames). Frames mode sends a [frames]complete=true marker at the end of each packet, which the desktop app uses to align display modes like Persistence and Spectrogram.

PlotType

A plot type selects how the desktop app renders the data.

Plot type Best for Typical data shape
PlotType::Cartesian time series, sampled values, general telemetry one value per point
PlotType::Scatter phase plots, paired channels, trajectories paired values (x, y)
PlotType::Polar directional, rotational, angular data magnitude plus angle

Cartesian is the default. Scatter and Polar take paired data via addData(label, x, y).

DisplayMode

A display mode is a rendering style layered onto a Cartesian plot in Frames mode. On any other plot type or in Continuous mode, the display mode is ignored.

Display mode What it does
DisplayMode::None normal rendering, no overlay
DisplayMode::Persistence older frames remain visible with alpha blending
DisplayMode::Spectrogram waterfall, time on one axis and frame index on the other
DisplayMode::Gradient per-pixel hit count rendered as a color spectrum

Namespace Shortcut Macros

viewpoint is the library's namespace. Every enum value has a fully qualified form (viewpoint::PlotType::Scatter, viewpoint::Mode::Frames) and a short macro form for the most common values (this is provided for added convenience and approachability):

Macro Expands to
cartesian viewpoint::PlotType::Cartesian
scatter, xy viewpoint::PlotType::Scatter
polar viewpoint::PlotType::Polar
continuous viewpoint::Mode::Continuous
frames viewpoint::Mode::Frames
persistence viewpoint::DisplayMode::Persistence
spectrogram viewpoint::DisplayMode::Spectrogram
gradient viewpoint::DisplayMode::Gradient

The Hello sketches use the macro form. Showcase sketches that pull in several enums commonly write using namespace viewpoint; and use the fully qualified forms instead.

If a macro name collides with another library in the sketch, opt out before the include:

#define USE_VIEWPOINT_WITH_NAMESPACE
#include <ViewPoint.h>

With the opt-out in place, only the fully qualified forms are available.

Legacy Mode

view.setLegacyMode(true) switches the library into a data-only stream suitable for non-ViewPoint receivers — the Arduino IDE Serial Plotter, third-party serial plotters, or headless CSV logging. In legacy mode the library skips the [viewpoint] handshake, omits frame-complete markers, and clamps each send() to 500 points so the Arduino Serial Plotter parser stays in sync.

void setup() {
    view.begin();
    view.setLegacyMode(true);
}

Without legacy mode, the library waits for the desktop app to announce its protocol version before emitting any configuration commands. Until that handshake completes, only data lines are sent — so the Arduino Serial Plotter still sees a clean CSV stream by default. Legacy mode is the right switch when the sketch is targeting Serial Plotter deliberately and wants to opt out of waiting on the handshake entirely.