visa-instrument-drivers 0.1.0__tar.gz
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.
Potentially problematic release.
This version of visa-instrument-drivers might be problematic. Click here for more details.
- visa_instrument_drivers-0.1.0/.gitignore +7 -0
- visa_instrument_drivers-0.1.0/LICENSE +0 -0
- visa_instrument_drivers-0.1.0/PKG-INFO +33 -0
- visa_instrument_drivers-0.1.0/README.md +12 -0
- visa_instrument_drivers-0.1.0/pyproject.toml +41 -0
- visa_instrument_drivers-0.1.0/src/visa_instrument_drivers/__init__.py +3 -0
- visa_instrument_drivers-0.1.0/src/visa_instrument_drivers/rigol_dp800.py +50 -0
- visa_instrument_drivers-0.1.0/src/visa_instrument_drivers/rigol_mso5000.py +108 -0
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: visa-instrument-drivers
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tiny, pragmatic VISA instrument drivers on top of PyVISA.
|
|
5
|
+
Project-URL: Homepage, https://github.com/yourname/visa-instrument-drivers
|
|
6
|
+
Project-URL: Issues, https://github.com/yourname/visa-instrument-drivers/issues
|
|
7
|
+
Author-email: Your Name <you@example.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: PyVISA,SCPI,VISA,automation,instruments,rigol
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Requires-Dist: pyvisa>=1.13
|
|
18
|
+
Provides-Extra: backends
|
|
19
|
+
Requires-Dist: pyvisa-py>=0.7; extra == 'backends'
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# visa-instrument-drivers
|
|
23
|
+
|
|
24
|
+
Tiny, pragmatic VISA instrument drivers built on PyVISA.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from visa_instrument_drivers import RigolDP800
|
|
28
|
+
|
|
29
|
+
psu = RigolDP800("DP832A")
|
|
30
|
+
psu.connect("TCPIP::192.168.0.107::INSTR")
|
|
31
|
+
psu.write_source_voltage(13.5) # CH1
|
|
32
|
+
print(psu.read_source_voltage()) # 13.5 (setpoint)
|
|
33
|
+
psu.disconnect()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# visa-instrument-drivers
|
|
2
|
+
|
|
3
|
+
Tiny, pragmatic VISA instrument drivers built on PyVISA.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from visa_instrument_drivers import RigolDP800
|
|
7
|
+
|
|
8
|
+
psu = RigolDP800("DP832A")
|
|
9
|
+
psu.connect("TCPIP::192.168.0.107::INSTR")
|
|
10
|
+
psu.write_source_voltage(13.5) # CH1
|
|
11
|
+
print(psu.read_source_voltage()) # 13.5 (setpoint)
|
|
12
|
+
psu.disconnect()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.25"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "visa-instrument-drivers" # 👇 The PyPI name
|
|
7
|
+
version = "0.1.0" # 👇 Bump each release
|
|
8
|
+
description = "Tiny, pragmatic VISA instrument drivers on top of PyVISA."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Your Name", email = "you@example.com" } # 👇
|
|
14
|
+
]
|
|
15
|
+
keywords = ["VISA", "SCPI", "PyVISA", "instruments", "automation", "rigol"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Topic :: Scientific/Engineering",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
# Core runtime deps
|
|
25
|
+
dependencies = [
|
|
26
|
+
"pyvisa>=1.13",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
# For users who want a pure-Python backend (no NI-VISA)
|
|
31
|
+
backends = ["pyvisa-py>=0.7"]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/yourname/visa-instrument-drivers" # 👇
|
|
35
|
+
Issues = "https://github.com/yourname/visa-instrument-drivers/issues"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.sdist]
|
|
38
|
+
include = ["src", "README.md", "LICENSE", "pyproject.toml"]
|
|
39
|
+
|
|
40
|
+
[tool.hatch.build.targets.wheel]
|
|
41
|
+
packages = ["src/visa_instrument_drivers"]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
import pyvisa
|
|
3
|
+
|
|
4
|
+
class Channel(Enum):
|
|
5
|
+
CH1 = 1
|
|
6
|
+
CH2 = 2
|
|
7
|
+
CH3 = 3
|
|
8
|
+
|
|
9
|
+
class OutputState(Enum):
|
|
10
|
+
OFF = 0
|
|
11
|
+
ON = 1
|
|
12
|
+
|
|
13
|
+
class RigolDP800:
|
|
14
|
+
|
|
15
|
+
def __init__(self, instr: pyvisa.Resource):
|
|
16
|
+
self.instr = instr
|
|
17
|
+
return
|
|
18
|
+
|
|
19
|
+
def query_source_current_level_immediate_amplitude(self, channel: Channel) -> float:
|
|
20
|
+
msg = f":SOUR{channel.value}:CURR?"
|
|
21
|
+
resp = self.instr.query(msg)
|
|
22
|
+
level = float(resp.strip())
|
|
23
|
+
return level
|
|
24
|
+
|
|
25
|
+
def write_source_current_level_immediate_amplitude(self, channel: Channel, level: float):
|
|
26
|
+
msg = f":SOUR{channel.value}:CURR {level}"
|
|
27
|
+
self.instr.write(msg)
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
def query_source_voltage_level_immediate_amplitude(self, channel: Channel) -> float:
|
|
31
|
+
msg = f":SOUR{channel.value}:VOLT?"
|
|
32
|
+
resp = self.instr.query(msg)
|
|
33
|
+
level = float(resp.strip())
|
|
34
|
+
return level
|
|
35
|
+
|
|
36
|
+
def write_source_voltage_level_immediate_amplitude(self, channel: Channel, level: float):
|
|
37
|
+
msg = f":SOUR{channel.value}:VOLT {level}"
|
|
38
|
+
self.instr.write(msg)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
def query_output_state(self, channel: Channel) -> OutputState:
|
|
42
|
+
msg = f":OUTP:STAT? {channel.name}"
|
|
43
|
+
resp = self.instr.query(msg)
|
|
44
|
+
output_state = resp.strip()
|
|
45
|
+
return OutputState(output_state)
|
|
46
|
+
|
|
47
|
+
def write_output_state(self, channel: Channel, state: OutputState):
|
|
48
|
+
msg = f":OUTP:STAT {channel.name},{state.name}"
|
|
49
|
+
self.instr.write(msg)
|
|
50
|
+
return
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
import pyvisa
|
|
3
|
+
|
|
4
|
+
class Channel(Enum):
|
|
5
|
+
CH1 = 1
|
|
6
|
+
CH2 = 2
|
|
7
|
+
CH3 = 3
|
|
8
|
+
CH4 = 4
|
|
9
|
+
|
|
10
|
+
class DisplayState(Enum):
|
|
11
|
+
OFF = 0
|
|
12
|
+
ON = 1
|
|
13
|
+
|
|
14
|
+
class AttenuationRatio(Enum):
|
|
15
|
+
AR100u = 0.0001
|
|
16
|
+
AR200u = 0.0002
|
|
17
|
+
AR500u = 0.0005
|
|
18
|
+
AR1m = 0.001
|
|
19
|
+
AR2m = 0.002
|
|
20
|
+
AR5m = 0.005
|
|
21
|
+
AR10m = 0.01
|
|
22
|
+
AR20m = 0.02
|
|
23
|
+
AR50m = 0.05
|
|
24
|
+
AR100m = 0.1
|
|
25
|
+
AR200m = 0.2
|
|
26
|
+
AR500m = 0.5
|
|
27
|
+
AR1 = 1
|
|
28
|
+
AR2 = 2
|
|
29
|
+
AR5 = 5
|
|
30
|
+
AR10 = 10
|
|
31
|
+
AR20 = 20
|
|
32
|
+
AR50 = 50
|
|
33
|
+
AR100 = 100
|
|
34
|
+
AR200 = 200
|
|
35
|
+
AR500 = 500
|
|
36
|
+
AR1000 = 1000
|
|
37
|
+
AR2000 = 2000
|
|
38
|
+
AR5000 = 5000
|
|
39
|
+
AR10000 = 10000
|
|
40
|
+
AR20000 = 20000
|
|
41
|
+
AR50000 = 50000
|
|
42
|
+
|
|
43
|
+
class Units(Enum):
|
|
44
|
+
AMP = 'AMP'
|
|
45
|
+
UNKN = 'UNKN'
|
|
46
|
+
VOLT = 'VOLT'
|
|
47
|
+
WATT = 'WATT'
|
|
48
|
+
|
|
49
|
+
class RigolMSO5000:
|
|
50
|
+
|
|
51
|
+
def __init__(self, instr: pyvisa.Resource):
|
|
52
|
+
self.instr = instr
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
def query_channel_offset(self, channel: Channel) -> float:
|
|
56
|
+
msg = f":CHAN{channel.value}:OFFS?"
|
|
57
|
+
resp = self.instr.query(msg)
|
|
58
|
+
level = float(resp.strip())
|
|
59
|
+
return level
|
|
60
|
+
|
|
61
|
+
def write_channel_offset(self, channel: Channel, offset: float):
|
|
62
|
+
msg = f":CHAN{channel.value}:OFFS {offset}"
|
|
63
|
+
self.instr.write(msg)
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
def query_channel_scale(self, channel: Channel) -> float:
|
|
67
|
+
msg = f":CHAN{channel.value}:SCAL?"
|
|
68
|
+
resp = self.instr.query(msg)
|
|
69
|
+
level = float(resp.strip())
|
|
70
|
+
return level
|
|
71
|
+
|
|
72
|
+
def write_channel_scale(self, channel: Channel, scale: float):
|
|
73
|
+
msg = f":CHAN{channel.value}:SCAL {scale}"
|
|
74
|
+
self.instr.write(msg)
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
def query_channel_probe(self, channel: Channel) -> AttenuationRatio:
|
|
78
|
+
msg = f":CHAN{channel.value}:PROB?"
|
|
79
|
+
resp = self.instr.query(msg)
|
|
80
|
+
level = float(resp.strip())
|
|
81
|
+
return AttenuationRatio(level)
|
|
82
|
+
|
|
83
|
+
def write_channel_probe(self, channel: Channel, attenuation: AttenuationRatio):
|
|
84
|
+
msg = f":CHAN{channel.value}:PROB {attenuation}"
|
|
85
|
+
self.instr.write(msg)
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
def query_channel_display(self, channel: Channel) -> DisplayState:
|
|
89
|
+
msg = f":CHAN{channel.value}:DISP?"
|
|
90
|
+
resp = self.instr.query(msg)
|
|
91
|
+
state = resp.strip()
|
|
92
|
+
return DisplayState(state)
|
|
93
|
+
|
|
94
|
+
def write_channel_display(self, channel: Channel, state: DisplayState):
|
|
95
|
+
msg = f":CHAN{channel.value}:DISP {state.name}?"
|
|
96
|
+
self.instr.write(msg)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
def query_channel_units(self, channel: Channel) -> Units:
|
|
100
|
+
msg = f":CHAN{channel.value}:UNIT?"
|
|
101
|
+
resp = self.instr.query(msg)
|
|
102
|
+
units = resp.strip()
|
|
103
|
+
return Units(units)
|
|
104
|
+
|
|
105
|
+
def write_channel_units(self, channel: Channel, units: Units):
|
|
106
|
+
msg = f":CHAN{channel.value}:UNIT {units.value}?"
|
|
107
|
+
self.instr.write(msg)
|
|
108
|
+
return
|