Skip to content

Project Editor

Alex Spataru edited this page Dec 28, 2025 · 25 revisions

The Project Editor in Serial Studio allows you to create and customize JSON Project Files that define your dashboard's layout and data mapping. It provides a graphical interface to easily manage groups, datasets, actions, and frame parsing logic.

Overview of the Project Editor Interface

The Project Editor consists of the following key elements:

  1. Tree View: Displays the structure of your project, including groups, datasets, and actions. Clicking on an item will bring up its specific view in the right panel.
  2. Toolbar: Provides buttons to create a new project, open an existing project, save your project, and add various widgets and components to the project.
  3. Detail Views: The main area where the details of the selected tree item are displayed and configured. Depending on the selection in the tree view, different views will be shown (e.g., project view, group view, dataset view, action view, or frame parser function).
Project Editor Sections

Toolbar Options

The Toolbar in the Project Editor allows you to quickly add new components to your project:

  • New: Start a new project from scratch.
  • Open: Open an existing JSON Project File.
  • Save: Save the current project to a JSON file.
  • Add Action: Add a button to the dashboard that sends specific data to the device when clicked.
  • Add Data Grid: Add a data grid widget to the dashboard (used for displaying datasets in a table format).
  • Add Multiple Plots: Add a group with multiple plots for visualizing datasets.
  • Add Accelerometer: Add an accelerometer widget to the dashboard for displaying X, Y, Z axis data.
  • Add Gyroscope: Add a gyroscope widget to the dashboard for displaying rotational data.
  • Add Map: Add a map widget for GPS-based datasets (latitude, longitude, altitude).
  • Add Container: Add a container group to organize datasets without displaying a specific widget.

Tree View

The Tree View on the left side of the Project Editor shows the hierarchical structure of your project. It consists of:

  • The Project Root (which represents the entire dashboard project).
  • Groups: These are collections of datasets that will be displayed together in a widget.
  • Datasets: Individual data values within a group that are mapped to incoming sensor data. Each dataset item in the tree view also displays an [IDX n] label to the right, where n is the index of the dataset value, starting from 1.
  • Actions: Buttons that trigger specific commands when clicked by the user.

Clicking on any of these items will load the corresponding view in the main panel, where you can configure its parameters.

Views in the Project Editor

Clicking on an item in the Tree View opens a specific view in the detail panel. These views allow you to configure different aspects of your project.

Project View (when the root item is selected)

The Project View allows you to set general properties of the project, such as:

  • Project Title: A name for the project.
  • Frame Detection: Define the frame detection method to use, includes Start + End Delimiter, End Delimiter Only and No Delimiters.
    • End Delimiter Only: Ideal for scenarios where only an end delimiter (e.g., \n) is needed to process frames.
    • Start & End Delimiter: Useful for projects that require both delimiters for more precise frame handling.
    • No Delimiters: Handle data as-it-comes and feed it directly to the frame parser function. Ideal for custom communication protocols.
  • Frame Delimiters: If applicable, define the start delimiter and end delimiter to identify and separate frames of data received from the device.
  • Conversion Method: Choose how the data inside the frame delimiters should be processed. The available methods are:
    • Normal (UTF8): Default text-based data processing.
    • Hexadecimal: This option is useful if your device sends binary data in hex format. Combined with a custom frame parser function, this can allow you to interpret and display binary data on the dashboard.
    • Base64: Use this method to encode incoming data in Base64 before passing it to the frame parser function.
  • Thunderforest API Key: Optional key for using Thunderforest map services in your project.
  • MapTiler API Key: Optional key for using MapTiler map services in your project.

These options give you control over how the incoming data is handled, allowing you to customize your setup for more complex requirements such as binary data processing (example), key/value frames (example) and interacting with external map services.

Project View

Group View (when a group is selected)

When you select a group in the Tree View, the Group View is displayed, allowing you to:

  • Title: Set the title for the group.
  • Widget: Choose the widget that will represent this group (e.g., multiple plots, accelerometer, data grid, etc.).

A secondary toolbar is available when viewing a group. This toolbar allows you to add datasets to the group, duplicate the group or delete it.

Group View

Dataset View (when a dataset is selected)

When you select a dataset in the Tree View, the Dataset View is displayed, allowing you to configure individual datasets:

  • Title: The label that will be displayed for this dataset.
  • Units: The measurement units for the dataset (e.g., °C, %, etc.).
  • Index: The position of the dataset in the incoming frame (this value tells the software which part of the data frame maps to this dataset).
  • Min/Max Values: Set the range for widgets like gauges and bars.
  • Widget Type: Choose how this dataset will be visualized (e.g., plot, gauge, bar).

