doc/help/Project-Editor.md
The Project Editor lets you create and edit JSON project files that define how Serial Studio interprets incoming data and displays it on the dashboard. Open it from the toolbar (wrench icon) or with Ctrl+Shift+P (Cmd+Shift+P on macOS).
A project file describes three things: the structure of your data (groups and datasets), how to detect and parse frames from the wire, and what actions (commands) the user can send back to the device. Serial Studio reads this file at connect time and builds the dashboard accordingly.
The following diagram shows the tree structure of a Serial Studio project file and how each element maps to the dashboard.
flowchart TD
Root["Project Root"]
Root --> Groups
Root --> Actions
Root --> Sources["Sources · Pro"]
Groups --> G["Groups → Datasets"]
Actions --> A["Actions → Buttons"]
Sources --> S["Sources → Connections"]
Each value in the incoming data frame is assigned a 1-based frame index that you reference when configuring datasets. The mapping works as follows:
flowchart LR
A["23.5, 1013, 45.2"] --> B["parse()"]
B --> C["[0]→IDX 1
[1]→IDX 2
[2]→IDX 3"]
The editor window is divided into three areas: a toolbar across the top, a tree view on the left, and a property panel on the right.
.json or .ssproj file.Shows the hierarchical structure of your project:
Project Root
Groups
Group: "Sensors"
Dataset: "Temperature" [IDX 1]
Dataset: "Humidity" [IDX 2]
Dataset: "Pressure" [IDX 3]
Group: "Status"
Dataset: "Battery" [IDX 4]
Actions
Action: "Reset Device"
Sources
Source: "Main Device"
The number in brackets is the dataset's frame index — its position in the parsed data array. Click any item to edit its properties in the right panel.
Displays a form for the selected tree item. Every change takes effect immediately in the project model. The form fields vary depending on whether you have selected the project root, a group, a dataset, an action, or a source.
When the project root is selected, the property panel shows frame detection settings. These apply globally in single-source projects, or per-source in multi-source projects.
\n). This is the most common choice./* and */).0A for newline).Groups organize related datasets and determine which group-level widget is used on the dashboard.
| Widget | Description | Dataset Requirements |
|---|---|---|
| Data Grid | Tabular view of all values | Any number |
| Multiple Plot | Overlaid time-series curves | One or more |
| Accelerometer | 3D acceleration visualization | Exactly 3 (X, Y, Z) |
| Gyroscope | 3D orientation visualization | Exactly 3 (X, Y, Z) |
| GPS Map | Geographic tracking on a map | 2--3 (lat, lon, optional alt) |
| 3D Plot (Pro) | 3D scatter/trajectory | Exactly 3 (X, Y, Z) |
| Image View (Pro) | Binary image stream | None (image data in frame) |
| None | No group widget; datasets shown individually | Any number |
Datasets map to individual data fields in your device's output.
General
23.5,1013,45.2, then Temperature = 1, Pressure = 2, Humidity = 3.Plotting
FFT (Frequency Analysis)
LED
Alarm
Widget Range
Actions place buttons on the dashboard that send commands to the connected device.
RST).\n, \r, \r\n, or nothing.| Mode | Behavior |
|---|---|
| Off | Manual click only (default). |
| AutoStart | Timer starts automatically on connect; command repeats at the configured interval. |
| StartOnTrigger | Timer starts on first click; command repeats until stopped. |
| ToggleOnTrigger | Each click toggles the repeating timer on or off. |
Sources define where data comes from. Single-device projects have one implicit source; multi-device projects use explicit sources.
Each source has its own Frame Parser tab for a per-source JavaScript parser.
For data that is not plain CSV, write a JavaScript parse() function to transform each frame into an array of values.
function parse(frame) {
// 'frame' is a string (PlainText/Hex/Base64) or byte array (Binary Direct).
// Return an array of values matching dataset frame indices.
return frame.split(",");
}
Rules:
parse and accept exactly one argument.parse() persist between calls — useful for stateful protocols.console.log() to print debug messages to the Serial Studio terminal.Example — binary protocol:
function parse(frame) {
// frame is a byte array in Binary Direct mode
var temp = (frame[0] << 8) | frame[1];
var humidity = (frame[2] << 8) | frame[3];
return [temp / 10.0, humidity / 10.0];
}
Your device sends a sequence of values. The frame parser (or the default comma splitter) produces an array. Each dataset's Frame Index tells Serial Studio which array position to read:
Device sends: 23.5,1013,45.2
Parser returns: ["23.5", "1013", "45.2"]
^ ^ ^
Index 1 Index 2 Index 3
When a project has multiple sources, each source represents a separate physical device with its own connection, bus type, frame detection, and JS parser.
.json file.Symptom: Widget shows "0", wrong data, or no data.
Fix: Verify that each dataset's frame index matches the correct position in the parser's return array. Index 1 = first element, index 2 = second element, and so on.
Symptom: Console shows "undefined" or parsing errors.
Fix:
console.log() calls to inspect the raw frame and parsed output.Symptom: Frames not detected, or data garbled.
Fix:
\r or \0.\n (most serial devices), \r\n (Windows-style), or custom markers like /* and */.Symptom: Widget appears but displays incorrectly.
Fix:
Symptom: Group widget does not appear on the dashboard.
Fix: Ensure the group has the required number of datasets for its widget type. See the table in Step 3 above.