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.
- scpi_instrument_control-1.0.0.dist-info/METADATA +918 -0
- scpi_instrument_control-1.0.0.dist-info/RECORD +7 -0
- scpi_instrument_control-1.0.0.dist-info/WHEEL +5 -0
- scpi_instrument_control-1.0.0.dist-info/entry_points.txt +3 -0
- scpi_instrument_control-1.0.0.dist-info/licenses/LICENSE +21 -0
- scpi_instrument_control-1.0.0.dist-info/top_level.txt +1 -0
- siglent/__init__.py +35 -0
|
@@ -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
|
+
[](https://github.com/little-did-I-know/SCPI-Instrument-Control/actions/workflows/ci.yml)
|
|
96
|
+
[](https://codecov.io/gh/little-did-I-know/SCPI-Instrument-Control)
|
|
97
|
+
[](https://pypi.org/project/SCPI-Instrument-Control/)
|
|
98
|
+
[](https://pypi.org/project/SCPI-Instrument-Control/)
|
|
99
|
+
[](https://pypi.org/project/SCPI-Instrument-Control/)
|
|
100
|
+
[](https://opensource.org/licenses/MIT)
|
|
101
|
+
[](https://github.com/psf/black)
|
|
102
|
+
[](https://github.com/little-did-I-know/SCPI-Instrument-Control/issues)
|
|
103
|
+
[](https://github.com/little-did-I-know/SCPI-Instrument-Control/stargazers)
|
|
104
|
+
[](https://github.com/little-did-I-know/SCPI-Instrument-Control/commits/main)
|
|
105
|
+
[](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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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,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
|