Skip to main content

Python library for Siglent oscilloscope control and automation via SCPI over Ethernet/LAN - supports SDS800XHD, SDS1000X-E, SDS2000X Plus, SDS5000X series. Features programmatic API for waveform capture, measurements, trigger control, and PyQt6 GUI with real-time visualization, FFT analysis, protocol decoding (I2C/SPI/UART), and automated data collection

Project description

Siglent Oscilloscope Control

CI codecov PyPI version PyPI Downloads Python Version License: MIT Code style: black GitHub issues GitHub stars GitHub last commit Buy Me A Coffee

A professional Python package for controlling Siglent oscilloscopes via Ethernet/LAN. Features both a comprehensive programmatic API and a high-performance PyQt6-based GUI application with real-time visualization.

Features

Core Features

  • Programmatic API: Control your oscilloscope from Python scripts
  • Automation & Data Collection: High-level API for batch capture, continuous monitoring, and analysis
  • GUI Application: Modern PyQt6-based graphical interface
  • Waveform Acquisition: Capture and download waveform data in multiple formats (NPZ, CSV, MAT, HDF5)
  • Channel Configuration: Control voltage scale, coupling, offset, bandwidth
  • Trigger Settings: Configure trigger modes, levels, edge detection
  • Advanced Analysis: Built-in FFT, SNR, THD, and statistical analysis tools

GUI Features (New!)

  • High-Performance Live View: Real-time waveform display at 1000+ fps using PyQtGraph
  • Interactive Visual Measurements: Click-and-drag measurement markers directly on waveforms
    • 15+ measurement types: Frequency, Vpp, Rise Time, Duty Cycle, etc.
    • Visual gates and markers with real-time calculation
    • Save/load measurement configurations
    • Export results to CSV/JSON
  • Non-Blocking Updates: Threaded data acquisition keeps GUI responsive
  • Reference Waveforms: Save, overlay, and compare waveforms
  • Protocol Decoding: I2C, SPI, UART, CAN, LIN support
  • Math Functions: Custom math expressions on waveforms
  • VNC Display: Embedded oscilloscope screen viewer

Vector Graphics / XY Mode (Fun! 🎨)

Use your oscilloscope as a vector display by generating waveforms for XY mode:

  • Draw Shapes: Circles, rectangles, stars, polygons, Lissajous figures
  • Text Rendering: Display text messages on your oscilloscope screen
  • Animations: Create rotating and transforming graphics
  • Composite Paths: Combine multiple shapes into complex drawings

Requirements: External AWG/DAC or scope's built-in AWG to feed generated waveforms into scope channels.

# Install the fun extras
# pip install "Siglent-Oscilloscope[fun]"

from siglent import Oscilloscope
from siglent.vector_graphics import Shape

scope = Oscilloscope('192.168.1.100')
scope.connect()

# Enable XY mode (CH1=X, CH2=Y)
scope.vector_display.enable_xy_mode()

# Generate waveforms for a circle
circle = Shape.circle(radius=0.8, points=1000)
x_wave, y_wave = scope.vector_display.draw(circle)

# Save for AWG upload
scope.vector_display.save_waveforms(circle, "my_circle", format='csv')
# Load my_circle_x.csv and my_circle_y.csv into your AWG!

See examples/vector_graphics_xy_mode.py for more demos including animations and text!

Installation

From PyPI (recommended)

pip install Siglent-Oscilloscope

To include optional features, use extras:

# GUI application with PyQt6
pip install "Siglent-Oscilloscope[gui]"

# Vector graphics and XY mode (draw shapes on scope!)
pip install "Siglent-Oscilloscope[fun]"

# Everything
pip install "Siglent-Oscilloscope[all]"

Note: The siglent-gui command includes automatic dependency checking. If you try to run the GUI without the required packages, you'll receive a clear error message with installation instructions. Missing optional dependencies (like PyQtGraph for high-performance live view) will trigger warnings but allow the GUI to launch.

From source

