Skip to content

Commit 7e5a0b8

Browse files
committed
Port to PyVISA (deprecating scpi.py)
1 parent 31a6ae2 commit 7e5a0b8

1 file changed

Lines changed: 40 additions & 43 deletions

File tree

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,53 @@
11
""" Simple driver for Keithley 2182 Nanovolt Meter """
22
import time
3-
from PyExpLabSys.drivers.scpi import SCPI
43

4+
import pyvisa
55

6-
class Keithley2182(SCPI):
6+
7+
class Keithley2182:
78
"""
89
Simple driver for Keithley 2182 Nanovolt Meter
910
Actual implementation performed on a 2182a - please
1011
double check if you have a 2182.
1112
"""
1213

13-
def __init__(
14-
self, interface, hostname='', device='', baudrate=9600, gpib_address=None
15-
):
16-
self.interface = interface
17-
14+
def __init__(self, interface, hostname='', device='', baudrate=19200):
15+
rm = pyvisa.ResourceManager('@py')
1816
if interface == 'serial':
19-
SCPI.__init__(self, interface=interface, device=device, baudrate=baudrate)
20-
self.comm_dev.timeout = 2
21-
self.comm_dev.rtscts = False
22-
self.comm_dev.xonxoff = False
23-
if interface == 'gpib':
24-
SCPI.__init__(self, interface=interface, gpib_address=gpib_address)
25-
17+
conn_string = 'ASRL{}::INSTR'.format(device)
18+
self.instr = rm.open_resource(conn_string)
19+
self.instr.read_termination = '\r'
20+
self.instr.write_termination = '\r'
21+
self.instr.baud_rate = baudrate
2622
# For now, turn off continous trigger - this might need reconsideration
2723
# self.scpi_comm('INIT:CONT OFF')
2824

2925
def set_range(self, channel1: float = None, channel2: float = None):
3026
"""
3127
Set the measurement range of the device, 0 will indicate auto-range
3228
"""
29+
print('Set range of channel 1')
3330
if channel1 is not None:
3431
if channel1 > 120:
3532
channel1 = 120
3633
if channel1 == 0:
37-
self.scpi_comm(':SENSE:VOLT:CHANNEL1:RANGE:AUTO ON')
34+
self.instr.write(':SENSE:VOLT:CHANNEL1:RANGE:AUTO ON')
3835
else:
39-
self.scpi_comm(':SENSE:VOLT:CHANNEL1:RANGE {:.2f}'.format(channel1))
36+
self.instr.write(':SENSE:VOLT:CHANNEL1:RANGE {:.2f}'.format(channel1))
4037

4138
if channel2 is not None:
4239
if channel2 > 12:
4340
channel2 = 12
4441
if channel2 == 0:
45-
self.scpi_comm(':SENSE:VOLTAGE:CHANNEL2:RANGE:AUTO ON')
42+
self.instr.write(':SENSE:VOLTAGE:CHANNEL2:RANGE:AUTO ON')
4643
else:
47-
self.scpi_comm(':SENSE:VOLT:CHANNEL2:RANGE {:.2f}'.format(channel2))
48-
49-
actual_channel1_raw = self.scpi_comm(':SENSE:VOLTAGE:CHANNEL1:RANGE?')
50-
actual_channel2_raw = self.scpi_comm(':SENSE:VOLTAGE:CHANNEL2:RANGE?')
44+
self.instr.write(':SENSE:VOLT:CHANNEL2:RANGE {:.2f}'.format(channel2))
45+
print('Check the actual range')
46+
actual_channel1_raw = self.instr.query(':SENSE:VOLTAGE:CHANNEL1:RANGE?')
47+
actual_channel2_raw = self.instr.query(':SENSE:VOLTAGE:CHANNEL2:RANGE?')
5148
range1 = float(actual_channel1_raw)
5249
range2 = float(actual_channel2_raw)
50+
print('Value is: ', range1)
5351
return range1, range2
5452

