Dual Monitor Side-by-Side View
Relevant source files
The following files were used as context for generating this wiki page:
The Dual Monitor Side-by-Side View is a feature in ComChan that allows users to monitor two serial ports simultaneously within a single split-pane Terminal User Interface (TUI). This system is designed for debugging communication bridges, such as UART/CAN bridges, or inter-microcontroller communication where observing two data streams in real-time is critical.
Sources: README.md:143-146, src/dual_ports.rs:204-210
The feature provides independent pane auto-scrolling, a unified help modal, and integrated transmission (TX) capabilities for both ports. It automatically handles the segregation of logs and CSV data into separate files to prevent data mixing between the two monitored channels.
Sources: README.md:152-156, src/dual_ports.rs:164-180
System Architecture
The dual monitor system operates using a multi-threaded architecture. The main thread manages the TUI rendering and user input, while two dedicated background threads handle the asynchronous reading and writing for each serial port.
Component Interaction
The following diagram illustrates the relationship between the UI thread and the serial port worker threads.
The system uses std::sync::mpsc channels for communication. The main thread receives DualEvent variants from the workers and sends command strings via command channels.
Sources: src/dual_ports.rs:33-41, src/dual_ports.rs:77-85, src/dual_ports.rs:188-202
Data Structures and State Management
The core state is managed by the DualMonitorState struct, which tracks logs, scroll positions, and UI modes for both panes.
| Field | Type | Description |
|---|---|---|
port1_logs / port2_logs | Vec<String> | Buffered line-oriented data for each port. |
scroll1 / scroll2 | usize | Current vertical scroll offset for each pane. |
active_pane | u8 | Tracks which pane (0 or 1) has focus for input/scrolling. |
auto_scroll1 / auto_scroll2 | bool | Toggle for automatic snapping to the latest data. |
input_mode | bool | Determines if keypresses are routed to the command buffer. |
input1 / input2 | String | Buffers for pending TX commands. |
Sources: src/dual_ports.rs:43-55
Event Processing
Data from serial ports is processed through the DualEvent enum:
pub enum DualEvent {
Port1(String),
Port2(String),
Error1(String),
Error2(String),
}
Sources: src/dual_ports.rs:36-41
Execution Logic
The entry point for this mode is run_dual_mode, which is triggered by the main application loop when exactly two ports are provided in the configuration and specialized modes (like RTT or BLE) are not active.
Sources: src/main.rs:103-112, src/dual_ports.rs:159-163
Thread Lifecycle
- Initialization: The system splits the user-provided log and CSV paths into port-specific filenames (e.g.,
log_port1.txt). - Spawning:
spawn_serial_threadis called for both ports. - Communication Loop: The serial thread continuously:
- Drains the command receiver (
rx_cmd) to write data to the hardware. - Reads available bytes into a 1024-byte buffer.
- Sends raw data or errors back to the main thread via the
txchannel.
- Drains the command receiver (
- UI Updates: The main thread processes these events, performs line-buffering, updates the
DualMonitorState, and triggers a TUI redraw.
Sources: src/dual_ports.rs:77-157, src/dual_ports.rs:223-261
Sequence of Data Flow
The sequence diagram below shows how a command is sent from the UI to the hardware and how response data returns.
TUI Layout and Controls
The interface is rendered using ratatui with a horizontal split. Each side contains a scrollable paragraph for logs and a smaller text area for command input.
Keyboard Shortcuts
| Key | Action |
|---|---|
Tab / Left / Right | Switch active focus between Port 1 and Port 2. |
Up / Down | Scroll through history in the active pane (disables auto-scroll). |
Enter | Snap active pane to the bottom and resume auto-scroll. |
i | Enter typing mode for sending data (TX). |
Esc | Exit typing mode back to navigation mode. |
? | Open the help modal. |
Sources: src/dual_ports.rs:327-366, src/dual_ports.rs:509-523
Memory and Logging Management
To prevent RAM exhaustion during long-running sessions, the DualMonitorState implements a trimming mechanism. When a port's log buffer exceeds 2,000 lines, the system automatically drains the oldest 500 lines.
Sources: src/dual_ports.rs:264-271
Logging and CSV streaming are handled by specialized splitting logic in split_filename, which appends _port1 and _port2 suffixes to the base paths defined in the MergedConfig.
Sources: src/dual_ports.rs:64-75, src/dual_ports.rs:168-180
Conclusion
The Dual Monitor Side-by-Side View provides a robust environment for simultaneous multi-port analysis. By decoupling the hardware I/O into background threads and maintaining independent state for each pane, ComChan ensures a responsive UI even when handling high-throughput serial data on two channels at once.
Sources: README.md:143-156, src/dual_ports.rs:77-85