Serial Studio is a multi-protocol telemetry dashboard application that receives data from embedded devices and visualizes it in real time. This page provides an introduction to the application's architecture, major subsystems, and data flow patterns.
For detailed information about specific subsystems, see:
Serial Studio is a cross-platform Qt 6/C++20 application that connects to embedded devices via multiple transport protocols and displays incoming data using customizable dashboard widgets. It is designed for hardware engineers, robotics teams, IoT developers, and researchers who need to visualize sensor data, debug firmware, or monitor telemetry without writing custom visualization code.
Key characteristics:
Sources: README.md1-91 CMakeLists.txt39-187
The following diagram shows the major subsystems and their dependencies using actual class names from the codebase.
Sources: app/src/Misc/ModuleManager.cpp308-480 app/src/IO/Manager.h1-300 app/src/DataModel/FrameBuilder.h1-200 app/src/UI/Dashboard.h1-150
This diagram shows the hot path for incoming data, from hardware driver to widget display, with actual signal/slot names and method calls.
Critical performance invariant: The dashboard path (UI::Dashboard::frameReceived) receives a const DataModel::Frame& reference with zero allocations. Only export workers allocate memory by creating std::shared_ptr<TimestampedFrame> for thread-safe queueing.
Sources: app/src/IO/Manager.cpp400-600 app/src/IO/FrameReader.cpp100-300 app/src/DataModel/FrameBuilder.cpp700-900 app/src/UI/Dashboard.cpp200-400
Serial Studio supports three distinct operational modes that determine how incoming data is interpreted and parsed.
| Mode | Enum Value | Frame Delimiters | Parsing | Typical Use Case |
|---|---|---|---|---|
| Project File | SerialStudio::OperationMode::ProjectFile (0) | Configurable via frameStart, frameEnd, frameDetection in JSON | JavaScript frameParser function | Binary protocols, custom checksums, structured data |
| Device Sends JSON | SerialStudio::OperationMode::DeviceSendsJSON (1) | Fixed: /* start, */ end | Native JSON parser | Devices that output JSON telemetry |
| Quick Plot | SerialStudio::OperationMode::QuickPlot (2) | Line-based (CR/LF/CRLF) | Comma-separated values | Arduino Serial.print() debugging |
The operation mode is selected in DataModel and affects frame extraction logic in IO and parsing dispatch in DataModel
Sources: app/src/SerialStudio.h50-100 app/src/DataModel/ProjectModel.cpp200-400 app/src/DataModel/FrameBuilder.cpp100-300
Serial Studio uses a dual-licensing model with conditional compilation to separate open-source (GPL-3.0) and commercial (Pro) features.
License validation: Commercial builds require SERIAL_STUDIO_LICENSE_KEY and SERIAL_STUDIO_INSTANCE_ID environment variables at configure time. CMake validates the license against the Lemon Squeezy API before allowing the build to proceed.
Sources: CMakeLists.txt76-294 app/CMakeLists.txt99-143 app/CMakeLists.txt404-479
Pro-only modules are conditionally compiled using preprocessor guards:
This pattern appears throughout app/src/Misc/ModuleManager.cpp310-480 and in driver registration code.
Sources: app/src/Misc/ModuleManager.cpp310-480 app/CMakeLists.txt404-479
Serial Studio runs on Windows, macOS, and Linux with architecture-specific builds:
| Platform | Architectures | Build Output | Package Format |
|---|---|---|---|
| Windows | x86_64 | Serial-Studio-Pro.exe or Serial-Studio-GPL3.exe | MSI installer, portable ZIP |
| macOS | Universal (arm64 + x86_64) | Serial Studio Pro.app or Serial Studio GPLv3.app | Notarized DMG |
| Linux | x86_64, aarch64 | serial-studio-pro or serial-studio-gpl3 | AppImage, Flatpak |
The build system uses GitHub Actions for CI/CD with parallel jobs for each platform. Final artifacts are uploaded to the continuous release tag.
Sources: .github/workflows/deploy.yml1-728 CMakeLists.txt158-187 app/deploy/linux/serial-studio-pro.desktop1-11 app/deploy/macOS/info-pro.plist1-67
Serial Studio uses singleton instances for major subsystems. These are initialized in Misc and exposed to QML as context properties:
| C++ Class | QML Context Property | Purpose |
|---|---|---|
IO::Manager | Cpp_IO_Manager | Connection orchestrator, driver lifecycle |
DataModel::FrameBuilder | Cpp_JSON_FrameBuilder | Frame parsing dispatcher |
DataModel::ProjectModel | Cpp_JSON_ProjectModel | Configuration and project file management |
UI::Dashboard | Cpp_UI_Dashboard | Widget registry and dashboard state |
Console::Handler | Cpp_Console_Handler | Console backend, command history, echo |
API::Server | Cpp_API_Server | TCP API server on port 7777 |
CSV::Export | Cpp_CSV_Export | Background CSV export worker |
Misc::ThemeManager | Cpp_ThemeManager | Color palette and theme switching |
Misc::Translator | Cpp_Misc_Translator | i18n and language switching |
QML files access these via Cpp_* properties, e.g., Cpp_IO_Manager.isConnected or Cpp_UI_Dashboard.frameReceived.
Sources: app/src/Misc/ModuleManager.cpp308-480 app/qml/MainWindow/MainWindow.qml1-100
The console subsystem consists of two main components:
The Console::Handler emits displayString(QString) signals that the Widgets::Terminal receives via the append(QString) slot. The terminal widget performs actual VT-100 processing (cursor movement, erase sequences, color codes) when vt100Emulation is enabled.
Important: VT-100 emulation is automatically disabled if the project contains an image widget (Pro feature) to prevent conflicts with image data escape sequences.
Sources: app/src/Console/Handler.cpp1-500 app/src/UI/Widgets/Terminal.cpp1-1708 app/qml/Widgets/Dashboard/Terminal.qml1-450
This overview provides entry points into the codebase. For deeper understanding:
IO::HAL_Driver interface and specific driver implementationsDataModel::FrameBuilder operation modes and JavaScript integration