5553
def set_integration_time(self, nplc: float = None):
@@ -61,9 +59,11 @@ def set_integration_time(self, nplc: float = None):
6159
nplc = 0.01
6260
if nplc > 60:
6361
nplc = 60
64-
self.scpi_comm('SENSE:VOLTAGE:NPLCYCLES {}'.format(nplc))
65-
time.sleep(nplc * 0.2)
66-
current_nplc = float(self.scpi_comm('SENSE:VOLTAGE:NPLCYCLES?'))
62+
self.instr.write('SENSE:VOLTAGE:NPLCYCLES {}'.format(nplc))
63+
# print('waiting....')
64+
time.sleep(nplc * 0.25)
65+
# print('done')
66+
current_nplc = float(self.instr.query('SENSE:VOLTAGE:NPLCYCLES?'))
6767
return current_nplc
6868

6969
def set_trigger_source(self, external):
@@ -73,17 +73,17 @@ def set_trigger_source(self, external):
7373
otherwise immediate triggering will be chosen.
7474
"""
7575
if external:
76-
self.scpi_comm(':TRIGGER:SOURCE External')
76+
self.instr.write(':TRIGGER:SOURCE External')
7777
else:
78-
self.scpi_comm(':TRIGGER:SOURCE Immediate')
78+
self.instr.write(':TRIGGER:SOURCE Immediate')
7979
return external
8080

8181
def read_fresh(self):
8282
"""
8383
Read a single value from current channel. This will also be a new value
8484
(or will fail if channel is not trigged.
8585
"""
86-
raw = self.scpi_comm(":DATA:FRESh?") # DF? also works
86+
raw = self.instr.query(':DATA:FRESh?') # DF? also works
8787
try:
8888
voltage = float(raw)
8989
except ValueError:
@@ -94,29 +94,26 @@ def read_voltage(self, channel: int):
9494
"""Read the measured voltage"""
9595
if channel not in (1, 2):
9696
return None
97-
self.scpi_comm(":SENSE:FUNC 'VOLT:DC'")
98-
self.scpi_comm(':SENSE:CHANNEL {}'.format(channel))
99-
raw = self.scpi_comm(':READ?')
97+
self.instr.write(":SENSE:FUNC 'VOLT:DC'")
98+
time.sleep(0.5)
99+
self.instr.write(':SENSE:CHANNEL {}'.format(channel))
100+
time.sleep(0.5)
101+
# raw = self.instr.query(':READ?')
102+
raw = self.read_fresh()
100103
voltage = float(raw)
101104
return voltage
102105

103106

104107
if __name__ == '__main__':
105-
GPIB = 7
108+
# usb-1a86_USB2.0-Ser_-if00-port0 # Vxx
109+
# usb-FTDI_Chipi-X_FT6EYK1T-if00-port0 # DMM
110+
# usb-FTDI_Chipi-X_FT6F1A7R-if00-port0 # Old gate
111+
# usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 # Vxy
106112
# NVM = Keithley2182(interface='gpib', gpib_address=GPIB)
107113
NVM = Keithley2182(
108114
interface='serial',
109-
device='/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0',
115+
device='/dev/serial/by-id/usb-1a86_USB2.0-Ser_-if00-port0',
110116
)
111117

112-
print(NVM.set_integration_time(50))
113-
exit()
114-
115-
print(NVM.set_range(1, 0.01))
116-
print(NVM.set_integration_time(10))
117-
print('Channel 1: {:.3f}uV'.format(NVM.read_voltage(1) * 1e6))
118-
119-
for i in range(0, 10):
120-
print()
121-
print('Channel 1: {:.3f}uV'.format(NVM.read_voltage(1) * 1e6))
122-
print('Channel 2: {:.3f}uV'.format(NVM.read_voltage(2) * 1e6))
118+
print(NVM.instr.query('*IDN?'))
119+
print(NVM.set_range(1, 0.1))

0 commit comments

Comments
 (0)