SCPI-Instrument-Control 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,918 @@
1
+ Metadata-Version: 2.4
2
+ Name: SCPI-Instrument-Control
3
+ Version: 1.0.0
4
+ Summary: Universal Python library for controlling SCPI-compatible test equipment via Ethernet/LAN. Supports oscilloscopes (Siglent SDS series, generic SCPI scopes), function generators/AWGs (Siglent SDG series, generic SCPI AWGs), and power supplies (Siglent SPD series, generic SCPI PSUs). Features include waveform capture, measurements, FFT analysis, PyQt6 GUI, automated report generation with AI analysis, and comprehensive SCPI command abstraction.
5
+ Author: Robin Mumm
6
+ Maintainer: little-did-I-know
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/little-did-I-know/SCPI-Instrument-Control
9
+ Project-URL: Documentation, https://little-did-I-know.github.io/SCPI-Instrument-Control/
10
+ Project-URL: Repository, https://github.com/little-did-I-know/SCPI-Instrument-Control
11
+ Project-URL: Issues, https://github.com/little-did-I-know/SCPI-Instrument-Control/issues
12
+ Project-URL: Changelog, https://github.com/little-did-I-know/SCPI-Instrument-Control/blob/main/CHANGELOG.md
13
+ Keywords: SCPI,instrument control,test equipment,oscilloscope,function generator,AWG,power supply,PSU,siglent,SDS,SDG,SPD,IEEE 488.2,waveform,signal generator,laboratory,automation,measurement,data acquisition,lab automation,PyQt6,GUI,FFT,protocol decoder,I2C,SPI,UART,visualization,voltage,current,frequency,waveform generator,waveform,test equipment,lab equipment
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Manufacturing
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3 :: Only
26
+ Classifier: Topic :: Scientific/Engineering
27
+ Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
28
+ Classifier: Topic :: System :: Hardware :: Hardware Drivers
29
+ Classifier: Topic :: System :: Networking :: Monitoring
30
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
+ Classifier: Environment :: X11 Applications :: Qt
32
+ Classifier: Typing :: Typed
33
+ Requires-Python: >=3.8
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: numpy>=1.24.0
37
+ Requires-Dist: matplotlib>=3.7.0
38
+ Requires-Dist: scipy>=1.10.0
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=7.0; extra == "dev"
41
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
42
+ Requires-Dist: codecov>=2.1.0; extra == "dev"
43
+ Requires-Dist: black>=23.0; extra == "dev"
44
+ Requires-Dist: flake8>=6.0; extra == "dev"
45
+ Requires-Dist: build>=0.10.0; extra == "dev"
46
+ Requires-Dist: twine>=4.0.0; extra == "dev"
47
+ Requires-Dist: black[jupyter]>=23.0; extra == "dev"
48
+ Provides-Extra: hdf5
49
+ Requires-Dist: h5py>=3.8.0; extra == "hdf5"
50
+ Provides-Extra: gui
51
+ Requires-Dist: PyQt6>=6.6.0; extra == "gui"
52
+ Requires-Dist: PyQt6-WebEngine>=6.6.0; extra == "gui"
53
+ Requires-Dist: pyqtgraph>=0.13.0; extra == "gui"
54
+ Provides-Extra: fun
55
+ Requires-Dist: shapely>=2.0.0; extra == "fun"
56
+ Requires-Dist: Pillow>=10.0.0; extra == "fun"
57
+ Requires-Dist: svgpathtools>=1.6.0; extra == "fun"
58
+ Provides-Extra: report-generator
59
+ Requires-Dist: PyQt6>=6.6.0; extra == "report-generator"
60
+ Requires-Dist: Pillow>=10.0.0; extra == "report-generator"
61
+ Requires-Dist: requests>=2.31.0; extra == "report-generator"
62
+ Requires-Dist: reportlab>=4.0.0; extra == "report-generator"
63
+ Requires-Dist: ollama>=0.6.0; extra == "report-generator"
64
+ Provides-Extra: power-supply-beta
65
+ Provides-Extra: usb
66
+ Requires-Dist: pyvisa>=1.14.0; extra == "usb"
67
+ Requires-Dist: pyvisa-py>=0.7.0; extra == "usb"
68
+ Provides-Extra: experimental
69
+ Provides-Extra: docs
70
+ Requires-Dist: mkdocs>=1.5.0; extra == "docs"
71
+ Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
72
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
73
+ Requires-Dist: mkdocs-gen-files>=0.5.0; extra == "docs"
74
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == "docs"
75
+ Requires-Dist: mkdocs-section-index>=0.3.0; extra == "docs"
76
+ Provides-Extra: build-exe
77
+ Requires-Dist: pyinstaller>=6.0.0; extra == "build-exe"
78
+ Provides-Extra: all
79
+ Requires-Dist: h5py>=3.8.0; extra == "all"
80
+ Requires-Dist: PyQt6>=6.6.0; extra == "all"
81
+ Requires-Dist: PyQt6-WebEngine>=6.6.0; extra == "all"
82
+ Requires-Dist: pyqtgraph>=0.13.0; extra == "all"
83
+ Requires-Dist: shapely>=2.0.0; extra == "all"
84
+ Requires-Dist: Pillow>=10.0.0; extra == "all"
85
+ Requires-Dist: svgpathtools>=1.6.0; extra == "all"
86
+ Requires-Dist: requests>=2.31.0; extra == "all"
87
+ Requires-Dist: reportlab>=4.0.0; extra == "all"
88
+ Requires-Dist: ollama>=0.6.0; extra == "all"
89
+ Dynamic: license-file
90
+
91
+ # SCPI Instrument Control
92
+
93
+ > **๐Ÿ“ฆ Package Renamed!** This project was formerly known as `Siglent-Oscilloscope`. See the [Migration Guide](#migration-guide) below for updating your code.
94
+
95
+ [![CI](https://github.com/little-did-I-know/SCPI-Instrument-Control/actions/workflows/ci.yml/badge.svg)](https://github.com/little-did-I-know/SCPI-Instrument-Control/actions/workflows/ci.yml)
96
+ [![codecov](https://codecov.io/gh/little-did-I-know/SCPI-Instrument-Control/branch/main/graph/badge.svg)](https://codecov.io/gh/little-did-I-know/SCPI-Instrument-Control)
97
+ [![PyPI version](https://img.shields.io/pypi/v/SCPI-Instrument-Control.svg)](https://pypi.org/project/SCPI-Instrument-Control/)
98
+ [![PyPI Downloads](https://img.shields.io/pypi/dm/SCPI-Instrument-Control.svg)](https://pypi.org/project/SCPI-Instrument-Control/)
99
+ [![Python Version](https://img.shields.io/pypi/pyversions/SCPI-Instrument-Control)](https://pypi.org/project/SCPI-Instrument-Control/)
100
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
101
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
102
+ [![GitHub issues](https://img.shields.io/github/issues/little-did-I-know/SCPI-Instrument-Control)](https://github.com/little-did-I-know/SCPI-Instrument-Control/issues)
103
+ [![GitHub stars](https://img.shields.io/github/stars/little-did-I-know/SCPI-Instrument-Control)](https://github.com/little-did-I-know/SCPI-Instrument-Control/stargazers)
104
+ [![GitHub last commit](https://img.shields.io/github/last-commit/little-did-I-know/SCPI-Instrument-Control)](https://github.com/little-did-I-know/SCPI-Instrument-Control/commits/main)
105
+ [![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-Support-yellow.svg?style=flat&logo=buy-me-a-coffee)](https://buymeacoffee.com/little.did.i.know)
106
+
107
+ A universal Python library for controlling SCPI-compatible test equipment via Ethernet/LAN. Supports oscilloscopes, function generators (AWGs), and power supplies with a comprehensive programmatic API and high-performance PyQt6-based GUI application.
108
+
109
+ ## Features
110
+
111
+ ### Core Features
112
+
113
+ - **Programmatic API**: Control your oscilloscope from Python scripts
114
+ - **Automation & Data Collection**: High-level API for batch capture, continuous monitoring, and analysis
115
+ - **GUI Application**: Modern PyQt6-based graphical interface
116
+ - **Waveform Acquisition**: Capture and download waveform data in multiple formats (NPZ, CSV, MAT, HDF5)
117
+ - **Channel Configuration**: Control voltage scale, coupling, offset, bandwidth
118
+ - **Trigger Settings**: Configure trigger modes, levels, edge detection
119
+ - **Advanced Analysis**: Built-in FFT, SNR, THD, and statistical analysis tools
120
+
121
+ ### GUI Features (New!)
122
+
123
+ - **High-Performance Live View**: Real-time waveform display at 1000+ fps using PyQtGraph
124
+ - **Interactive Visual Measurements**: Click-and-drag measurement markers directly on waveforms
125
+ - 15+ measurement types: Frequency, Vpp, Rise Time, Duty Cycle, etc.
126
+ - Visual gates and markers with real-time calculation
127
+ - Save/load measurement configurations
128
+ - Export results to CSV/JSON
129
+ - **Non-Blocking Updates**: Threaded data acquisition keeps GUI responsive
130
+ - **Reference Waveforms**: Save, overlay, and compare waveforms
131
+ - **Protocol Decoding**: I2C, SPI, UART, CAN, LIN support
132
+ - **Math Functions**: Custom math expressions on waveforms
133
+ - **VNC Display**: Embedded oscilloscope screen viewer
134
+
135
+ ### Automated Test Report Generation ๐Ÿ“Š
136
+
137
+ **Automatically generate comprehensive PDF and Markdown test reports** from your waveform captures with detailed analysis, visualizations, and AI-powered insights. Perfect for documentation, test validation, and automated quality control.
138
+
139
+ ```python
140
+ # Install report generator dependencies
141
+ # pip install "SCPI-Instrument-Control[report-generator]"
142
+
143
+ from scpi_control.report_generator import ReportGenerator, PDFGenerator, MarkdownGenerator
144
+ from pathlib import Path
145
+
146
+ # Create a report generator
147
+ report = ReportGenerator(
148
+ title="Probe Calibration Test Report",
149
+ test_id="CAL-2024-001",
150
+ operator="Lab Technician"
151
+ )
152
+
153
+ # Add waveform captures
154
+ waveform = scope.get_waveform(channel=1)
155
+ report.add_waveform(waveform, channel_number=1, name="Calibration Signal")
156
+
157
+ # Automatic signal analysis
158
+ waveform.analyze() # Auto-detects signal type, calculates 25+ statistics
159
+
160
+ # Optional: Add AI insights (requires Ollama)
161
+ report.set_ai_model("llama3.2") # Local LLM analysis
162
+
163
+ # Generate reports in multiple formats
164
+ pdf_gen = PDFGenerator(report_data=report.data)
165
+ pdf_gen.generate(Path("calibration_report.pdf"))
166
+
167
+ markdown_gen = MarkdownGenerator(report_data=report.data)
168
+ markdown_gen.generate(Path("calibration_report.md"))
169
+ ```
170
+
171
+ **Key Features:**
172
+
173
+ - โœ… **Automatic Signal Detection** - FFT-based classification (sine, square, triangle, pulse, etc.)
174
+ - โœ… **Comprehensive Statistics** - 25+ parameters including Vpp, RMS, frequency, SNR, THD, jitter, overshoot
175
+ - โœ… **AI-Powered Analysis** - Optional LLM integration via Ollama for intelligent waveform insights
176
+ - โœ… **Region Extraction** - Zoom into plateaus, edges, and transients with calibration guidance
177
+ - โœ… **Multiple Formats** - Generate PDF and Markdown reports with embedded plots
178
+ - โœ… **Professional Layout** - Publication-ready reports with metadata, statistics tables, and visualizations
179
+
180
+ **Report Sections Include:**
181
+
182
+ - Test metadata (title, ID, operator, timestamp, scope model)
183
+ - Waveform plots with automatic scaling
184
+ - Signal classification and characteristics
185
+ - Detailed measurement tables
186
+ - Region-of-interest analysis with zoomed views
187
+ - AI-generated insights and recommendations (optional)
188
+ - Pass/fail criteria and test conclusions
189
+
190
+ See `examples/probe_calibration_analysis.py` for complete examples including region extraction and automated probe compensation guidance.
191
+
192
+ ### Vector Graphics / XY Mode (Fun! ๐ŸŽจ)
193
+
194
+ Use your oscilloscope as a vector display by generating waveforms for XY mode:
195
+
196
+ - **Draw Shapes**: Circles, rectangles, stars, polygons, Lissajous figures
197
+ - **Text Rendering**: Display text messages on your oscilloscope screen
198
+ - **Animations**: Create rotating and transforming graphics
199
+ - **Composite Paths**: Combine multiple shapes into complex drawings
200
+
201
+ **Requirements**: External AWG/DAC or scope's built-in AWG to feed generated waveforms into scope channels.
202
+
203
+ ```python
204
+ # Install the fun extras
205
+ # pip install "SCPI-Instrument-Control[fun]"
206
+
207
+ from scpi_control import Oscilloscope
208
+ from scpi_control.vector_graphics import Shape
209
+
210
+ scope = Oscilloscope('192.168.1.100')
211
+ scope.connect()
212
+
213
+ # Enable XY mode (CH1=X, CH2=Y)
214
+ scope.vector_display.enable_xy_mode()
215
+
216
+ # Generate waveforms for a circle
217
+ circle = Shape.circle(radius=0.8, points=1000)
218
+ x_wave, y_wave = scope.vector_display.draw(circle)
219
+
220
+ # Save for AWG upload
221
+ scope.vector_display.save_waveforms(circle, "my_circle", format='csv')
222
+ # Load my_circle_x.csv and my_circle_y.csv into your AWG!
223
+ ```
224
+
225
+ See `examples/vector_graphics_xy_mode.py` for more demos including animations and text!
226
+
227
+ ## Installation
228
+
229
+ ### From PyPI (recommended)
230
+
231
+ ```bash
232
+ pip install SCPI-Instrument-Control
233
+ ```
234
+
235
+ To include optional features, use extras:
236
+
237
+ ```bash
238
+ # GUI application with PyQt6
239
+ pip install "SCPI-Instrument-Control[gui]"
240
+
241
+ # Automated report generation (PDF/Markdown with AI analysis)
242
+ pip install "SCPI-Instrument-Control[report-generator]"
243
+
244
+ # Vector graphics and XY mode (draw shapes on scope!)
245
+ pip install "SCPI-Instrument-Control[fun]"
246
+
247
+ # Everything
248
+ pip install "SCPI-Instrument-Control[all]"
249
+ ```
250
+
251
+ **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.
252
+
253
+ ### From source
254
+
255
+ ```bash
256
+ git clone git@github.com:little-did-I-know/SCPI-Instrument-Control.git
257
+ cd SCPI-Instrument-Control
258
+ pip install -e .
259
+ ```
260
+
261
+ Install with GUI support from source:
262
+
263
+ ```bash
264
+ pip install -e ".[gui]"
265
+ ```
266
+
267
+ ### Development installation
268
+
269
+ ```bash
270
+ pip install -e ".[dev]"
271
+ ```
272
+
273
+ ### Build & Publish (PyPI)
274
+
275
+ To create release artifacts that render correctly on PyPI:
276
+
277
+ ```bash
278
+ python -m build
279
+ twine check dist/*
280
+ ```
281
+
282
+ The `twine check` command validates the built distributions, including the long description rendered from `README.md`, before upload.
283
+
284
+ ## Migration Guide
285
+
286
+ **v1.0.0** introduces a package rename from `Siglent-Oscilloscope` to `SCPI-Instrument-Control` to better reflect the expanded capabilities of this library.
287
+
288
+ ### For Existing Users
289
+
290
+ If you're upgrading from the old `siglent` package:
291
+
292
+ #### 1. Update Your Installation
293
+
294
+ **Uninstall the old package** (if installed):
295
+
296
+ ```bash
297
+ pip uninstall siglent
298
+ ```
299
+
300
+ **Install the new package**:
301
+
302
+ ```bash
303
+ pip install SCPI-Instrument-Control
304
+ ```
305
+
306
+ Or with extras:
307
+
308
+ ```bash
309
+ pip install "SCPI-Instrument-Control[gui]"
310
+ pip install "SCPI-Instrument-Control[all]"
311
+ ```
312
+
313
+ #### 2. Update Your Import Statements
314
+
315
+ **Old imports** (deprecated but still work):
316
+
317
+ ```python
318
+ from siglent import Oscilloscope, PowerSupply, FunctionGenerator
319
+ from siglent.gui.app import main
320
+ from siglent.waveform import Waveform
321
+ ```
322
+
323
+ **New imports** (recommended):
324
+
325
+ ```python
326
+ from scpi_control import Oscilloscope, PowerSupply, FunctionGenerator
327
+ from scpi_control.gui.app import main
328
+ from scpi_control.waveform import Waveform
329
+ ```
330
+
331
+ #### 3. Backward Compatibility
332
+
333
+ **Good news**: The old `import siglent` syntax still works! A compatibility shim automatically redirects to `scpi_control`.
334
+
335
+ However, you'll see a `DeprecationWarning` encouraging you to update your code:
336
+
337
+ ```
338
+ DeprecationWarning: The 'siglent' package name is deprecated and will be removed in v2.0.0.
339
+ Please update your imports to use 'scpi_control' instead.
340
+ ```
341
+
342
+ **The compatibility layer will be removed in v2.0.0**, so please migrate your code when convenient.
343
+
344
+ #### 4. Command-Line Tools
345
+
346
+ The CLI commands remain **unchanged** for convenience:
347
+
348
+ ```bash
349
+ siglent-gui # Still works!
350
+ siglent-report-generator # Still works!
351
+ ```
352
+
353
+ No changes needed to scripts or automation that invoke these commands.
354
+
355
+ #### 5. What Changed
356
+
357
+ | Old | New | Status |
358
+ |-----|-----|--------|
359
+ | PyPI package: `siglent` | PyPI package: `SCPI-Instrument-Control` | **Changed** |
360
+ | `import siglent` | `import scpi_control` | **Recommended** |
361
+ | `siglent-gui` command | `siglent-gui` command | **Unchanged** |
362
+ | `siglent-report-generator` command | `siglent-report-generator` command | **Unchanged** |
363
+
364
+ #### 6. Why the Rename?
365
+
366
+ This library has grown significantly beyond its original focus on Siglent oscilloscopes:
367
+
368
+ - **Multi-Instrument Support**: Oscilloscopes, power supplies, and function generators
369
+ - **Multi-Vendor Support**: Works with any SCPI-compatible equipment (not just Siglent)
370
+ - **Universal Protocol**: Based on industry-standard SCPI commands
371
+
372
+ The new name better represents what the library does: **control any SCPI-compatible test equipment**.
373
+
374
+ ### Need Help?
375
+
376
+ If you encounter any migration issues:
377
+
378
+ - Check the [CHANGELOG.md](CHANGELOG.md) for detailed v1.0.0 release notes
379
+ - [Open an issue](https://github.com/little-did-I-know/SCPI-Instrument-Control/issues) on GitHub
380
+ - Review the updated [examples/](examples/) directory for new usage patterns
381
+
382
+ ## Quick Start
383
+
384
+ ### Programmatic Usage
385
+
386
+ ```python
387
+ from scpi_control import Oscilloscope
388
+
389
+ # Connect to oscilloscope
390
+ scope = Oscilloscope('192.168.1.100')
391
+ scope.connect()
392
+
393
+ # Get device information
394
+ print(scope.identify())
395
+
396
+ # Configure channel 1
397
+ scope.channel1.set_scale(1.0) # 1V/div
398
+ scope.channel1.set_coupling('DC')
399
+ scope.channel1.enable()
400
+
401
+ # Capture waveform
402
+ waveform = scope.get_waveform(channel=1)
403
+ print(f"Captured {len(waveform.time)} samples")
404
+
405
+ scope.disconnect()
406
+ ```
407
+
408
+ ### GUI Application
409
+
410
+ ```bash
411
+ siglent-gui
412
+ ```
413
+
414
+ Or from Python:
415
+
416
+ ```python
417
+ from scpi_control.gui.app import main
418
+ main()
419
+ ```
420
+
421
+ ## Requirements
422
+
423
+ ### Core Library
424
+
425
+ - Python 3.8+
426
+ - NumPy >= 1.24.0
427
+ - Matplotlib >= 3.7.0
428
+ - SciPy >= 1.10.0
429
+
430
+ ### GUI Application (optional)
431
+
432
+ Install with `[gui]` extra to add:
433
+
434
+ - PyQt6 >= 6.6.0
435
+ - PyQt6-WebEngine >= 6.6.0
436
+ - PyQtGraph >= 0.13.0 (high-performance plotting)
437
+
438
+ ### Optional Extras
439
+
440
+ - **Report Generator**: Install with `[report-generator]` to add PyQt6, Pillow, requests, ReportLab, Ollama (PDF/Markdown reports with AI)
441
+ - **HDF5 support**: Install with `[hdf5]` to add h5py >= 3.8.0
442
+ - **Vector Graphics**: Install with `[fun]` to add shapely, Pillow, svgpathtools (XY mode drawing)
443
+ - **All features**: Install with `[all]` for complete functionality
444
+
445
+ ## Connection
446
+
447
+ The oscilloscope must be connected to your network. The default SCPI port is 5024.
448
+
449
+ To find your oscilloscope's IP address:
450
+
451
+ 1. Press **Utility** on the oscilloscope
452
+ 2. Navigate to **I/O** settings
453
+ 3. Check the **LAN** configuration
454
+
455
+ ## GUI Application Overview
456
+
457
+ The SCPI Instrument Control GUI provides a comprehensive interface for controlling your oscilloscope, capturing waveforms, and performing measurements.
458
+
459
+ > **Note**: Screenshots can be captured following the guide in [`docs/SCREENSHOT_GUIDE.md`](docs/SCREENSHOT_GUIDE.md). This provides visual documentation of all GUI features.
460
+
461
+ ### Main Window
462
+
463
+ ![Main Window](docs/images/main_window.png)
464
+
465
+ The main interface consists of:
466
+
467
+ - **Waveform Display**: High-performance real-time plotting area (center)
468
+ - **Control Panels**: Tabbed interface with all oscilloscope controls (right)
469
+ - **Menu Bar**: File operations, acquisition controls, and utilities (top)
470
+ - **Status Bar**: Connection status and system information (bottom)
471
+
472
+ ### Getting Connected
473
+
474
+ ![Connection Dialog](docs/images/connection_dialog.png)
475
+
476
+ To connect to your oscilloscope:
477
+
478
+ 1. Launch the GUI: `siglent-gui`
479
+ 2. Enter your oscilloscope's IP address
480
+ 3. Click **Connect**
481
+
482
+ The oscilloscope must be connected to your network (default SCPI port: 5024).
483
+
484
+ **Finding your oscilloscope's IP address**:
485
+
486
+ - Press **Utility** on the oscilloscope
487
+ - Navigate to **I/O** settings
488
+ - Check the **LAN** configuration
489
+
490
+ ### Channel Controls
491
+
492
+ ![Channel Controls](docs/images/channel_controls.png)
493
+
494
+ The **Channels** tab provides complete control over all input channels:
495
+
496
+ - **Enable/Disable**: Toggle channels on/off with checkboxes
497
+ - **Voltage Scale**: Adjust volts/division (0.001V to 10V)
498
+ - **Coupling**: Set DC, AC, or GND coupling
499
+ - **Probe Ratio**: Configure probe attenuation (1X, 10X, 100X, etc.)
500
+ - **Bandwidth Limit**: Enable 20MHz bandwidth limiting
501
+ - **Offset**: Adjust vertical position
502
+
503
+ **Quick Tip**: Enable channels before starting Live View or capturing waveforms.
504
+
505
+ ## GUI Application Guide
506
+
507
+ ### Live View
508
+
509
+ ![Live View](docs/images/live_view.png)
510
+
511
+ The GUI features **high-performance real-time waveform viewing** powered by PyQtGraph:
512
+
513
+ ```
514
+ Acquisition โ†’ Live View (Ctrl+R)
515
+ ```
516
+
517
+ **Performance:**
518
+
519
+ - Real-time updates at 5-20 fps (configurable)
520
+ - 100x faster than traditional matplotlib-based viewers
521
+ - Non-blocking: GUI remains responsive during data acquisition
522
+ - Supports all 4 channels simultaneously
523
+
524
+ **Controls:**
525
+
526
+ - Enable channels in the "Channels" tab first
527
+ - Live view automatically acquires from enabled channels
528
+ - Adjust update rate by modifying `update_interval` in `live_view_worker.py`
529
+
530
+ ### Visual Measurements
531
+
532
+ ![Visual Measurements](docs/images/visual_measurements.png)
533
+
534
+ Interactive measurement markers that you can place and adjust directly on waveforms:
535
+
536
+ **How to use:**
537
+
538
+ 1. Go to the **"Visual Measure"** tab
539
+ 2. Select measurement type (Frequency, Vpp, Rise Time, etc.)
540
+ 3. Select channel (CH1-CH4)
541
+ 4. Click **"Add Marker"**
542
+ 5. Marker auto-places on waveform
543
+ 6. Drag marker gates to adjust measurement region
544
+ 7. See real-time measurement updates
545
+
546
+ **Measurement Types:**
547
+
548
+ - **Frequency/Period**: Auto-detects signal period
549
+ - **Voltage**: Vpp, Amplitude, Max, Min, RMS, Mean
550
+ - **Timing**: Rise Time, Fall Time, Pulse Width, Duty Cycle
551
+
552
+ **Features:**
553
+
554
+ - **Save/Load Configs**: Save measurement setups for reuse
555
+ - **Export Results**: Export to CSV or JSON
556
+ - **Auto-Update**: Optional 1-second auto-refresh
557
+ - **Batch Mode**: Run multiple measurements simultaneously
558
+
559
+ **Example Workflow:**
560
+
561
+ ```python
562
+ # In GUI:
563
+ # 1. Capture or enable live view
564
+ # 2. Visual Measure tab โ†’ Add Marker
565
+ # 3. Type: "Frequency", Channel: "CH1" โ†’ Add
566
+ # 4. Marker appears with measurement result
567
+ # 5. Save Config โ†’ "my_measurements.json"
568
+ # 6. Export Results โ†’ "results.csv"
569
+ ```
570
+
571
+ ### Automated Measurements
572
+
573
+ ![Measurements Panel](docs/images/measurements_panel.png)
574
+
575
+ The **Measurements** tab provides quick access to standard oscilloscope measurements:
576
+
577
+ - 15+ measurement types (frequency, Vpp, RMS, rise time, etc.)
578
+ - Channel selection
579
+ - Results table with units
580
+ - Export measurement results
581
+
582
+ ### Cursors
583
+
584
+ ![Cursors](docs/images/cursors.png)
585
+
586
+ Interactive cursors for precise measurements:
587
+
588
+ - **Vertical cursors** for time measurements
589
+ - **Horizontal cursors** for voltage measurements
590
+ - **Delta calculations** (ฮ”T, ฮ”V, frequency)
591
+ - Draggable cursor lines
592
+ - Real-time delta updates
593
+
594
+ ### FFT Analysis
595
+
596
+ ![FFT Analysis](docs/images/fft_analysis.png)
597
+
598
+ Frequency domain analysis:
599
+
600
+ - Fast Fourier Transform visualization
601
+ - Peak detection and markers
602
+ - Window function selection (Hanning, Hamming, Blackman)
603
+ - Frequency and amplitude axes
604
+ - Export FFT data
605
+
606
+ ### Vector Graphics ๐ŸŽจ (XY Mode)
607
+
608
+ > **Requires**: `pip install "SCPI-Instrument-Control[fun]"`
609
+
610
+ Turn your oscilloscope into a vector display by generating waveforms for XY mode!
611
+
612
+ The **Vector Graphics** tab provides:
613
+
614
+ **Shape Generator:**
615
+
616
+ - **Basic Shapes**: Circle, Rectangle, Star, Triangle, Line
617
+ - **Lissajous Figures**: Classic oscilloscope patterns (3:2, 5:4, 7:5, etc.)
618
+ - **Parameter Controls**: Adjust size, points, frequency ratios, phase shifts
619
+ - **Generate Button**: Create vector paths with customizable parameters
620
+
621
+ **Waveform Export:**
622
+
623
+ - **Sample Rate Control**: 1-1000 MSa/s for AWG compatibility
624
+ - **Duration**: 1ms to 10s per waveform
625
+ - **Format Options**: CSV (universal), NumPy (.npy), Binary (.bin)
626
+ - **Save for AWG**: Exports separate X and Y waveform files
627
+
628
+ **XY Mode Control:**
629
+
630
+ - **Enable/Disable**: Configure oscilloscope for XY display mode
631
+ - **Channel Setup**: Auto-configures CH1 (X-axis) and CH2 (Y-axis)
632
+ - **Status Display**: Connection and configuration feedback
633
+
634
+ **How to use:**
635
+
636
+ 1. Go to the **"Vector Graphics ๐ŸŽจ"** tab
637
+ 2. Select a shape (e.g., "Circle" or "Lissajous")
638
+ 3. Adjust parameters (radius, points, frequencies)
639
+ 4. Click **"Generate Shape"**
640
+ 5. Set sample rate and duration for your AWG
641
+ 6. Click **"Save Waveforms..."** to export
642
+ 7. Load the X/Y files into your AWG (Channel 1 = X, Channel 2 = Y)
643
+ 8. Connect AWG outputs to scope inputs
644
+ 9. Click **"Enable XY Mode"** or manually enable on scope
645
+ 10. Watch your shape appear on the oscilloscope! โœจ
646
+
647
+ **Works without scope connection** - you can generate and export waveforms offline!
648
+
649
+ **Example Use Cases:**
650
+
651
+ - Draw circles, stars, and geometric shapes
652
+ - Create classic Lissajous patterns for calibration
653
+ - Generate animations (rotating shapes, morphing patterns)
654
+ - Educational demonstrations of XY mode
655
+ - Signal generator pattern testing
656
+
657
+ See `examples/vector_graphics_xy_mode.py` for programmatic usage and animation examples.
658
+
659
+ ### Other GUI Features
660
+
661
+ **Reference Waveforms:**
662
+
663
+ - Save waveforms as references
664
+ - Overlay comparisons
665
+ - Difference mode (live - reference)
666
+ - Calculate correlation
667
+
668
+ **Math Channels:**
669
+
670
+ - Custom expressions: `C1 + C2`, `C1 * 2`, etc.
671
+ - Real-time calculation
672
+
673
+ **FFT Analysis:**
674
+
675
+ - Frequency domain visualization
676
+ - Window function selection
677
+ - Peak detection
678
+
679
+ **Protocol Decode:**
680
+
681
+ - I2C, SPI, UART, CAN, LIN decoding
682
+ - Packet analysis and export
683
+
684
+ ## API Documentation
685
+
686
+ ### Oscilloscope
687
+
688
+ ```python
689
+ from scpi_control import Oscilloscope
690
+
691
+ # Connect
692
+ scope = Oscilloscope('192.168.1.100', port=5024, timeout=5.0)
693
+ scope.connect()
694
+
695
+ # Device information
696
+ print(scope.identify()) # Get *IDN? string
697
+ print(scope.device_info) # Parsed device info dict
698
+
699
+ # Basic controls
700
+ scope.run() # Start acquisition (AUTO mode)
701
+ scope.stop() # Stop acquisition
702
+ scope.auto_setup() # Auto setup
703
+ scope.reset() # Reset to defaults
704
+ ```
705
+
706
+ ### Channels
707
+
708
+ ```python
709
+ # Channel configuration (channels 1-4)
710
+ scope.channel1.enable()
711
+ scope.channel1.coupling = "DC" # DC, AC, or GND
712
+ scope.channel1.voltage_scale = 1.0 # Volts/division
713
+ scope.channel1.voltage_offset = 0.0 # Volts
714
+ scope.channel1.probe_ratio = 10.0 # 10X probe
715
+ scope.channel1.bandwidth_limit = "OFF" # ON or OFF
716
+
717
+ # Get configuration
718
+ config = scope.channel1.get_configuration()
719
+ ```
720
+
721
+ ### Trigger
722
+
723
+ ```python
724
+ # Trigger configuration
725
+ scope.trigger.mode = "NORMAL" # AUTO, NORM, SINGLE, STOP
726
+ scope.trigger.source = "C1" # C1, C2, C3, C4, EX, LINE
727
+ scope.trigger.level = 0.0 # Trigger level in volts
728
+ scope.trigger.slope = "POS" # POS (rising) or NEG (falling)
729
+
730
+ # Edge trigger setup
731
+ scope.trigger.set_edge_trigger(source="C1", slope="POS")
732
+
733
+ # Trigger actions
734
+ scope.trigger.single() # Single trigger
735
+ scope.trigger.force() # Force trigger
736
+ ```
737
+
738
+ ### Waveform Acquisition
739
+
740
+ ```python
741
+ # Acquire waveform
742
+ waveform = scope.get_waveform(channel=1)
743
+
744
+ # Access data
745
+ print(waveform.time) # Time array (numpy)
746
+ print(waveform.voltage) # Voltage array (numpy)
747
+ print(waveform.sample_rate)
748
+ print(waveform.record_length)
749
+
750
+ # Save waveform
751
+ scope.waveform.save_waveform(waveform, "data.csv", format="CSV")
752
+ ```
753
+
754
+ ### Measurements
755
+
756
+ ```python
757
+ # Individual measurements
758
+ freq = scope.measurement.measure_frequency(1)
759
+ vpp = scope.measurement.measure_vpp(1)
760
+ vrms = scope.measurement.measure_rms(1)
761
+ period = scope.measurement.measure_period(1)
762
+
763
+ # All measurements at once
764
+ measurements = scope.measurement.measure_all(1)
765
+ ```
766
+
767
+ ### Programmatic Data Collection & Automation
768
+
769
+ For advanced data collection workflows, use the high-level automation API:
770
+
771
+ ```python
772
+ from scpi_control.automation import DataCollector
773
+
774
+ # Simple capture with automatic analysis
775
+ with DataCollector('192.168.1.100') as collector:
776
+ # Capture waveforms
777
+ data = collector.capture_single([1, 2])
778
+
779
+ # Analyze waveform
780
+ stats = collector.analyze_waveform(data[1])
781
+ print(f"Vpp: {stats['vpp']:.3f}V, Freq: {stats['frequency']/1e3:.2f}kHz")
782
+
783
+ # Save to file (supports NPZ, CSV, MAT, HDF5)
784
+ collector.save_data(data, 'measurement.npz')
785
+ ```
786
+
787
+ **Batch capture with configuration sweeps:**
788
+
789
+ ```python
790
+ # Capture with different timebase and voltage settings
791
+ results = collector.batch_capture(
792
+ channels=[1],
793
+ timebase_scales=['1us', '10us', '100us'],
794
+ voltage_scales={1: ['500mV', '1V', '2V']},
795
+ triggers_per_config=5
796
+ )
797
+ collector.save_batch(results, 'batch_output')
798
+ ```
799
+
800
+ **Continuous time-series collection:**
801
+
802
+ ```python
803
+ # Collect data over time with automated file saving
804
+ collector.start_continuous_capture(
805
+ channels=[1, 2],
806
+ duration=300, # 5 minutes
807
+ interval=1.0, # 1 capture per second
808
+ output_dir='time_series_data',
809
+ file_format='npz'
810
+ )
811
+ ```
812
+
813
+ **Event-based trigger capture:**
814
+
815
+ ```python
816
+ from scpi_control.automation import TriggerWaitCollector
817
+
818
+ with TriggerWaitCollector('192.168.1.100') as tc:
819
+ # Configure trigger
820
+ tc.collector.scope.trigger.set_source(1)
821
+ tc.collector.scope.trigger.set_slope('POS')
822
+ tc.collector.scope.trigger.set_level(1, 1.0)
823
+
824
+ # Wait for trigger event
825
+ data = tc.wait_for_trigger(channels=[1, 2], max_wait=30.0)
826
+ ```
827
+
828
+ **Advanced analysis:**
829
+
830
+ ```python
831
+ # Built-in analysis includes: Vpp, RMS, frequency, SNR, THD, etc.
832
+ analysis = collector.analyze_waveform(waveform)
833
+ print(f"SNR: {analysis['snr_db']:.2f} dB")
834
+ print(f"THD: {analysis['thd_percent']:.2f}%")
835
+ ```
836
+
837
+ See `examples/` directory for complete automation examples including:
838
+
839
+ - Simple capture (`simple_capture.py`)
840
+ - Batch processing (`batch_capture.py`)
841
+ - Continuous monitoring (`continuous_capture.py`)
842
+ - Trigger-based capture (`trigger_based_capture.py`)
843
+ - Advanced analysis with visualization (`advanced_analysis.py`)
844
+
845
+ ## Examples
846
+
847
+ See the `examples/` directory for complete working examples:
848
+
849
+ - **basic_usage.py** - Connection and basic operations
850
+ - **waveform_capture.py** - Capture and save waveforms
851
+ - **measurements.py** - Automated measurements
852
+ - **live_plot.py** - Real-time plotting
853
+ - **probe_calibration_analysis.py** - Automated report generation with region extraction and AI analysis
854
+
855
+ ## Supported Models
856
+
857
+ ### Fully Tested
858
+
859
+ - **SDS800X HD Series**: SDS804X HD, SDS824X HD
860
+ - **SDS1000X-E Series**: SDS1102X-E, SDS1104X-E, SDS1202X-E, SDS1204X-E
861
+ - **SDS2000X Plus Series**: SDS2104X+, SDS2204X+, SDS2354X+
862
+ - **SDS5000X Series**: SDS5034X, SDS5054X, SDS5104X
863
+
864
+ ### Compatibility
865
+
866
+ Should work with other Siglent oscilloscopes that support SCPI commands over Ethernet. Model-specific features are auto-detected via the `ModelCapability` registry.
867
+
868
+ **Note**: Some SCPI commands vary between models. The library includes model-specific command variants for HD, X, and Plus series.
869
+
870
+ ## Contributing
871
+
872
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
873
+
874
+ - Development setup and workflow
875
+ - Code style and testing requirements
876
+ - Pull request process
877
+ - How to report bugs and request features
878
+
879
+ ### Quick Start for Contributors
880
+
881
+ ```bash
882
+ # Clone and setup
883
+ git clone https://github.com/little-did-I-know/SCPI-Instrument-Control.git
884
+ cd SCPI-Instrument-Control
885
+
886
+ # Install development environment
887
+ make dev-setup
888
+
889
+ # Run tests
890
+ make test
891
+
892
+ # Format code
893
+ make format
894
+
895
+ # Run all checks
896
+ make check
897
+ ```
898
+
899
+ See our [Code of Conduct](CODE_OF_CONDUCT.md) and [Security Policy](SECURITY.md) for more information.
900
+
901
+ ## Community and Support
902
+
903
+ - **Issues**: [Report bugs or request features](https://github.com/little-did-I-know/SCPI-Instrument-Control/issues)
904
+ - **Discussions**: [Ask questions and share ideas](https://github.com/little-did-I-know/SCPI-Instrument-Control/discussions)
905
+ - **Security**: See our [Security Policy](SECURITY.md) for reporting vulnerabilities
906
+
907
+ ## Resources
908
+
909
+ - ๐Ÿ“˜ **[Interactive Tutorial](examples/interactive_tutorial.ipynb)** - Jupyter notebook with step-by-step examples
910
+ - ๐Ÿ“ **[Examples Directory](examples/)** - Ready-to-run example scripts
911
+ - ๐Ÿ“– **[API Documentation](#api-documentation)** - Complete API reference in this README
912
+ - ๐Ÿ”ง **[Contributing Guide](CONTRIBUTING.md)** - How to contribute to the project
913
+ - ๐Ÿงช **[Experimental Features Guide](docs/development/EXPERIMENTAL_FEATURES.md)** - Beta releases and experimental features
914
+ - ๐Ÿ”’ **[Security Policy](SECURITY.md)** - Security best practices and reporting
915
+
916
+ ## License
917
+
918
+ MIT License - see [LICENSE](LICENSE) file for details
@@ -0,0 +1,7 @@
1
+ scpi_instrument_control-1.0.0.dist-info/licenses/LICENSE,sha256=i9ZSY6vVyVzmzmZ7rgpuiK3USZH5yJ2Q_FjbIFVa68w,1062
2
+ siglent/__init__.py,sha256=X6NuAX2EGc3YX3R-dBMyDkecUtfbPuBjM9lc__b9Wlc,1498
3
+ scpi_instrument_control-1.0.0.dist-info/METADATA,sha256=jrjLLwIJeFyr7Yr0mIqSmc3oSUZuLGHAIS4__3QNTok,31277
4
+ scpi_instrument_control-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ scpi_instrument_control-1.0.0.dist-info/entry_points.txt,sha256=eqPCEzf5od0P0ggwn0EESAURiCXZbu6AryayMfqCQyM,114
6
+ scpi_instrument_control-1.0.0.dist-info/top_level.txt,sha256=jqHtrzYuCmSomoCH6f2F5CqE-xRWeLlQ8FP-CDHchE4,8
7
+ scpi_instrument_control-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ siglent-gui = siglent.gui.app:main
3
+ siglent-report-generator = siglent.report_generator.app:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Robin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ siglent
siglent/__init__.py ADDED
@@ -0,0 +1,35 @@
1
+ """Backward compatibility module for the 'siglent' package name.
2
+
3
+ DEPRECATED: This module provides backward compatibility for code using 'import siglent'.
4
+
5
+ The package has been renamed to 'scpi_control' to better reflect its capabilities:
6
+ - SCPI Instrument Control (scpi_control) supports oscilloscopes, power supplies,
7
+ and function generators from Siglent and other SCPI-compatible manufacturers.
8
+
9
+ Migration Guide:
10
+ Old import (deprecated):
11
+ from siglent import Oscilloscope, PowerSupply, FunctionGenerator
12
+
13
+ New import (recommended):
14
+ from scpi_control import Oscilloscope, PowerSupply, FunctionGenerator
15
+
16
+ This compatibility module will be removed in v2.0.0.
17
+ For more information, see: https://github.com/little-did-I-know/SCPI-Instrument-Control
18
+ """
19
+
20
+ import warnings
21
+
22
+ warnings.warn(
23
+ "The 'siglent' package name is deprecated and will be removed in v2.0.0.\n"
24
+ "Please update your imports to use 'scpi_control' instead:\n\n"
25
+ " Old: from siglent import Oscilloscope, PowerSupply, FunctionGenerator\n"
26
+ " New: from scpi_control import Oscilloscope, PowerSupply, FunctionGenerator\n\n"
27
+ "PyPI package name: pip install SCPI-Instrument-Control\n"
28
+ "See migration guide: https://github.com/little-did-I-know/SCPI-Instrument-Control",
29
+ DeprecationWarning,
30
+ stacklevel=2,
31
+ )
32
+
33
+ # Re-export everything from the new package for backward compatibility
34
+ from scpi_control import * # noqa: F401, F403
35
+ from scpi_control import __version__, __all__ # noqa: F401