From ec351b13b2970c6ec0efb99b3e0a3e94de1fe1ea Mon Sep 17 00:00:00 2001
From: Nicolas Roisin <nicolas.roisin@uclouvain.be>
Date: Wed, 26 Feb 2025 14:14:20 +0100
Subject: [PATCH] equipment_control script and classes

---
 __init__.py                                   |   0
 .../__pycache__/equipment.cpython-311.pyc     | Bin 2220 -> 3747 bytes
 equipment_control/cm110.py                    |  34 ++++-
 equipment_control/dmm.py                      |  49 ++++++-
 equipment_control/equipment.py                |  18 ++-
 equipment_control/hp4145.py                   |   6 +-
 equipment_control/k24xx.py                    |  85 +++++++++++-
 equipment_control/k4200.py                    |   6 +-
 equipment_control/script_template.py          |  53 ++++++++
 equipment_control/sh242.py                    | 127 ++++++++++++++++++
 10 files changed, 358 insertions(+), 20 deletions(-)
 create mode 100644 __init__.py
 create mode 100644 equipment_control/script_template.py
 create mode 100644 equipment_control/sh242.py

diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/equipment_control/__pycache__/equipment.cpython-311.pyc b/equipment_control/__pycache__/equipment.cpython-311.pyc
index 38619ad18dbf067ef14e2ca29461d31adc447a20..e5b530873ffb7280253d0bac3cf39f99c15f31b5 100644
GIT binary patch
literal 3747
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
H%BJ#POI9{4

delta 713
zcmZvZzi-n(6vyw*=Qt%e=`SEae*{n?xd>QF5fyYmiP$nw38X5L75NTi>e%7VE}}3L
z#K1^(0}D(@pbECmls|!m0r?L=>O@ePDhBS^O)CM<^2fUO-uL}Dzn%OzQhsmSN07El
zpFiD8%#CvO&YV8ILJTn+pk+kRO~lA^#0-w^W5@)1XCU-Jzqu_FhL?~-ci`Ca_PyC>
zpxB*P+xUv5vx@0ZQxWpm*u*XMjLe=-iRh+QhcUsWlu)!*tL<HFEVOS$zVyR(Bl40i
z4`bO@^SC}$bX`C6W7l09Z9Yi+9)vCqd?odr)X6T|DjRcnVMrGfBY;uB7+@T5Ov5n*
zY@Qk`{84JIc7lWtx(i!9q0_jjUehzUqPFQ9T-j=yC-IFcD9oPl!`Pv@e%y<~kbAKo
zg>J7SI$a)fA&x_v6B?3g=#6T^2JM7;N~`Kip^#TMUFLfe>UZIx?h{+Lmn@y+5CM~?
zrWZt#J2>kj;VSow3}*rNu<_cd!>jl^Hlrqsb*rM)EvKY@99_Ij13z35W$h8LkC+CW
z)!0M=^0G+<%$)&#iR9|8Jw;3QdPBXiua6;Y&h!Df0CG2WPOs*oSx_Dn+ACh`Ml1>V
pqPU;~u!d}E^bL&hH)OA8PoJK{y5hfhS@=3!{|SL#|A}U8{s7!Lq$2<T

diff --git a/equipment_control/cm110.py b/equipment_control/cm110.py
index b7eea32..cef2892 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 b734264..f4600f1 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 098c86c..b4f3c45 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 eebc037..66229aa 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 1126aa9..6ee66c0 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 c590bfd..351a51c 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 0000000..41b9f56
--- /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 0000000..71df436
--- /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
-- 
GitLab