git clone git@github.com:little-did-I-know/Siglent-Oscilloscope.git
cd siglent
pip install -e .

Install with GUI support from source:

pip install -e ".[gui]"

Development installation

pip install -e ".[dev]"

Build & Publish (PyPI)

To create release artifacts that render correctly on PyPI:

python -m build
twine check dist/*

The twine check command validates the built distributions, including the long description rendered from README.md, before upload.

Quick Start

Programmatic Usage

from siglent import Oscilloscope

# Connect to oscilloscope
scope = Oscilloscope('192.168.1.100')
scope.connect()

# Get device information
print(scope.identify())

# Configure channel 1
scope.channel1.set_scale(1.0)  # 1V/div
scope.channel1.set_coupling('DC')
scope.channel1.enable()

# Capture waveform
waveform = scope.get_waveform(channel=1)
print(f"Captured {len(waveform.time)} samples")

scope.disconnect()

GUI Application

siglent-gui

Or from Python:

from siglent.gui.app import main
main()

Requirements

Core Library

  • Python 3.8+
  • NumPy >= 1.24.0
  • Matplotlib >= 3.7.0
  • SciPy >= 1.10.0

GUI Application (optional)

Install with [gui] extra to add:

  • PyQt6 >= 6.6.0
  • PyQt6-WebEngine >= 6.6.0
  • PyQtGraph >= 0.13.0 (high-performance plotting)

Optional Extras

  • HDF5 support: Install with [hdf5] to add h5py >= 3.8.0
  • Vector Graphics: Install with [fun] to add shapely, Pillow, svgpathtools (XY mode drawing)
  • All features: Install with [all] for complete functionality

Connection

The oscilloscope must be connected to your network. The default SCPI port is 5024.

To find your oscilloscope's IP address:

  1. Press Utility on the oscilloscope
  2. Navigate to I/O settings
  3. Check the LAN configuration

GUI Application Overview

The Siglent Oscilloscope Control GUI provides a comprehensive interface for controlling your oscilloscope, capturing waveforms, and performing measurements.

Note: Screenshots can be captured following the guide in docs/SCREENSHOT_GUIDE.md. This provides visual documentation of all GUI features.

Main Window

Main Window

The main interface consists of:

  • Waveform Display: High-performance real-time plotting area (center)
  • Control Panels: Tabbed interface with all oscilloscope controls (right)
  • Menu Bar: File operations, acquisition controls, and utilities (top)
  • Status Bar: Connection status and system information (bottom)

Getting Connected

Connection Dialog

To connect to your oscilloscope:

  1. Launch the GUI: siglent-gui
  2. Enter your oscilloscope's IP address
  3. Click Connect

The oscilloscope must be connected to your network (default SCPI port: 5024).

Finding your oscilloscope's IP address:

  • Press Utility on the oscilloscope
  • Navigate to I/O settings
  • Check the LAN configuration

Channel Controls

Channel Controls

The Channels tab provides complete control over all input channels:

  • Enable/Disable: Toggle channels on/off with checkboxes
  • Voltage Scale: Adjust volts/division (0.001V to 10V)
  • Coupling: Set DC, AC, or GND coupling
  • Probe Ratio: Configure probe attenuation (1X, 10X, 100X, etc.)
  • Bandwidth Limit: Enable 20MHz bandwidth limiting
  • Offset: Adjust vertical position

Quick Tip: Enable channels before starting Live View or capturing waveforms.

GUI Application Guide

Live View

Live View

The GUI features high-performance real-time waveform viewing powered by PyQtGraph:

Acquisition → Live View (Ctrl+R)

Performance:

  • Real-time updates at 5-20 fps (configurable)
  • 100x faster than traditional matplotlib-based viewers
  • Non-blocking: GUI remains responsive during data acquisition
  • Supports all 4 channels simultaneously

Controls:

  • Enable channels in the "Channels" tab first
  • Live view automatically acquires from enabled channels
  • Adjust update rate by modifying update_interval in live_view_worker.py

Visual Measurements

Visual Measurements

Interactive measurement markers that you can place and adjust directly on waveforms:

How to use:

  1. Go to the "Visual Measure" tab
  2. Select measurement type (Frequency, Vpp, Rise Time, etc.)
  3. Select channel (CH1-CH4)
  4. Click "Add Marker"
  5. Marker auto-places on waveform
  6. Drag marker gates to adjust measurement region
  7. See real-time measurement updates

Measurement Types:

  • Frequency/Period: Auto-detects signal period
  • Voltage: Vpp, Amplitude, Max, Min, RMS, Mean
  • Timing: Rise Time, Fall Time, Pulse Width, Duty Cycle

Features:

  • Save/Load Configs: Save measurement setups for reuse
  • Export Results: Export to CSV or JSON
  • Auto-Update: Optional 1-second auto-refresh
  • Batch Mode: Run multiple measurements simultaneously

Example Workflow:

# In GUI:
# 1. Capture or enable live view
# 2. Visual Measure tab → Add Marker
# 3. Type: "Frequency", Channel: "CH1" → Add
# 4. Marker appears with measurement result
# 5. Save Config → "my_measurements.json"
# 6. Export Results → "results.csv"

Automated Measurements

Measurements Panel

The Measurements tab provides quick access to standard oscilloscope measurements:

  • 15+ measurement types (frequency, Vpp, RMS, rise time, etc.)
  • Channel selection
  • Results table with units
  • Export measurement results

Cursors

Cursors

Interactive cursors for precise measurements:

  • Vertical cursors for time measurements
  • Horizontal cursors for voltage measurements
  • Delta calculations (ΔT, ΔV, frequency)
  • Draggable cursor lines
  • Real-time delta updates

FFT Analysis

FFT Analysis

Frequency domain analysis:

  • Fast Fourier Transform visualization
  • Peak detection and markers
  • Window function selection (Hanning, Hamming, Blackman)
  • Frequency and amplitude axes
  • Export FFT data

Vector Graphics 🎨 (XY Mode)

Requires: pip install "Siglent-Oscilloscope[fun]"

Turn your oscilloscope into a vector display by generating waveforms for XY mode!

The Vector Graphics tab provides:

Shape Generator:

  • Basic Shapes: Circle, Rectangle, Star, Triangle, Line
  • Lissajous Figures: Classic oscilloscope patterns (3:2, 5:4, 7:5, etc.)
  • Parameter Controls: Adjust size, points, frequency ratios, phase shifts
  • Generate Button: Create vector paths with customizable parameters

Waveform Export:

  • Sample Rate Control: 1-1000 MSa/s for AWG compatibility
  • Duration: 1ms to 10s per waveform
  • Format Options: CSV (universal), NumPy (.npy), Binary (.bin)
  • Save for AWG: Exports separate X and Y waveform files

XY Mode Control:

  • Enable/Disable: Configure oscilloscope for XY display mode
  • Channel Setup: Auto-configures CH1 (X-axis) and CH2 (Y-axis)
  • Status Display: Connection and configuration feedback

How to use:

  1. Go to the "Vector Graphics 🎨" tab
  2. Select a shape (e.g., "Circle" or "Lissajous")
  3. Adjust parameters (radius, points, frequencies)
  4. Click "Generate Shape"
  5. Set sample rate and duration for your AWG
  6. Click "Save Waveforms..." to export
  7. Load the X/Y files into your AWG (Channel 1 = X, Channel 2 = Y)
  8. Connect AWG outputs to scope inputs
  9. Click "Enable XY Mode" or manually enable on scope
  10. Watch your shape appear on the oscilloscope! ✨

Works without scope connection - you can generate and export waveforms offline!

Example Use Cases:

  • Draw circles, stars, and geometric shapes
  • Create classic Lissajous patterns for calibration
  • Generate animations (rotating shapes, morphing patterns)
  • Educational demonstrations of XY mode
  • Signal generator pattern testing

See examples/vector_graphics_xy_mode.py for programmatic usage and animation examples.

Other GUI Features

Reference Waveforms:

  • Save waveforms as references
  • Overlay comparisons
  • Difference mode (live - reference)
  • Calculate correlation

Math Channels:

  • Custom expressions: C1 + C2, C1 * 2, etc.
  • Real-time calculation

FFT Analysis:

  • Frequency domain visualization
  • Window function selection
  • Peak detection

Protocol Decode:

  • I2C, SPI, UART, CAN, LIN decoding
  • Packet analysis and export

API Documentation

Oscilloscope

from siglent import Oscilloscope

# Connect
scope = Oscilloscope('192.168.1.100', port=5024, timeout=5.0)
scope.connect()

# Device information
print(scope.identify())  # Get *IDN? string
print(scope.device_info)  # Parsed device info dict

# Basic controls
scope.run()           # Start acquisition (AUTO mode)
scope.stop()          # Stop acquisition
scope.auto_setup()    # Auto setup
scope.reset()         # Reset to defaults

Channels

# Channel configuration (channels 1-4)
scope.channel1.enable()
scope.channel1.coupling = "DC"  # DC, AC, or GND
scope.channel1.voltage_scale = 1.0  # Volts/division
scope.channel1.voltage_offset = 0.0  # Volts
scope.channel1.probe_ratio = 10.0  # 10X probe
scope.channel1.bandwidth_limit = "OFF"  # ON or OFF

# Get configuration
config = scope.channel1.get_configuration()

Trigger

# Trigger configuration
scope.trigger.mode = "NORMAL"  # AUTO, NORM, SINGLE, STOP
scope.trigger.source = "C1"  # C1, C2, C3, C4, EX, LINE
scope.trigger.level = 0.0  # Trigger level in volts
scope.trigger.slope = "POS"  # POS (rising) or NEG (falling)

# Edge trigger setup
scope.trigger.set_edge_trigger(source="C1", slope="POS")

# Trigger actions
scope.trigger.single()  # Single trigger
scope.trigger.force()   # Force trigger

Waveform Acquisition

# Acquire waveform
waveform = scope.get_waveform(channel=1)

# Access data
print(waveform.time)      # Time array (numpy)
print(waveform.voltage)   # Voltage array (numpy)
print(waveform.sample_rate)
print(waveform.record_length)

# Save waveform
scope.waveform.save_waveform(waveform, "data.csv", format="CSV")

Measurements

# Individual measurements
freq = scope.measurement.measure_frequency(1)
vpp = scope.measurement.measure_vpp(1)
vrms = scope.measurement.measure_rms(1)
period = scope.measurement.measure_period(1)

# All measurements at once
measurements = scope.measurement.measure_all(1)

Programmatic Data Collection & Automation

For advanced data collection workflows, use the high-level automation API:

from siglent.automation import DataCollector

# Simple capture with automatic analysis
with DataCollector('192.168.1.100') as collector:
    # Capture waveforms
    data = collector.capture_single([1, 2])

    # Analyze waveform
    stats = collector.analyze_waveform(data[1])
    print(f"Vpp: {stats['vpp']:.3f}V, Freq: {stats['frequency']/1e3:.2f}kHz")

    # Save to file (supports NPZ, CSV, MAT, HDF5)
    collector.save_data(data, 'measurement.npz')

Batch capture with configuration sweeps:

# Capture with different timebase and voltage settings
results = collector.batch_capture(
    channels=[1],
    timebase_scales=['1us', '10us', '100us'],
    voltage_scales={1: ['500mV', '1V', '2V']},
    triggers_per_config=5
)
collector.save_batch(results, 'batch_output')

Continuous time-series collection:

# Collect data over time with automated file saving
collector.start_continuous_capture(
    channels=[1, 2],
    duration=300,          # 5 minutes
    interval=1.0,          # 1 capture per second
    output_dir='time_series_data',
    file_format='npz'
)

Event-based trigger capture:

from siglent.automation import TriggerWaitCollector

with TriggerWaitCollector('192.168.1.100') as tc:
    # Configure trigger
    tc.collector.scope.trigger.set_source(1)
    tc.collector.scope.trigger.set_slope('POS')
    tc.collector.scope.trigger.set_level(1, 1.0)

    # Wait for trigger event
    data = tc.wait_for_trigger(channels=[1, 2], max_wait=30.0)

Advanced analysis:

# Built-in analysis includes: Vpp, RMS, frequency, SNR, THD, etc.
analysis = collector.analyze_waveform(waveform)
print(f"SNR: {analysis['snr_db']:.2f} dB")
print(f"THD: {analysis['thd_percent']:.2f}%")

See examples/ directory for complete automation examples including:

  • Simple capture (simple_capture.py)
  • Batch processing (batch_capture.py)
  • Continuous monitoring (continuous_capture.py)
  • Trigger-based capture (trigger_based_capture.py)
  • Advanced analysis with visualization (advanced_analysis.py)

Examples

See the examples/ directory for complete working examples:

  • basic_usage.py - Connection and basic operations
  • waveform_capture.py - Capture and save waveforms
  • measurements.py - Automated measurements
  • live_plot.py - Real-time plotting

Supported Models

Fully Tested

  • SDS800X HD Series: SDS804X HD, SDS824X HD
  • SDS1000X-E Series: SDS1102X-E, SDS1104X-E, SDS1202X-E, SDS1204X-E
  • SDS2000X Plus Series: SDS2104X+, SDS2204X+, SDS2354X+
  • SDS5000X Series: SDS5034X, SDS5054X, SDS5104X

Compatibility

Should work with other Siglent oscilloscopes that support SCPI commands over Ethernet. Model-specific features are auto-detected via the ModelCapability registry.

Note: Some SCPI commands vary between models. The library includes model-specific command variants for HD, X, and Plus series.

Contributing

Contributions are welcome! Please read our Contributing Guide for details on:

  • Development setup and workflow
  • Code style and testing requirements
  • Pull request process
  • How to report bugs and request features

Quick Start for Contributors

# Clone and setup
git clone https://github.com/little-did-I-know/Siglent-Oscilloscope.git
cd Siglent-Oscilloscope

# Install development environment
make dev-setup

# Run tests
make test

# Format code
make format

# Run all checks
make check

See our Code of Conduct and Security Policy for more information.

Community and Support

Resources

License

MIT License - see LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

siglent_oscilloscope-0.3.1.tar.gz (7.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

siglent_oscilloscope-0.3.1-py3-none-any.whl (175.0 kB view details)

Uploaded Python 3

File details

Details for the file siglent_oscilloscope-0.3.1.tar.gz.

File metadata

  • Download URL: siglent_oscilloscope-0.3.1.tar.gz
  • Upload date:
  • Size: 7.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for siglent_oscilloscope-0.3.1.tar.gz
Algorithm Hash digest
SHA256 f4af712e60bf24b0fa55e75ebc5aa4c305393afbebf09aad25e13a2ed16a9b9c
MD5 67da1cda03af350310dae5fc47fac951
BLAKE2b-256 18653c69cff9b3ee6d42e772d8e502ecc521b8900c4fc0247621b92a0b8e2498

See more details on using hashes here.

Provenance

The following attestation bundles were made for siglent_oscilloscope-0.3.1.tar.gz:

Publisher: publish.yml on little-did-I-know/Siglent-Oscilloscope

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file siglent_oscilloscope-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for siglent_oscilloscope-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 508c1a7889de93bf8a8a0f70c1e91e5d8727d5faf94575955063adb26f85b735
MD5 90dff7c0e988d3b12beb3be943b4315b
BLAKE2b-256 57fbeef859a76f8a21f1fc6ecae0bda5cb28b4e1676a2492ebae7208bad24267

See more details on using hashes here.

Provenance

The following attestation bundles were made for siglent_oscilloscope-0.3.1-py3-none-any.whl:

Publisher: publish.yml on little-did-I-know/Siglent-Oscilloscope

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page