A secondary toolbar is available in the Dataset View to toggle dataset parameters. Here, you can configure the plotting options & easily set the widget used to display the dataset. As with the group view, you can also duplicate the dataset and/or delete it.

Dataset View

Frame Parser Function View

The Frame Parser Function View allows you to customize how incoming data frames are parsed. This view contains a JavaScript editor where you can write or modify the function that processes the incoming data based on your project’s needs.

Reminder: How Frames Are Parsed

Frames are parsed according to the frame detection method, start delimiter and end delimiter that are configured in the project settings (in the Project View). The input passed to the frame parser function is only the data contained inside the frame, and the function is charge of transforming the frame data into an array that can later populate the values for each dataset in your project.

You can read more about this in the Data Flow in Serial Studio page.

Example Frame

$1023,512,850,300,45;

In this example:

  • Start Delimiter: $
  • End Delimiter: ;

The data inside the delimiters is: 1023,512,850,300,45.

This string (1023,512,850,300,45) will be passed to the frame parser function and split using the comma as a separator, resulting in the following array:

["1023", "512", "850", "300", "45"]

The frame parser function will return this array to Serial Studio, which later uses it to update the dashboard model.

Using Global Variables

You can declare global variables outside the frame parser function, allowing them to persist between function calls. This is useful for maintaining state or configuration across multiple frames. By using global variables, you can customize the behavior of the frame parser for more complex projects, such as when you need to handle multiple frame types or formats within a single project.

Default Frame Parser Function:

function parse(frame) {
    return frame.split(',');
}

This default parser simply splits the incoming data frame into individual elements using a comma (,) as a separator. However, you can modify this function to handle more advanced parsing needs, such as binary data processing, custom frame formats, or pre-processing the incoming data.

Frame Parser

⚠️ Remember to click on the Apply button to save your changes in the frame parser code!

⚠️ The function template must always be parse(frame), changing the function name or adding/removing arguments will result in a runtime error.

Debugging the Frame Parser

To help debug your Frame Parser Function, you can use the console.log() function to print messages to the terminal. This allows you to monitor the execution of your parser function and inspect the values of variables or the structure of the data being processed. Debugging with console.log() is especially useful when customizing the frame parser for more complex data formats.

Example: Using console.log() for Debugging

function parse(frame) {
    // Log the received frame and separator to the terminal
    console.log("Received frame: " + frame);
    console.log("Using separator: " + ',');

    // Split the frame based on the separator and log the result
    let parsedValues = frame.split(',');
    console.log("Parsed values: " + JSON.stringify(parsedValues));

    // Return the parsed values
    return parsedValues;
}

In this example:

  • The console.log() function prints the raw frame data, the separator being used, and the parsed values as an array.
  • This helps you debug the function by observing the data flow and ensuring that the function behaves as expected.

Action View (when an action is selected)

The Action View is where you configure actions, which are buttons displayed on the dashboard. These buttons can be used to send specific commands or data to your device when clicked by the user. Each action is fully customizable, from its label and icon to the data it sends.

Action View Configuration

  • Title: The label displayed on the button.
  • Icon: The icon that will be displayed on the button.
  • Data to Send: The specific data or command that will be sent to the device when the button is clicked.
  • EOL Character: The End-of-Line (EOL) character appended to the data. This can be useful for commands that require a specific ending (e.g., newline \n, carriage return \r, etc.).

Example Action Configuration

Imagine you have an embedded system where sending the string RESET\n to the device will trigger a device reboot. You could create an action button for this:

  • Title: Reset Device
  • Icon: (choose any icon representing a reset action)
  • Data to Send: RESET
  • EOL Character: \n (newline)

When this action button is clicked on the dashboard, it sends the command RESET\n to the device.

Action View

Saving and Exporting Your Project

Once you have finished setting up your project:

  • Click Save on the toolbar to save the project to a JSON file.
  • This file can then be loaded by Serial Studio to visualize data according to your project's configuration.

Step-by-Step Tutorial: Visualizing Arduino Sensor Data

In this tutorial, we will walk you through how to use Serial Studio to visualize analog sensor data from an Arduino using the Project Editor and a custom frame parser.

Requirements

  • Arduino (with at least 6 analog input ports, e.g., Arduino Uno)
  • Serial Studio
  • USB cable to connect the Arduino to your computer

