diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/equipment_control/__pycache__/equipment.cpython-311.pyc b/equipment_control/__pycache__/equipment.cpython-311.pyc index 38619ad18dbf067ef14e2ca29461d31adc447a20..e5b530873ffb7280253d0bac3cf39f99c15f31b5 100644 Binary files a/equipment_control/__pycache__/equipment.cpython-311.pyc and b/equipment_control/__pycache__/equipment.cpython-311.pyc differ diff --git a/equipment_control/cm110.py b/equipment_control/cm110.py index b7eea32ec424d9222022f0907a54c8f2208d9efd..cef28925f784ed8a28a6b9b52c2d3a92c11bcf57 100644 --- a/equipment_control/cm110.py +++ b/equipment_control/cm110.py @@ -2,10 +2,42 @@ import equipment import pyvisa import time import numpy as np +import serial -class CM110(equipment.Equipment): +class cm110(equipment.equipment): """Class to control CM110 monochromator""" model="CM110" company="Spectral Product" link="https://www.spectralproducts.com/CM110" + + def __init__(self,port): + self.serial_resource = serial.Serial( + port='COM5', + baudrate=9600, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS + ) + + + def initialize(self,grating_number=1,waiting_time=30): + reset=[255,255,255] + + self.serial_resource.write(serial.to_bytes([26,grating_number])) + time.sleep(waiting_time) + self.serial_resource.write(serial.to_bytes(reset)) + time.sleep(waiting_time) + + def set_wavelength(self, wavelength,waiting_time=10): + set_position = [16,int((wavelength-wavelength%256)/256),wavelength%256] # Goto Position : 1000 -> 0x3E8 -> 3 and 232 + self.serial_resource.write(serial.to_bytes(set_position)) + time.sleep(waiting_time) + + def close_connection(self): + self.serial_resource.close() + + + + + \ No newline at end of file diff --git a/equipment_control/dmm.py b/equipment_control/dmm.py index b734264a8277ebbe8690c88b91c20b9e24c02311..f4600f12edf1ace071d296f3fc107ae313072847 100644 --- a/equipment_control/dmm.py +++ b/equipment_control/dmm.py @@ -1,11 +1,50 @@ import equipment -import pyvisa -import time -import numpy as np -class DMM(equipment.Equipment): +class dmm(equipment.equipment): """Class to control DMM multimeter""" model="DMM7510, DMM6500 or K2000" company="Keithley" - link="https://www.tek.com/en/products/keithley/benchtop-digital-multimeter" + url="https://www.tek.com/en/products/keithley/benchtop-digital-multimeter" + + def initialize(self, mode, autozero=True, offset_compensation=True, nplc=1): + """ + mode: + - "voltage": voltage measurement + - "current": current measurement + - "resistance": resistance measurement + - "4 wires": 4 wires measurement + """ + self.pyvisa_resource.write("*RST") + + if mode=="voltage": + self.pyvisa_resource.write(":SENS:FUNC 'VOLT'") + elif mode=="current": + self.pyvisa_resource.write(":SENS:FUNC 'CURR'") + elif mode=="resistance": + self.pyvisa_resource.write(":SENS:FUNC 'RES'") + elif mode=="4 wires": + self.pyvisa_resource.write(":SENS:FUNC 'FRES'") + + + self.pyvisa_resource.write(":SENS:FRES:RANG:AUTO ON") # set automatic range + self.pyvisa_resource.write(":DISP:DIG MAX") # Query largest allowable display resolutio + self.pyvisa_resource.write(":DISP:ENAB ON") # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed. + self.pyvisa_resource.write("INIT:CONT ON") # able continuous triggering + + if offset_compensation: + self.pyvisa_resource.write(":SENS:FRES:OCOM ON") # enable offset compensation + else: + self.pyvisa_resource.write(":SENS:FRES:OCOM OFF") + + if autozero: + self.pyvisa_resource.write(":SENS:FRES:AZER ON") # enable auto-zero + else: + self.pyvisa_resource.write(":SENS:FRES:AZER OFF") + + self.pyvisa_resource.write(":SENS:FRES:NPLC %d"%nplc) # set NPLC. For a PLC of 1, the integration period would be 1/50 (for 50Hz line power) which is 20 msec + + + def read_single(self): + data=self.pyvisa_resource.query("READ?") + return float(data) diff --git a/equipment_control/equipment.py b/equipment_control/equipment.py index 098c86cf952e98ad0a32fd69fb3c517198807561..b4f3c458d6c1065e68997a5ee580250f2ad781fa 100644 --- a/equipment_control/equipment.py +++ b/equipment_control/equipment.py @@ -1,15 +1,27 @@ import pyvisa import datetime import numpy as np -class Equipment(pyvisa.ResourceManager): + + +def available_connections(): + rm = pyvisa.ResourceManager() + return rm.list_resources() + +def resource_manager(): + rm = pyvisa.ResourceManager() + return rm + +class equipment(pyvisa.ResourceManager): """Base for Equipment classes.""" model = "" company = "" - link = "" + url = "" - def __init__(self,rm,address): + def __init__(self,address,rm=None): + if rm==None: + rm = pyvisa.ResourceManager() self.pyvisa_resource = rm.open_resource(address) diff --git a/equipment_control/hp4145.py b/equipment_control/hp4145.py index eebc0373b1d2fe846cd5e94dfc53023a17484a1f..66229aae4988a961e18fac6e853672a5a54c2ed7 100644 --- a/equipment_control/hp4145.py +++ b/equipment_control/hp4145.py @@ -3,14 +3,14 @@ import pyvisa import time import numpy as np -class HP4145(equipment.Equipment): +class hp4145(equipment.equipment): """Class to control HP4145 semiconductor analyzer""" model="HP4145" company="Keysight" - link="https://www.keysight.com/dk/en/assets/9018-07935/service-manuals/9018-07935.pdf" + url="https://www.keysight.com/dk/en/assets/9018-07935/service-manuals/9018-07935.pdf" - def initialize_sweep(self, mode="voltage sweep",number_channel=4,smu_bias={"SMU2":0,"SMU3":0,"SMU4":0}, + def initialize(self, mode="voltage sweep",number_channel=4,smu_bias={"SMU2":0,"SMU3":0,"SMU4":0}, smu_compliance={"SMU1":1e-6,"SMU2":1e-6,"SMU3":1e-6,"SMU4":1e-6},sweep_param={"start":0,"stop":0,"step":0}, integration_mode="IT1",delay_time=0,hold_time=0): diff --git a/equipment_control/k24xx.py b/equipment_control/k24xx.py index 1126aa967b1d8497692ec3ff118f83e6bef3b8e8..6ee66c007e3ee728148ee259703ae34885fd6edc 100644 --- a/equipment_control/k24xx.py +++ b/equipment_control/k24xx.py @@ -1,11 +1,86 @@ import equipment -import pyvisa -import time -import numpy as np -class K24XX(equipment.Equipment): +class k24XX(equipment.equipment): """Class to control K2400 or k2450 SMU""" model="K2400 or K2450" company="Keithley" - link="https://www.tek.com/en/products/keithley/digital-multimeter/dmm7510" + url="https://www.tek.com/en/products/keithley/digital-multimeter/dmm7510" + + + def initialize(self, source_mode,measurement_mode, compliance, autozero=True, offset_compensation=True, nplc=1): + + """ + source_mode: + - "voltage": voltage source + - "current": current source + measurement_mode: + - "voltage": voltage measurement + - "current": current measurement + - "resistance": resistance measurement + - "4 wires": 4 wires measurement + """ + + self.pyvisa_resource.write("*RST") + self.source_mode=source_mode + + if source_mode=="voltage": + self.pyvisa_resource.write(":SOUR:FUNC 'VOLT'") + self.pyvisa_resource.write(":SOUR:CURR:VLIM %f"%compliance) # set automatic range + + if source_mode=="current": + self.pyvisa_resource.write(":SOUR:FUNC 'CURR'") + self.pyvisa_resource.write(":SOUR:VOLT:CLIM %f"%compliance) # set automatic range + + + + if measurement_mode=="voltage": + self.pyvisa_resource.write(":SENS:FUNC 'VOLT'") + self.pyvisa_resource.write(":SENS:VOLT:RANG:AUTO ON") # set automatic range + + elif measurement_mode=="current": + self.pyvisa_resource.write(":SENS:FUNC 'CURR'") + self.pyvisa_resource.write(":SENS:CURR:RANG:AUTO ON") # set automatic range + + elif measurement_mode=="resistance": + self.pyvisa_resource.write(":SENS:FUNC 'RES'") + self.pyvisa_resource.write(":SENS:RES:RANG:AUTO ON") # set automatic range + + elif measurement_mode=="4 wires": + self.pyvisa_resource.write(":SENS:FUNC 'FRES'") + self.pyvisa_resource.write(":SENS:FRES:RANG:AUTO ON") # set automatic range + + + + self.pyvisa_resource.write(":DISP:DIG MAX") # Query largest allowable display resolutio + self.pyvisa_resource.write(":DISP:ENAB ON") # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed. + self.pyvisa_resource.write("INIT:CONT ON") # able continuous triggering + + if offset_compensation: + self.pyvisa_resource.write(":SENS:FRES:OCOM ON") # enable offset compensation + else: + self.pyvisa_resource.write(":SENS:FRES:OCOM OFF") + + if autozero: + self.pyvisa_resource.write(":SENS:FRES:AZER ON") # enable auto-zero + else: + self.pyvisa_resource.write(":SENS:FRES:AZER OFF") + + self.pyvisa_resource.write(":SENS:FRES:NPLC %.1f"%nplc) # set NPLC. For a PLC of 1, the integration period would be 1/50 (for 50Hz line power) which is 20 msec + + + def read_single(self): + data=self.pyvisa_resource.query("READ?") + return float(data) + + def set_source(self,value): + if self.source_mode=="current": + self.pyvisa_resource.write(":SOUR:CURR %.2E"%value) #set output voltage + elif self.source_mode=="voltage": + self.pyvisa_resource.write(":SOUR:VOLT %.2E"%value) #set output voltage + + + def set_output(self,output_state="ON"): + self.pyvisa_resource.write(":OUTP %s"%output_state) + + diff --git a/equipment_control/k4200.py b/equipment_control/k4200.py index c590bfd8c59df121ae73b577b04902c88f883af2..351a51cacdd1d02692d1986ef00fc2a17d7844fa 100644 --- a/equipment_control/k4200.py +++ b/equipment_control/k4200.py @@ -3,14 +3,14 @@ import pyvisa import time import numpy as np -class K4200(equipment.Equipment): +class k4200(equipment.equipment): """Class to control HP4145 semiconductor analyzer""" model="K4200" company="Keysight" - link="https://www.tek.com/en/products/keithley/4200a-scs-parameter-analyzer" + url="https://www.tek.com/en/products/keithley/4200a-scs-parameter-analyzer" - def initialize_sweep(self, mode="voltage sweep",number_channel=4,smu_bias={"SMU2":0,"SMU3":0,"SMU4":0}, + def initialize(self, mode="voltage sweep",number_channel=4,smu_bias={"SMU2":0,"SMU3":0,"SMU4":0}, smu_compliance={"SMU1":1e-6,"SMU2":1e-6,"SMU3":1e-6,"SMU4":1e-6},sweep_param={"start":0,"stop":0,"step":0}, integration_mode="IT1",delay_time=0,hold_time=0): diff --git a/equipment_control/script_template.py b/equipment_control/script_template.py new file mode 100644 index 0000000000000000000000000000000000000000..41b9f5646139e587c33c33bc23d56895affc2877 --- /dev/null +++ b/equipment_control/script_template.py @@ -0,0 +1,53 @@ + + +# ============================================================================= +# 1. Import classes and modules +# ============================================================================= + +import sys +#sys.path.insert(1, '/path/to/application/app/folder') +sys.path.insert(1, 'D:/Roisin/Documents/chopes') + +import equipment_control.equipment as eq +import equipment_control.EQUIPMENT_TYPE as EQ_TYPE + + +# ============================================================================= +# 2. List available connections (chopes use pyvisa package for communicate with most equipments) +# ============================================================================= +rm=eq.resource_manager() +list_connections= eq.available_connections() +print("Available connections: %s"%str(list_connections)) + +# ============================================================================= +# 3. Connection to the equipments +# ============================================================================= +myEQUIPMENT=EQ_TYPE.EQUIPMENT_TYPE() + +# ============================================================================= +# 4. Measurement parameters +# ============================================================================= +FILE_PATH='/path/to/data/folder' +PARAM_INIT=??? +PARAM_OPERATION=??? + +# ============================================================================= +# 5. Initialization of the equipments +# ============================================================================= +myEQUIPMENT.initialize(PARAM_INIT) + +# ============================================================================= +# 6. Measurement script +# ============================================================================= +myEQUIPMENT.set_PARAM(PARAM_OPERATION) +DATA=myEQUIPMENT.read_data() + +# ============================================================================= +# 7. Close connection +# ============================================================================= +myEQUIPMENT.close_connection() + +# ============================================================================= +# 8. Save data +# ============================================================================= +myEQUIPMENT.write_in_file(FILE_PATH,DATA) diff --git a/equipment_control/sh242.py b/equipment_control/sh242.py new file mode 100644 index 0000000000000000000000000000000000000000..71df43646268dc63cdc0a52eccdfebb6152e0e0d --- /dev/null +++ b/equipment_control/sh242.py @@ -0,0 +1,127 @@ +import equipment +import time +import numpy as np + +class sh242(equipment.equipment): + + """Class to control SH242 climatic chamber""" + model="SH242" + company="ESPEC" + url="https://espec.com/na/products/model/sh_242" + +# ============================================================================= +# mysh242.read_termination = ';' +# mysh242.write_termination = ';' +# mysh242.timeout=300*1000 +# ============================================================================= + + + + def initialize(self,temperature=True, humidity=False,temperature_dic={"upper":125,"lower":-45,"set":20},humidity_dic={"upper":100,"lower":0,"set":55}): + self.pyvisa_resource.write('POWER, ON') + time.sleep(1) + self.pyvisa_resource.read() + self.pyvisa_resource.write('POWER, CONSTANT') + time.sleep(10) + self.pyvisa_resource.read() + + if temperature: + self.pyvisa_resource.write("TEMP, L%.2f"%temperature_dic["upper"]) #Changes the temperature lower absolute alarm value in constant setup + time.sleep(1) + self.pyvisa_resource.read() + self.pyvisa_resource.write("TEMP, H%.2f"%temperature_dic["lower"]) #Changes the temperature upper absolute alarm value in constant setup + time.sleep(1) + self.pyvisa_resource.read() + self.pyvisa_resource.write("TEMP, S%.2f"%temperature_dic["set"]) #Changes the temperature set point in constant setup + time.sleep(1) + self.pyvisa_resource.read() + else: + self.pyvisa_resource.write("TEMP, SOFF") # disable temperature + time.sleep(1) + self.pyvisa_resource.read() + + + if humidity: + self.pyvisa_resource.write("HUMI, L%.2f"%humidity_dic["upper"]) #Changes the temperature lower absolute alarm value in constant setup + time.sleep(1) + self.pyvisa_resource.read() + self.pyvisa_resource.write("HUMI, H%.2f"%humidity_dic["lower"]) #Changes the temperature upper absolute alarm value in constant setup + time.sleep(1) + self.pyvisa_resource.read() + self.pyvisa_resource.write("HUMI, S%.2f"%humidity_dic["set"]) #Changes the temperature set point in constant setup + time.sleep(1) + self.pyvisa_resource.read() + else: + self.pyvisa_resource.write("HUMI, SOFF") # disable temperature + time.sleep(1) + self.pyvisa_resource.read() + + def read_temperature(self): + self.pyvisa_resource.write('TEMP?') + time.sleep(0.5) + temperature=self.pyvisa_resource.read() + return temperature + + def read_humidity(self): + self.pyvisa_resource.write('HUMI?') + time.sleep(0.5) + humidity=self.pyvisa_resource.read() + return humidity + + + def set_temperature(self,temperature,waiting_time=0,wait_for_stabilization=False,stabilization_tolerance=0.1,stabilization_number=10): + self.pyvisa_resource.write("TEMP, S%.2f"%temperature) #Changes the temperature set point in constant setup + time.sleep(1) + self.pyvisa_resource.read() + time.sleep(waiting_time) + + if wait_for_stabilization: + temperature_stabilized=False + stabilization_count=0 + + while temperature_stabilized==False: + self.pyvisa_resource.write("TEMP?") + time.sleep(5) + temperature_read=np.round(float(self.pyvisa_resource.read().split(",")[0]),1) + if abs(temperature_read-temperature)<stabilization_tolerance: + stabilization_count+=1 + if stabilization_count==stabilization_number: + temperature_stabilized=True + else: + stabilization_count=0 + + + def set_humidity(self,humidity,waiting_time=0,wait_for_stabilization=False,stabilization_tolerance=0.5,stabilization_number=1): + self.pyvisa_resource.write("HUMI, S%.2f"%humidity) #Changes the temperature set point in constant setup + time.sleep(1) + self.pyvisa_resource.read() + time.sleep(waiting_time) + + if wait_for_stabilization: + humidity_stabilized=False + stabilization_count=0 + + while humidity_stabilized==False: + self.pyvisa_resource.write("HUMI?") + time.sleep(5) + humidity_read=np.round(float(self.pyvisa_resource.read().split(",")[0]),1) + if abs(humidity_read-humidity)<stabilization_tolerance: + stabilization_count+=1 + if stabilization_count==stabilization_number: + humidity_stabilized=True + else: + stabilization_count=0 + + + + + + + + + + + + + + \ No newline at end of file