11""" Simple driver for Keithley 2182 Nanovolt Meter """
22import 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
104107if __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