Step 1: Upload the Arduino Code

First, upload the following code to your Arduino. This sketch reads values from the six analog pins (A0 to A5) and sends the values as a comma-separated string over serial, wrapped with start and end delimiters.

Arduino Code:

void setup() {
  // Initialize serial communication at 115200 baud
  Serial.begin(115200);
}

void loop() {
  // Read analog values from all ADC ports (A0 to A5 on most Arduinos)
  int sensorValue1 = analogRead(A0);
  int sensorValue2 = analogRead(A1);
  int sensorValue3 = analogRead(A2);
  int sensorValue4 = analogRead(A3);
  int sensorValue5 = analogRead(A4);
  int sensorValue6 = analogRead(A5);

  // Send start delimiter
  Serial.print("/*");

  // Send the values as a comma-separated string
  Serial.print(sensorValue1);
  Serial.print(",");
  Serial.print(sensorValue2);
  Serial.print(",");
  Serial.print(sensorValue3);
  Serial.print(",");
  Serial.print(sensorValue4);
  Serial.print(",");
  Serial.print(sensorValue5);
  Serial.print(",");
  Serial.print(sensorValue6);

  // Send end delimiter
  Serial.print("*/");
  Serial.print("\n");

  // Small delay between readings
  delay(1);
}

Step 2: Open Serial Studio

  1. Download and install Serial Studio (if you haven’t already) from the releases page.
  2. Connect your Arduino to your computer via USB.
  3. Open Serial Studio.

Step 3: Create a New Project

  1. In Serial Studio, open the Project Editor by clicking on the Project Editor button in the toolbar.
  2. Click New to create a new project.
  3. Set a Project Title (e.g., "Arduino Sensor Data").
  4. Set the Frame Detection to Start + End Delimiters.
  5. Configure the Frame Delimiters:
    • Start Delimiter: /*
    • End Delimiter: */

Step 4: Add Datasets

  1. Add a new Group by clicking the Add Multiple Plots button in the toolbar.
  2. For each analog input (A0 to A5), add a dataset:
    • Click the Add Dataset button in the Group View.
    • Set the Title to something descriptive (e.g., "Sensor 1", "Sensor 2", etc.).
    • Set the Index value:
      • A0 -> Index 1
      • A1 -> Index 2
      • A2 -> Index 3
      • A3 -> Index 4
      • A4 -> Index 5
      • A5 -> Index 6
    • Choose the plot type (e.g., FFT Plot).
Example

Step 5: Frame Parser Function (Optional)

If you want to customize the frame parser function, go to the Frame Parser Function View. By default, the function will split the data using the comma character (,) as a separator, but you can add custom logic if needed.

Here’s the default function:

/**
 * Splits a data frame into an array of elements using a comma separator.
 *
 * Use this function to break a string (like "value1,value2,value3") into
 * individual pieces, which can then be displayed or processed in your project.
 *
 * @param[in]  frame   A string containing the data frame.
 *                     Example: "value1,value2,value3"
 * @return     An array of strings with the split elements.
 *             Example: ["value1", "value2", "value3"]
 *
 * @note You can declare global variables outside this function if needed
 *       for storing settings or keeping state between calls.
 */
function parse(frame) {
    return frame.split(',');
}

Step 6: Connect to the Arduino

  1. Go back to the Setup Panel in Serial Studio.
  2. Select the Serial input method.
  3. Choose the correct serial port (the one your Arduino is connected to).
  4. Set the baud rate to 115200 (to match the baud rate in the Arduino code).
  5. Click Connect.

Step 7: Visualize the Data

Once connected, the data will start streaming in real time, and the dashboard will display the sensor readings for each analog input. You should see the values changing as you adjust the inputs (e.g., by connecting different sensors or adjusting the input voltage).

Example Dashboard

Summary of Steps:

  1. Upload the provided Arduino code to your board.
  2. Open Serial Studio and create a new project.
  3. Set the frame delimiters and separator.
  4. Add datasets for each analog input (A0 to A5).
  5. Optionally, customize the frame parser function.
  6. Connect to your Arduino and start visualizing the sensor data.

This tutorial gives you a simple way to visualize real-time data from your Arduino using Serial Studio. You can expand on this by adding more sensors or customizing the dashboard further.


Widget Selection Guide

Choosing the right widget for your data is important for effective visualization. Here's a quick reference:

For continuous values changing over time:

  • Plot - Line graph showing trends over time
  • Multiple Plots (group widget) - Compare multiple values on same timeline

For bounded values (0-100%, 0-255, etc.):

  • Bar - Horizontal progress bar
  • Gauge - Circular speedometer-style display
  • Level - Vertical thermometer-style display

For position/orientation data:

  • GPS Map (group) - Latitude/longitude on interactive map (requires 2-3 datasets: lat, lon, optional alt)
  • Accelerometer (group) - 3D visualization of X, Y, Z acceleration (requires exactly 3 datasets)
  • Gyroscope (group) - 3D visualization of rotation rates (requires exactly 3 datasets)
  • Compass - Heading/bearing display (0-360°)

For frequency analysis:

  • FFT Plot - Frequency spectrum (automatically performs FFT on incoming data)

For status indicators:

  • LED Panel (group) - Color-coded status lights for multiple binary/status values
  • Data Grid (group) - Table showing all values with titles and units

For advanced visualization (Pro):

  • 3D Plot - X, Y, Z coordinates in 3D space (requires exactly 3 datasets)
  • XY Plot - Y vs X correlation/phase diagrams (requires exactly 2 datasets)

Need more details? See the complete Widget Reference for requirements, examples, and use cases for all widgets.


Common Mistakes and How to Fix Them

Dataset Index Mismatch

Problem: Widget shows "0" or wrong data

Cause: Dataset indices don't match the parser function's return array positions

Solution:

  • Dataset with index 1 = array position 0
  • Dataset with index 2 = array position 1
  • etc.

Example:

function parse(frame) {
    return ["temp", "humidity", "pressure"];
    //      index 1   index 2     index 3
}

Frame Parser Errors

Problem: Console shows "undefined" or parsing errors

Cause: JavaScript syntax errors or incorrect return value

Solution:

  1. Check console for error messages (red text)
  2. Add console.log() to debug:
function parse(frame) {
    console.log("Input:", frame);
    let result = frame.split(',');
    console.log("Output:", result);
    return result;
}
  1. Ensure you always return an array (not string, object, or undefined)

Delimiter Issues

Problem: Frames not being detected or split incorrectly

Cause: Delimiters don't match what device actually sends

Solution:

  1. Check raw console output to see actual delimiters
  2. Common delimiters:
    • \n (newline) - Most common
    • \r\n (Windows line ending)
    • Custom characters (e.g., $ for start, # for end)
  3. Use hex view in console to see hidden characters

Wrong Widget for Data Type

Problem: Widget doesn't display data properly

Cause: Widget type doesn't match data characteristics

Solution:

  • Don't use Gauge for text data
  • Don't use Bar for unbounded values
  • Don't use Accelerometer unless you have exactly 3 datasets (X, Y, Z)
  • See Widget Selection Guide above

Missing Datasets for Group Widgets

Problem: Group widget shows error or doesn't appear

Cause: Widget requires specific number of datasets

Solution:

  • GPS Map: Needs 2-3 datasets (lat, lon, optional alt)
  • Accelerometer/Gyroscope: Need exactly 3 datasets (X, Y, Z)
  • 3D Plot (Pro): Needs exactly 3 datasets (X, Y, Z)
  • XY Plot (Pro): Needs exactly 2 datasets (X, Y)

OpenGL Issues (3D Widgets)

Problem: 3D widgets don't work or show errors

Cause: Graphics card doesn't support OpenGL or drivers are outdated

Solution:

  1. Update graphics drivers
  2. Check if running in virtual machine (VMs often don't support OpenGL)
  3. Use 2D widget alternatives if OpenGL not available

Advanced Tips

Use Meaningful Names

✅ Good: "Temperature (°C)", "Battery Voltage (V)", "Motor RPM"
❌ Bad: "Dataset 1", "Value", "Data"

Set Appropriate Min/Max for Gauges and Bars

// If temperature range is 0-50°C
Min: 0
Max: 50
// Don't leave auto-scale - it wastes the gauge's range

Test with CSV Player

  1. Record a session with real data
  2. Export to CSV
  3. Use CSV Player to test your project without hardware connected
  4. Iterate on your dashboard design

Comment Your Parser Code

// Parse custom binary protocol
// Format: [temp_high, temp_low, hum_high, hum_low]
function parse(frame) {
    let temp = (frame[0] << 8) | frame[1];  // Combine bytes
    let humidity = (frame[2] << 8) | frame[3];
    return [temp / 10.0, humidity / 10.0];  // Convert to actual values
}

See Also


Need help? Check the Troubleshooting Guide or ask on GitHub Discussions!

Clone this wiki locally