diff --git a/equipment_control/__pycache__/dmm.cpython-311.pyc b/equipment_control/__pycache__/dmm.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..84320a1ca1f6ef1565659367e52e192a271cd3f3
Binary files /dev/null and b/equipment_control/__pycache__/dmm.cpython-311.pyc differ
diff --git a/equipment_control/__pycache__/equipment.cpython-311.pyc b/equipment_control/__pycache__/equipment.cpython-311.pyc
index 656e109941a4e89daec1764462b956ead1dce9bd..83a47f5dd9896150bb92f4f2dfbbd2fe940651ea 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/__pycache__/hp4145.cpython-311.pyc b/equipment_control/__pycache__/hp4145.cpython-311.pyc
index 7427a598aa61f7d6a06b6b5568801b2db1caeeb2..dfc03a98e1bb6f4e1aab97330c3c072f6662cf7c 100644
Binary files a/equipment_control/__pycache__/hp4145.cpython-311.pyc and b/equipment_control/__pycache__/hp4145.cpython-311.pyc differ
diff --git a/equipment_control/__pycache__/k2450.cpython-311.pyc b/equipment_control/__pycache__/k2450.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4ada50c438bcb1a1c83e32da6e9062b025e7e93d
Binary files /dev/null and b/equipment_control/__pycache__/k2450.cpython-311.pyc differ
diff --git a/equipment_control/__pycache__/k24xx.cpython-311.pyc b/equipment_control/__pycache__/k24xx.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d0615ce1d658c1ad7ba226efdc9ea220aa3ca7b2
Binary files /dev/null and b/equipment_control/__pycache__/k24xx.cpython-311.pyc differ
diff --git a/equipment_control/__pycache__/k4200.cpython-311.pyc b/equipment_control/__pycache__/k4200.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a7bcbb2bba58af1122ba628d6589d291c2e97780
Binary files /dev/null and b/equipment_control/__pycache__/k4200.cpython-311.pyc differ
diff --git a/equipment_control/cm110.py b/equipment_control/cm110.py
index 8658953f32c981bde4bcb138bfd2d668bbe6e93f..3c10e61a006374dc7207fc24288ec5c2bbe43fe3 100644
--- a/equipment_control/cm110.py
+++ b/equipment_control/cm110.py
@@ -7,11 +7,11 @@ class cm110(equipment.equipment):
     """Class to control CM110 monochromator"""
     model="CM110"
     company="Spectral Product"
-    link="https://www.spectralproducts.com/CM110"
+    url="https://www.spectralproducts.com/CM110"
 
     def __init__(self,port):
         self.serial_resource = serial.Serial(
-            port='COM5',
+            port=port,
             baudrate=9600,
             parity=serial.PARITY_NONE,
             stopbits=serial.STOPBITS_ONE,
diff --git a/equipment_control/dmm.py b/equipment_control/dmm.py
index 7444a6e546c2627dbc82c3447a744bd2e304f393..62256bd1b223e4abc8549f795552b21ade9ca0b3 100644
--- a/equipment_control/dmm.py
+++ b/equipment_control/dmm.py
@@ -1,4 +1,5 @@
 import equipment_control.equipment as equipment
+import time
 
 class dmm(equipment.equipment):
     
@@ -7,45 +8,78 @@ class dmm(equipment.equipment):
     company="Keithley"
     url="https://www.tek.com/en/products/keithley/benchtop-digital-multimeter"
 
-    def initialize(self, mode, autozero=True, offset_compensation=True, nplc=1,timeout=10e3):
+    def initialize(self, mode, autozero=True, offset_compensation=True, nplc=1,timeout=10e3,digits=6,k2000=False,continuous_trigger=False,disp_enable=True):
         """
         mode:
             - "voltage": voltage measurement
             - "current": current measurement
             - "resistance": resistance measurement
-            - "4 wires": 4 wires measurement
+            - "4 wires": 4wires measurement
         """
+        self.continuous_trigger=continuous_trigger
+        self.k2000=k2000
         self.pyvisa_resource.write("*RST")
         # self.set_connection_parameter_dic({"write_termination":'\r\n',"read_termination":'\r\n',"send_end":True})
 
-        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
+        mode_name={"voltage":"VOLT", "current":"CURR", "resistance":"RES", "4wires":"FRES", "4 wires":"FRES"}        
+
+        self.pyvisa_resource.write(":SENS:FUNC '%s'"%mode_name[mode])           
+
+        self.pyvisa_resource.write(":SENS:%s:RANG:AUTO ON"%mode_name[mode])     # set automatic range
+
+
+        if k2000:
+            self.pyvisa_resource.write(":SENS:%s:DIG %d"%(mode_name[mode],digits))    
+            if disp_enable:
+                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.
+            else:
+                 self.pyvisa_resource.write(":DISP:ENAB OFF")     # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed.
+
+            if continuous_trigger:
+                self.pyvisa_resource.write("INIT:CONT ON")     # able continuous triggering
+            else:
+                self.pyvisa_resource.write("INIT:CONT OFF")     # able continuous triggering
+
         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
-        
+            if disp_enable:
+                self.pyvisa_resource.write(":DISP:LIGHT:STAT ON100")     # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed.
+            else:
+                 self.pyvisa_resource.write(":DISP:LIGHT:STAT OFF")     # 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(":DISP:%s:DIG %d"%(mode_name[mode],digits))   
+            self.pyvisa_resource.write(":SENS:%s:NPLC %d"%(mode_name[mode],nplc))           # set NPLC. For a PLC of 1, the integration period would be 1/50 (for 50Hz line power) which is 20 msec
+
+            # if mode_name[mode]=="RES" or mode_name[mode]=="FRES":
+
+            #     if offset_compensation:
+            #         self.pyvisa_resource.write(":%s:OCOM ON"%mode_name[mode])          # enable offset compensation
+            #     else:
+            #         self.pyvisa_resource.write(":%s:OCOM OFF"%mode_name[mode])  
+           
+            if autozero:
+                self.pyvisa_resource.write(":%s:AZER ON"%mode_name[mode])          # enable auto-zero
+            else:
+                self.pyvisa_resource.write(":%s:AZER OFF"%mode_name[mode])
+
+            if continuous_trigger:
+                self.pyvisa_resource.write("TRIG:CONT REST")     # able continuous triggering
+            else:
+                self.pyvisa_resource.write("TRIG:CONT OFF")
 
     def read_single(self):
-        data=self.pyvisa_resource.query("READ?")
+        if self.k2000:
+            if self.continuous_trigger:
+                data=self.pyvisa_resource.query("FETCH?")
+            else:
+                data=self.pyvisa_resource.query("READ?")
+        else:
+            if self.continuous_trigger:
+                self.pyvisa_resource.write("TRIG:CONT OFF")
+                time.sleep(0.1)
+                data=self.pyvisa_resource.query("MEAS?")
+                self.pyvisa_resource.write("TRIG:CONT REST")
+            else:
+                data=self.pyvisa_resource.query("MEAS?")
+
         return float(data)
+    
diff --git a/equipment_control/equipment.py b/equipment_control/equipment.py
index 739c56604aa389024521c6ee3617cb77277cff6f..d275b920846371dece200396baac7b90b4fea9c8 100644
--- a/equipment_control/equipment.py
+++ b/equipment_control/equipment.py
@@ -51,25 +51,42 @@ class equipment():
     def close_connection(self):
         self.pyvisa_resource.close()
 
-    def write_in_file(self,file_path,data,delimiter=",",extension="txt"):
+    def write_in_file(self,file_path,data,delimiter=",",extension="txt",overwrite=False,header=None,date=True):
         
         if file_path.split(".")[-1]=="csv":
             delimiter=","
         # Create file and header
-        f = open(file_path, "a")
-        f.write("%s\n"%(datetime.datetime.now().strftime("%c")))
+        if overwrite:
+            f = open(file_path, "w")
+        else:
+            f = open(file_path, "a")
+            
+        if date:
+            f.write("# %s\n"%(datetime.datetime.now().strftime("%c")))
         
-        shape=np.shape(data)
+        if isinstance(header, str):
+            for line in header.split("\n"):
+                f.write("# "+line+"\n")
+
         
-        if len(shape)==1:
+        shape=np.shape(data)
+        if len(shape)==0:
+            f.write("%.6E\n"%(data))
+        elif len(shape)==1:
             for i in range(shape[0]):
-                f.write("%.6f\n"%(data[i]))
+                if i==0:
+                    f.write("%.6E"%(data[i]))
+                else:
+                    f.write("%s%.6E"%(delimiter,data[i]))
+
+            f.write("\n")
+
         elif len(shape)==2:
             for i in range(shape[0]):
                 for j in range(shape[1]):
                     if j==0:
-                        f.write("%.6f"%(data[i,j]))
+                        f.write("%.6E"%(data[i,j]))
                     else:
-                        f.write("%s%.6f"%(delimiter,data[i,j]))
+                        f.write("%s%.6E"%(delimiter,data[i,j]))
                 f.write("\n")                
         f.close()
diff --git a/equipment_control/example/single_equipment/dmm_script.py b/equipment_control/example/single_equipment/dmm_script.py
new file mode 100644
index 0000000000000000000000000000000000000000..cf0643d7e2c07cde7469046a86dcd49b8555f233
--- /dev/null
+++ b/equipment_control/example/single_equipment/dmm_script.py
@@ -0,0 +1,68 @@
+
+
+# =============================================================================
+# 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.dmm as dmm
+import time
+
+# =============================================================================
+# 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
+# =============================================================================
+mydmm=dmm.dmm('USB0::0x05E6::0x6500::04529651::INSTR',timeout=1e3)
+
+# =============================================================================
+# 4. Measurement parameters
+# =============================================================================
+units={"voltage":"V", "current":"A", "resistance":"Ohms", "4wires":"Ohms"}        
+
+mode="current"
+autozero=True
+offset_compensation=True
+nplc=1
+digits=4
+continuous_trigger = False
+disp_enable=True
+k2000=False
+file_path='temp.txt'
+t_init=time.time()
+
+# =============================================================================
+# 5. Initialization of the equipments
+# =============================================================================
+mydmm.initialize( mode=mode, autozero=autozero, offset_compensation=offset_compensation, 
+                 continuous_trigger=continuous_trigger, digits=digits,nplc=nplc,disp_enable=disp_enable
+                 ,k2000=k2000)
+
+# =============================================================================
+# 6. Measurement script
+# =============================================================================
+data=mydmm.read_single()
+t_data=time.time()-t_init
+print("%s measured: %E %s"%(mode,data,units[mode]))
+# =============================================================================
+# 7. Close connection
+# =============================================================================
+mydmm.close_connection()
+
+
+# =============================================================================
+# 8. Save data
+# =============================================================================
+data_to_write=[t_data,data]
+header="Time (s), %s (%s)"%(mode,units[mode])
+mydmm.write_in_file(file_path,data_to_write,header=header,date=True,overwrite=True)
+mydmm.write_in_file(file_path,data_to_write,header=None,date=False,overwrite=False)
diff --git a/equipment_control/example/single_equipment/hp4145_script.py b/equipment_control/example/single_equipment/hp4145_script.py
index 93848b6825f6e783b3e9befcc0d4e24629fe129e..5c50d64c5a01ec1d06b1d5200b64c0eb787e49a5 100644
--- a/equipment_control/example/single_equipment/hp4145_script.py
+++ b/equipment_control/example/single_equipment/hp4145_script.py
@@ -6,47 +6,60 @@ 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.hp4145 as hp4145
-
+import equipment_control.equipment as eq # Parent class that handle the connections with the equipments
+import equipment_control.hp4145 as hp4145 # Child class that inherits from equipment parent class
+import traceback # to write error message in try/except command
+import datetime
 
 # =============================================================================
 # 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))
+rm=eq.resource_manager() # you can use the function from equipment class or directly the pyvisa command rm = pyvisa.ResourceManager()
+list_connections= eq.available_connections(rm=rm) # you can use the function from equipment class or directly the pyvisa command rm.list_resources()
+print("-------------------------------------------------\n Available connections: %s"%str(list_connections))
 
 # =============================================================================
 # 3. Connection to the equipments
 # =============================================================================
-myHP4145=hp4145.hp4145("GPIB0::1::INSTR")
+myHP4145=hp4145.hp4145("GPIB0::1::INSTR",timeout=100e3)
 
 # =============================================================================
 # 4. Measurement parameters
 # =============================================================================
 file_path='temp.txt'
 
-mode="voltage sweep"
-number_channel=4
-smu_bias={"SMU2":0,"SMU3":0,"SMU4":0}
+smu_type={"SMU1":"voltage","SMU2":"current","SMU3":"current","SMU4":"current"}
+smu_used={"SMU1":"on","SMU2":"off","SMU3":"on","SMU4":"on"}
+smu_master=1
+smu_bias={"SMU1":10,"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":1,"step":0.1}
+sweep_param={"start":0,"stop":1,"step":0.05}
+sweep_type="linear"
 integration_mode="IT1"
 delay_time=0
 hold_time=0
 
+
 # =============================================================================
 # 5. Initialization of the equipments
 # =============================================================================
-myHP4145.initialize(mode=mode,number_channel=number_channel,smu_bias=smu_bias,
-              smu_compliance=smu_compliance,sweep_param=sweep_param,
-              integration_mode=integration_mode,delay_time=delay_time,hold_time=hold_time)
 
+print("-------------------------------------------------\n Starting initialisation ...", end='')
+
+myHP4145.initialize(smu_type=smu_type,smu_used=smu_used,smu_master=smu_master,smu_bias=smu_bias,
+                    smu_compliance=smu_compliance,sweep_param=sweep_param,sweep_type=sweep_type,
+                    integration_mode=integration_mode,delay_time=delay_time,hold_time=hold_time)
+print("  Done!")
 # =============================================================================
 # 6. Measurement script
 # =============================================================================
-data=myHP4145.launch_measurements()
+print("-------------------------------------------------\n Starting measurement ...", end='')
+try:
+    data,data_header=myHP4145.launch_measurements()
+except Exception:
+    traceback.print_exc()
+    myHP4145.close_connection()
+print("  Done!")
 
 # =============================================================================
 # 7. Close connection
@@ -56,4 +69,11 @@ myHP4145.close_connection()
 # =============================================================================
 # 8. Save data
 # =============================================================================
-myHP4145.write_in_file(file_path,data)
+custom_header="IV results with HP4145\n"
+
+print("-------------------------------------------------\n Print in file %s"%file_path)
+print(" - Header:")
+print("   # %s"%(datetime.datetime.now().strftime("%c")))
+for line in (custom_header+data_header).split('\n'):
+    print("   # "+line)
+myHP4145.write_in_file(file_path,data,overwrite=True,header=custom_header+data_header)
diff --git a/equipment_control/example/single_equipment/k2400_script.py b/equipment_control/example/single_equipment/k2400_script.py
new file mode 100644
index 0000000000000000000000000000000000000000..b94598f41a1f09dcd229464284455f37e1d946b2
--- /dev/null
+++ b/equipment_control/example/single_equipment/k2400_script.py
@@ -0,0 +1,71 @@
+
+
+# =============================================================================
+# 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.k2400 as k2400
+import time
+
+# =============================================================================
+# 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
+# =============================================================================
+myk2400=k2400.k2400("GPIB0::29::INSTR",timeout=1e3)
+
+# =============================================================================
+# 4. Measurement parameters
+# =============================================================================
+units={"voltage":"V", "current":"A", "resistance":"Ohms"}        
+
+source_mode = "current"
+measurement_mode = "voltage"
+compliance = 1
+autozero = True
+offset_compensation = True
+nplc = 1
+digits = 6
+continuous_trigger = False
+disp_enable = True
+bias_source = 1e-6
+file_path = 'temp.txt'
+t_init=time.time()
+# =============================================================================
+# 5. Initialization of the equipments
+# =============================================================================
+myk2400.initialize(source_mode=source_mode, measurement_mode=measurement_mode,
+                   compliance=compliance, autozero=autozero, offset_compensation=offset_compensation,
+                   digits=digits,continuous_trigger=continuous_trigger,disp_enable=disp_enable, nplc=nplc)
+
+# =============================================================================
+# 6. Measurement script
+# =============================================================================
+myk2400.set_source(bias_source)
+myk2400.set_output("ON")
+data=myk2400.read_single()
+t_data=time.time()-t_init
+print("%s measured: %E %s"%(measurement_mode,data,units[measurement_mode]))
+# =============================================================================
+# 7. Close connection
+# =============================================================================
+myk2400.close_connection()
+
+
+# =============================================================================
+# 8. Save data
+# =============================================================================
+data_to_write=[t_data,data]
+header="Time (s), %s (%s)"%(measurement_mode,units[measurement_mode])
+myk2400.write_in_file(file_path,data_to_write,header=header,date=True,overwrite=True)
+myk2400.write_in_file(file_path,data_to_write,header=None,date=False,overwrite=False)
diff --git a/equipment_control/example/single_equipment/k2450_script.py b/equipment_control/example/single_equipment/k2450_script.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3aad27544a33b944b7909d1fb4de2324ad742c6
--- /dev/null
+++ b/equipment_control/example/single_equipment/k2450_script.py
@@ -0,0 +1,71 @@
+
+
+# =============================================================================
+# 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.k2450 as k2450
+import time
+
+# =============================================================================
+# 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
+# =============================================================================
+myk2450=k2450.k2450("GPIB0::29::INSTR",timeout=5e3)
+
+# =============================================================================
+# 4. Measurement parameters
+# =============================================================================
+units={"voltage":"V", "current":"A", "resistance":"Ohms"}        
+
+source_mode = "voltage"
+measurement_mode = "current"
+compliance = 1e-6
+autozero = True
+offset_compensation = True
+nplc = 1
+digits = 6
+continuous_trigger = True
+disp_enable = True
+bias_source = 1
+file_path = 'temp.txt'
+t_init=time.time()
+# =============================================================================
+# 5. Initialization of the equipments
+# =============================================================================
+myk2450.initialize(source_mode=source_mode, measurement_mode=measurement_mode,
+                   compliance=compliance, autozero=autozero, offset_compensation=offset_compensation,
+                   digits=digits,continuous_trigger=continuous_trigger,disp_enable=disp_enable, nplc=nplc)
+
+# =============================================================================
+# 6. Measurement script
+# =============================================================================
+myk2450.set_source(bias_source)
+myk2450.set_output("ON")
+data=myk2450.read_single()
+t_data=time.time()-t_init
+print("%s measured: %E %s"%(measurement_mode,data,units[measurement_mode]))
+# =============================================================================
+# 7. Close connection
+# =============================================================================
+myk2450.close_connection()
+
+
+# =============================================================================
+# 8. Save data
+# =============================================================================
+data_to_write=[t_data,data]
+header="Time (s), %s (%s)"%(measurement_mode,units[measurement_mode])
+myk2450.write_in_file(file_path,data_to_write,header=header,date=True,overwrite=True)
+myk2450.write_in_file(file_path,data_to_write,header=None,date=False,overwrite=False)
diff --git a/equipment_control/example/single_equipment/k4200_script.py b/equipment_control/example/single_equipment/k4200_script.py
new file mode 100644
index 0000000000000000000000000000000000000000..557ae5c487c72120cc2157eb1086d109f752e1c3
--- /dev/null
+++ b/equipment_control/example/single_equipment/k4200_script.py
@@ -0,0 +1,79 @@
+# =============================================================================
+# 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 # Parent class that handle the connections with the equipments
+import equipment_control.k4200 as k4200 # Child class that inherits from equipment parent class
+import traceback # to write error message in try/except command
+import datetime
+
+# =============================================================================
+# 2. List  available connections (chopes use pyvisa package for communicate with most equipments)
+# =============================================================================
+rm=eq.resource_manager() # you can use the function from equipment class or directly the pyvisa command rm = pyvisa.ResourceManager()
+list_connections= eq.available_connections(rm=rm) # you can use the function from equipment class or directly the pyvisa command rm.list_resources()
+print("-------------------------------------------------\n Available connections: %s"%str(list_connections))
+
+# =============================================================================
+# 3. Connection to the equipments
+# =============================================================================
+myK4200=k4200.k4200("GPIB0::17::INSTR",timeout=10e3)
+
+# =============================================================================
+# 4. Measurement parameters
+# =============================================================================
+file_path='temp.txt'
+
+smu_type={"SMU1":"voltage","SMU2":"voltage","SMU3":"voltage","SMU4":"voltage"}
+smu_used={"SMU1":"on","SMU2":"on","SMU3":"on","SMU4":"on"}
+smu_master=1
+smu_bias={"SMU1":10,"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":1,"step":0.05}
+sweep_type="linear"
+integration_mode="IT1"
+delay_time=0
+hold_time=0
+
+
+# =============================================================================
+# 5. Initialization of the equipments
+# =============================================================================
+
+print("-------------------------------------------------\n Starting initialisation ...", end='')
+
+myK4200.initialize(smu_type=smu_type,smu_used=smu_used,smu_master=smu_master,smu_bias=smu_bias,
+                    smu_compliance=smu_compliance,sweep_param=sweep_param,sweep_type=sweep_type,
+                    integration_mode=integration_mode,delay_time=delay_time,hold_time=hold_time)
+print("  Done!")
+# =============================================================================
+# 6. Measurement script
+# =============================================================================
+print("-------------------------------------------------\n Starting measurement ...", end='')
+try:
+    data,data_header=myK4200.launch_measurements()
+except Exception:
+    traceback.print_exc()
+    myK4200.close_connection()
+print("  Done!")
+
+# =============================================================================
+# 7. Close connection
+# =============================================================================
+myK4200.close_connection()
+
+# =============================================================================
+# 8. Save data
+# =============================================================================
+custom_header="IV results with K4200\n"
+
+print("-------------------------------------------------\n Print in file %s"%file_path)
+print(" - Header:")
+print("   # %s"%(datetime.datetime.now().strftime("%c")))
+for line in (custom_header+data_header).split('\n'):
+    print("   # "+line)
+myK4200.write_in_file(file_path,data,overwrite=True,header=custom_header+data_header)
diff --git a/equipment_control/example/single_equipment/temp.txt b/equipment_control/example/single_equipment/temp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ff704737c1b7ca6b6da9b585048f0dac2dee61dd
--- /dev/null
+++ b/equipment_control/example/single_equipment/temp.txt
@@ -0,0 +1,4 @@
+# Mon Mar 10 17:02:23 2025
+# Time (s), current (A)
+-1.114205E+00,1.364986E-12
+-1.114205E+00,1.364986E-12
diff --git a/equipment_control/hp4145.py b/equipment_control/hp4145.py
index baab7d695d8888b2d861827b9dda1faf083f5582..de71eefed301378424f27f5f4fdbcfa91b812b22 100644
--- a/equipment_control/hp4145.py
+++ b/equipment_control/hp4145.py
@@ -10,8 +10,9 @@ class hp4145(equipment.equipment):
     company="Keysight"
     url="https://www.keysight.com/dk/en/assets/9018-07935/service-manuals/9018-07935.pdf"
     
-    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},
+    def initialize(self, smu_type={"SMU1":"voltage","SMU2":"voltage","SMU3":"common","SMU4":"common"}, smu_used={"SMU1":"on","SMU2":"on","SMU3":"on","SMU4":"on"}, 
+                  smu_master=1,smu_bias={"SMU1":0,"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},sweep_type="linear",
                   integration_mode="IT1",delay_time=0,hold_time=0):
         
         
@@ -19,8 +20,10 @@ class hp4145(equipment.equipment):
         mode:
             - "voltage sweep": voltage sweep with SMU1 and current measurements on all the SMUs
         """
-        self.mode=mode
-        self.number_channel=number_channel
+        self.smu_type=smu_type
+        self.sweep_type=sweep_type
+        self.smu_used=smu_used
+        self.smu_master=smu_master
         self.sweep_param=sweep_param
         self.smu_compliance=smu_compliance
         self.smu_bias=smu_bias
@@ -28,36 +31,60 @@ class hp4145(equipment.equipment):
         self.delay_time=delay_time
         self.hold_time=hold_time
         
-        # self.set_connection_parameter_dic({write_termination":'\r\n',"read_termination":'\r\n',"send_end":True})
+        index_measurement_type={"sweep":1, "constant":3}
+        index_smu_type={"voltage":1, "current":2, "common":3}
     
         try:
             self.pyvisa_resource.write("BC") # clear all buffer.
             self.pyvisa_resource.write("DR1") # This command enables or disables service request for data ready when communications is set to GPIB.
             self.pyvisa_resource.write("EC 1") # This command sets the condition to exit the test if compliance is reached.
             
-            if mode =="voltage sweep":
                 
-                self.length_data=int(abs((sweep_param["stop"]-sweep_param["start"])/sweep_param["step"]))
-                self.pyvisa_resource.write("DE") # DE: Accesses SMU channel definition page.
+            self.pyvisa_resource.write("DE") # DE: Accesses SMU channel definition page.
+            
+            self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', %d, %d"%(smu_master,smu_master,smu_master,index_smu_type[smu_type["SMU%d"%smu_master]],index_measurement_type["sweep"])) # 1/2/3: voltage/current/Common 1/2/3: VAR1/VAR2/constant
+            
+            for smu_index in range(4):
+                if (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="off":
+                    self.pyvisa_resource.write("CH%d"%(smu_index+1)) 
+                elif (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="on":
+                    self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', %d, %d"%(smu_index+1,smu_index+1,smu_index+1,index_smu_type[smu_type["SMU%d"%(smu_index+1)]],index_measurement_type["constant"])) 
 
-                self.pyvisa_resource.write("CH1, 'V1', 'I1', 1, 1") # 1/2/3: voltage/current/Common 1/2/3: VAR1/VAR2/constant
-                
-                for i in range(number_channel-1):
-                    self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', 1, 3"%(i+2,i+2,i+2)) 
+            self.pyvisa_resource.write("SS")# Accesses source setup page
+            if smu_type["SMU%d"%smu_master]=="voltage":
+                if sweep_type=="linear":
+                    self.pyvisa_resource.write("VR1, %.6E, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],smu_compliance["SMU%d"%smu_master])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif sweep_type=="log":
+                    self.pyvisa_resource.write("VR2, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],smu_compliance["SMU%d"%smu_master])) # VR2 for log sweep of VAR1 source function, vmin, vmax, compliance
+            elif smu_type["SMU%d"%smu_master]=="current":
+                if sweep_type=="linear":
+                    self.pyvisa_resource.write("IR1, %.6E, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],smu_compliance["SMU%d"%smu_master])) # IR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif sweep_type=="log":
+                    self.pyvisa_resource.write("IR2, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],smu_compliance["SMU%d"%smu_master])) # IR2 for log sweep of VAR1 source function, vmin, vmax, compliance
+            
+            for smu_index in range(4):
+                if (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="on":
+                    if smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                        self.pyvisa_resource.write("VC%d, %.2f, %.6E"%(smu_index+1,smu_bias["SMU%d"%(smu_index+1)],smu_compliance["SMU%d"%(smu_index+1)]))
+                    elif smu_type["SMU%d"%(smu_index+1)]=="current":
+                        self.pyvisa_resource.write("IC%d, %.2f, %.6E"%(smu_index+1,smu_bias["SMU%d"%(smu_index+1)],smu_compliance["SMU%d"%(smu_index+1)]))
+            time.sleep(20)
+            self.pyvisa_resource.write("HT %f"%hold_time) # Sets a hold time that delays the start of a sweep
+            self.pyvisa_resource.write("DT %f"%delay_time) # delay time: Sets the time to wait between when the output voltage is set and when the measurement is made in a sweep.
+            self.pyvisa_resource.write(integration_mode) # integration time, IT1/IT2/IT3 : short/medium/long
 
-                self.pyvisa_resource.write("SS")# Accesses source setup page
-                self.pyvisa_resource.write("VR1, %s, %s, %s, %s"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],sweep_param["compliance"])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
-                self.pyvisa_resource.write("VC2, %.2f, %s"%(smu_bias[0],smu_compliance[0]))
-                self.pyvisa_resource.write("VC3, %.2f, %s"%(smu_bias[1],smu_compliance[1]))
-                self.pyvisa_resource.write("VC4, %.2f, %s"%(smu_bias[2],smu_compliance[2]))
+            self.pyvisa_resource.write("SM")
+            self.pyvisa_resource.write("DM2")
             
-                self.pyvisa_resource.write("HT %f"%hold_time) # Sets a hold time that delays the start of a sweep
-                self.pyvisa_resource.write("DT %f"%delay_time) # delay time: Sets the time to wait between when the output voltage is set and when the measurement is made in a sweep.
-                self.pyvisa_resource.write(integration_mode) # integration time, IT1/IT2/IT3 : short/medium/long
-    
-                self.pyvisa_resource.write("SM")
-                self.pyvisa_resource.write("DM2")
-                self.pyvisa_resource.write("LI 'I1','I2','I3','I4'")
+            list_display=""
+            for smu_index in range(4):
+                if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                    if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                        list_display+=",'%s%d'"%("I",smu_index+1)
+                    elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                        list_display+=",'%s%d'"%("V",smu_index+1)
+                        
+            self.pyvisa_resource.write("LI %s"%list_display[1:])
             # self.pyvisa_resource.write("DM1")
             # self.pyvisa_resource.write("XN 'V1', 1, %.1f, %.1f"%(v_sweep_param["start"],v_sweep_param["stop"]))
             # self.pyvisa_resource.write("YA 'I1',2, 1E-15, 1E-12")
@@ -65,12 +92,15 @@ class hp4145(equipment.equipment):
             print("/!\ VisaIOError : timeout expired")
             self.pyvisa_resource.close()
         
-        return {"mode":mode, "number_channels":number_channel, "sweep_param":sweep_param}
+        return 42
     
-    def launch_measurements(self):
+    def launch_measurements(self,activate_segmentation=True):
         
-        N_v=self.length_data
-        data={}
+        number_channel=0
+        for smu_index in range(4):
+            if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                number_channel+=1
+
         
         if self.integration_mode=="IT1":
             Nmax=50
@@ -80,39 +110,80 @@ class hp4145(equipment.equipment):
             Nmax=10
             
             
-        if self.mode=="voltage sweep":
             
-            v_list=np.round(np.arange(self.sweep_param["start"],self.sweep_param["stop"]+self.sweep_param["step"],self.sweep_param["step"]),6)
+        sweep_list=np.round(np.arange(self.sweep_param["start"],self.sweep_param["stop"]+self.sweep_param["step"],self.sweep_param["step"]),6)
+        N_v=len(sweep_list)
+        data=np.zeros((N_v,number_channel+1))
+        data[:,0]=sweep_list
+        j=0
 
-            data=np.zeros((N_v,self.number_channel))
-            data[:,0]=v_list
-            
+        if activate_segmentation:
             iteration=int(N_v/Nmax)+1
             index=0
-            j=0
             while iteration>0:
-                v_start=v_list[index]
+                sweep_start=sweep_list[index]
                 if index+Nmax>N_v:
-                    v_end=v_list[-1]
+                    sweep_end=sweep_list[-1]
                 else:
-                    v_end=v_list[index+Nmax-1]
-                    
+                    sweep_end=sweep_list[index+Nmax-1]
+                
+                if self.smu_type["SMU%d"%self.smu_master]=="voltage":
+                    if self.sweep_type=="linear":
+                        self.pyvisa_resource.write("VR1, %.6E, %.6E, %.6E, %.6E"%(sweep_start,sweep_end,self.sweep_param["step"],self.smu_compliance["SMU%d"%self.smu_master])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif self.smu_type["SMU%d"%self.smu_master]=="current":
+                    if self.sweep_type=="linear":
+                        self.pyvisa_resource.write("IR1, %.6E, %.6E, %.6E, %.6E"%(sweep_start,sweep_end,self.sweep_param["step"],self.smu_compliance["SMU%d"%self.smu_master])) # IR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+
+                self.pyvisa_resource.write("SS")
+                if self.smu_type["SMU%d"%(self.smu_master)]=="voltage":
+                    self.pyvisa_resource.write("VR1, %.6E, %.6E, %.6E, %.6E"%(sweep_start,sweep_end,self.sweep_param["step"],self.smu_compliance["SMU%d"%self.smu_master])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif self.smu_type["SMU%d"%(self.smu_master)]=="current":
+                    self.pyvisa_resource.write("IR1, %.6E, %.6E, %.6E, %.6E"%(sweep_start,sweep_end,self.sweep_param["step"],self.smu_compliance["SMU%d"%self.smu_master])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+    
                 self.pyvisa_resource.write("MD") # This command controls measurements.
                 self.pyvisa_resource.write("ME1") # Run a single trigger test and store readings in a cleared buffer: 1
-                time.sleep(10)
-
-                N=int(abs((v_end-v_start)/self.sweep_param["step"]))+1
                 
-                for i in range(self.number_channel):
-                    data_list=self.pyvisa_resource.query("DO 'I%d'"%(i+1))# Read measurements
-                    for  data_i in data_list.split(","):
-                        data[j,i+1]=float(data_i[1:])
-                        if i==0:
+                i=0
+                for smu_index in range(4):
+                    if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                        i+=1
+                        if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                            data_list=self.pyvisa_resource.query("DO 'I%d'"%(smu_index+1))# Read measurements
+                        elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                            data_list=self.pyvisa_resource.query("DO 'V%d'"%(smu_index+1))# Read measurements
+                        j=0
+                        for  data_i in data_list.split(","):
+                            data[index+j,i]=float(data_i[1:])
                             j+=1
                             
                 index+=Nmax
                 iteration-=1  
-                j+=1
+        else:
             
-        return data
+            self.pyvisa_resource.write("MD") # This command controls measurements.
+            self.pyvisa_resource.write("ME1") # Run a single trigger test and store readings in a cleared buffer: 1
+            time.sleep(10)
+            i=0
+            for smu_index in range(4):
+                if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                    i+=1
+                    if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                        data_list=self.pyvisa_resource.query("DO 'I%d'"%(smu_index+1))# Read measurements
+                    elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                        data_list=self.pyvisa_resource.query("DO 'V%d'"%(smu_index+1))# Read measurements
+                    
+                    j=0
+                    for  data_j in data_list.split(","):
+                        data[j,i]=float(data_j[1:])
+                        j+=1
+            
+
+        header="%s%d"%(self.smu_type["SMU%d"%self.smu_master][0].upper(),self.smu_master)
+        for smu_index in range(4):
+            if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                    header+=", %s%d"%("I",smu_index+1)
+                elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                    header+=", %s%d"%("V",smu_index+1)
+        return data, header
     
diff --git a/equipment_control/k2400.py b/equipment_control/k2400.py
new file mode 100644
index 0000000000000000000000000000000000000000..72d8b9937feb04af0aaffff3252379be7fc2fe27
--- /dev/null
+++ b/equipment_control/k2400.py
@@ -0,0 +1,112 @@
+import equipment_control.equipment as equipment
+import time
+class k2400(equipment.equipment):
+    
+    """Class to control K2400 or k2450 SMU"""
+    model="K2400 or K2450"
+    company="Keithley"
+    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,digits=6,continuous_trigger=False,disp_enable=True):
+        
+        """
+        source_mode:
+            - "voltage": voltage source
+            - "current": current source
+        measurement_mode:
+            - "voltage": voltage measurement
+            - "current": current measurement
+            - "resistance": resistance measurement
+        """
+        mode_name={"voltage":"VOLT", "current":"CURR", "resistance":"RES"}        
+        self.output_state="OFF"
+        self.pyvisa_resource.write("*RST")
+        self.source_mode=source_mode
+        self.continuous_trigger=continuous_trigger
+        
+        if source_mode=="voltage":
+            self.pyvisa_resource.write(":SOUR:FUNC VOLT")   
+            self.pyvisa_resource.write(":SENS:CURR:PROT %E"%compliance)     # set automatic range
+
+        if source_mode=="current":
+            self.pyvisa_resource.write(":SOUR:FUNC CURR")   
+            self.pyvisa_resource.write(":SENS:VOLT:PROT %E"%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
+            
+                   
+        self.pyvisa_resource.write(":DISP:DIG %d"%digits)     # Query largest allowable display resolutio
+        if disp_enable:
+            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.
+        else:
+            self.pyvisa_resource.write(":DISP:ENAB OFF")     # 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(":SYST:AZER:STAT ON")          # enable auto-zero
+        else:
+            self.pyvisa_resource.write(":SYST:AZER:STAT OFF")
+        
+
+        self.pyvisa_resource.write(":SENS:%s:NPLC %d"%(mode_name[measurement_mode],nplc))           # set NPLC. For a PLC of 1, the integration period would be 1/50 (for 50Hz line power) which is 20 msec
+        self.pyvisa_resource.write(":FORM:ELEM %s"%mode_name[measurement_mode])
+        
+        if continuous_trigger:
+            self.pyvisa_resource.write(":ARM:SOUR TIMer")
+            self.pyvisa_resource.write(":ARM:TIMer 0.001")
+            self.pyvisa_resource.write(":ARM:COUNT INF")
+        else:
+            self.pyvisa_resource.write(":ARM:SOUR IMMediate")
+
+    def read_single(self):
+        self.pyvisa_resource.write(":OUTP ON")
+
+        if self.continuous_trigger:
+            self.pyvisa_resource.write(":ABORt")
+            self.pyvisa_resource.write(":ARM:COUNT 1")
+            data=self.pyvisa_resource.query(":READ?")
+            self.pyvisa_resource.write(":ARM:COUNT INF")
+            self.pyvisa_resource.write(":INIT")
+            
+        else:
+            data=self.pyvisa_resource.query("READ?")
+            self.pyvisa_resource.write(":OUTP %s"%self.output_state)
+
+
+        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.output_state=output_state
+
+        self.pyvisa_resource.write(":OUTP %s"%output_state)
+        if self.continuous_trigger:
+            self.pyvisa_resource.write(":INIT")
+
+        
+        
diff --git a/equipment_control/k2450.py b/equipment_control/k2450.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab1dedf081d0ee1a5a624842f41671aa9b8e4dfd
--- /dev/null
+++ b/equipment_control/k2450.py
@@ -0,0 +1,101 @@
+import equipment_control.equipment as equipment
+import time
+class k2450(equipment.equipment):
+    
+    """Class to control k2450 SMU"""
+    model="K2400 or K2450"
+    company="Keithley"
+    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,digits=6,continuous_trigger=False,disp_enable=True):
+        
+        """
+        source_mode:
+            - "voltage": voltage source
+            - "current": current source
+        measurement_mode:
+            - "voltage": voltage measurement
+            - "current": current measurement
+            - "resistance": resistance measurement
+        """
+        mode_name={"voltage":"VOLT", "current":"CURR", "resistance":"RES"}        
+        self.output_state="OFF"
+        self.pyvisa_resource.write("*RST")
+        self.source_mode=source_mode
+        self.continuous_trigger=continuous_trigger
+        
+        if source_mode=="voltage":
+            self.pyvisa_resource.write(":SOUR:FUNC VOLT")   
+            self.pyvisa_resource.write(":SOUR:VOLT:ILIM %E"%compliance)     # set automatic range
+
+        if source_mode=="current":
+            self.pyvisa_resource.write(":SOUR:FUNC CURR")   
+            self.pyvisa_resource.write(":SOUR:CURR:VLIM %E"%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
+
+            
+        self.pyvisa_resource.write(":DISP:%s:DIG %d"%(mode_name[measurement_mode],digits))   
+        self.pyvisa_resource.write(":SENS:%s:NPLC %d"%(mode_name[measurement_mode],nplc))           # set NPLC. For a PLC of 1, the integration period would be 1/50 (for 50Hz line power) which is 20 msec
+
+        if disp_enable:
+            self.pyvisa_resource.write(":DISP:LIGHT:STAT ON100")     # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed.
+        else:
+             self.pyvisa_resource.write(":DISP:LIGHT:STAT OFF")     # This command is used to enable and disable the front panel display circuitry. When disabled, the instrument operates at a higher speed.
+             
+        if autozero:
+            self.pyvisa_resource.write(":SENS:%s:AZER ON"%mode_name[measurement_mode])          # enable auto-zero
+        else:
+            self.pyvisa_resource.write(":SENS:%s:AZER OFF"%mode_name[measurement_mode])
+
+
+
+        if continuous_trigger:
+            self.pyvisa_resource.write(":TRIG:LOAD 'LoopUntilEvent', DISP, 0")     # able continuous triggering
+
+        else:
+            self.pyvisa_resource.write("TRIG:CONT OFF")
+
+
+          
+    def read_single(self):
+        self.pyvisa_resource.write(":OUTP ON")
+
+        if self.continuous_trigger:
+            self.pyvisa_resource.write(":ABORt")     # able continuous triggering
+            data=self.pyvisa_resource.query("MEAS?")
+            self.pyvisa_resource.write(":TRIG:LOAD 'LoopUntilEvent', DISP, 0")     # able continuous triggering
+            self.pyvisa_resource.write(":INIT")     # able continuous triggering
+        else:
+            data=self.pyvisa_resource.query("MEAS?")
+            self.pyvisa_resource.write(":OUTP %s"%self.output_state)
+
+        return float(data)
+    
+    def set_source(self,value):
+        if self.source_mode=="current":
+            self.pyvisa_resource.write(":SOUR:CURR %E"%value)           #set output voltage
+        elif self.source_mode=="voltage":
+            self.pyvisa_resource.write(":SOUR:VOLT %E"%value)           #set output voltage
+
+
+    def set_output(self,output_state="ON"):
+        self.output_state=output_state
+        self.pyvisa_resource.write(":OUTP %s"%output_state)
+        if self.continuous_trigger:
+            self.pyvisa_resource.write(":INIT")
+
+        
+        
diff --git a/equipment_control/k24xx.py b/equipment_control/k24xx.py
deleted file mode 100644
index ce91ad446f06e2d945093b67089f5a46a254b85d..0000000000000000000000000000000000000000
--- a/equipment_control/k24xx.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import equipment_control.equipment as equipment
-
-class k24XX(equipment.equipment):
-    
-    """Class to control K2400 or k2450 SMU"""
-    model="K2400 or K2450"
-    company="Keithley"
-    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 72aaf7a145a1af698f7a19c12791596714f628e8..76c251cae53ac95c5975644d0a999fe38e69aeed 100644
--- a/equipment_control/k4200.py
+++ b/equipment_control/k4200.py
@@ -10,8 +10,9 @@ class k4200(equipment.equipment):
     company="Keysight"
     url="https://www.tek.com/en/products/keithley/4200a-scs-parameter-analyzer"
     
-    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},
+    def initialize(self, smu_type={"SMU1":"voltage","SMU2":"voltage","SMU3":"common","SMU4":"common"}, smu_used={"SMU1":"on","SMU2":"on","SMU3":"on","SMU4":"on"}, 
+                  smu_master=1,smu_bias={"SMU1":0,"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},sweep_type="linear",
                   integration_mode="IT1",delay_time=0,hold_time=0):
         
         
@@ -19,8 +20,10 @@ class k4200(equipment.equipment):
         mode:
             - "voltage sweep": voltage sweep with SMU1 and current measurements on all the SMUs
         """
-        self.mode=mode
-        self.number_channel=number_channel
+        self.smu_type=smu_type
+        self.sweep_type=sweep_type
+        self.smu_used=smu_used
+        self.smu_master=smu_master
         self.sweep_param=sweep_param
         self.smu_compliance=smu_compliance
         self.smu_bias=smu_bias
@@ -28,69 +31,119 @@ class k4200(equipment.equipment):
         self.delay_time=delay_time
         self.hold_time=hold_time
         
-        self.set_connection_parameter_dic({"write_termination":'\r\n',"read_termination":'\r\n',"send_end":True})
+        index_measurement_type={"sweep":1, "constant":3}
+        index_smu_type={"voltage":1, "current":2, "common":3}
     
         try:
             self.pyvisa_resource.write("BC") # clear all buffer.
             self.pyvisa_resource.write("DR1") # This command enables or disables service request for data ready when communications is set to GPIB.
             self.pyvisa_resource.write("EC 1") # This command sets the condition to exit the test if compliance is reached.
             
-            if mode =="voltage sweep":
                 
-                self.length_data=int(abs((sweep_param["stop"]-sweep_param["start"])/sweep_param["step"]))
-                self.pyvisa_resource.write("DE") # DE: Accesses SMU channel definition page.
-
-                self.pyvisa_resource.write("CH1, 'V1', 'I1', 1, 1") # 1/2/3: voltage/current/Common 1/2/3: VAR1/VAR2/constant
-                
-                for i in range(number_channel-1):
-                    self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', 1, 3"%(i+2,i+2,i+2)) 
+            self.pyvisa_resource.write("DE") # DE: Accesses SMU channel definition page.
+            
+            self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', %d, %d"%(smu_master,smu_master,smu_master,index_smu_type[smu_type["SMU%d"%smu_master]],index_measurement_type["sweep"])) # 1/2/3: voltage/current/Common 1/2/3: VAR1/VAR2/constant
+            
+            for smu_index in range(4):
+                if (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="off":
+                    self.pyvisa_resource.write("CH%d"%(smu_index+1)) 
+                elif (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="on":
+                    self.pyvisa_resource.write("CH%d, 'V%d', 'I%d', %d, %d"%(smu_index+1,smu_index+1,smu_index+1,index_smu_type[smu_type["SMU%d"%(smu_index+1)]],index_measurement_type["constant"])) 
 
-                self.pyvisa_resource.write("SS")# Accesses source setup page
-                self.pyvisa_resource.write("VR1, %s, %s, %s, %s"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],sweep_param["compliance"])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
-                self.pyvisa_resource.write("VC2, %.2f, %s"%(smu_bias[0],smu_compliance[0]))
-                self.pyvisa_resource.write("VC3, %.2f, %s"%(smu_bias[1],smu_compliance[1]))
-                self.pyvisa_resource.write("VC4, %.2f, %s"%(smu_bias[2],smu_compliance[2]))
+            self.pyvisa_resource.write("SS")# Accesses source setup page
+            if smu_type["SMU%d"%smu_master]=="voltage":
+                if sweep_type=="linear":
+                    self.pyvisa_resource.write("VR1, %.6E, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],smu_compliance["SMU%d"%smu_master])) # VR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif sweep_type=="log":
+                    self.pyvisa_resource.write("VR2, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],smu_compliance["SMU%d"%smu_master])) # VR2 for log sweep of VAR1 source function, vmin, vmax, compliance
+            elif smu_type["SMU%d"%smu_master]=="current":
+                if sweep_type=="linear":
+                    self.pyvisa_resource.write("IR1, %.6E, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],sweep_param["step"],smu_compliance["SMU%d"%smu_master])) # IR1 for linear sweep of VAR1 source function, vmin, vmax,vstep, compliance
+                elif sweep_type=="log":
+                    self.pyvisa_resource.write("IR2, %.6E, %.6E, %.6E"%(sweep_param["start"],sweep_param["stop"],smu_compliance["SMU%d"%smu_master])) # IR2 for log sweep of VAR1 source function, vmin, vmax, compliance
             
-                self.pyvisa_resource.write("HT %f"%hold_time) # Sets a hold time that delays the start of a sweep
-                self.pyvisa_resource.write("DT %f"%delay_time) # delay time: Sets the time to wait between when the output voltage is set and when the measurement is made in a sweep.
-                self.pyvisa_resource.write(integration_mode) # integration time, IT1/IT2/IT3 : short/medium/long
+            for smu_index in range(4):
+                if (smu_index+1!=smu_master) and smu_used["SMU%d"%(smu_index+1)]=="on":
+                    if smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                        self.pyvisa_resource.write("VC%d, %.2f, %.6E"%(smu_index+1,smu_bias["SMU%d"%(smu_index+1)],smu_compliance["SMU%d"%(smu_index+1)]))
+                    elif smu_type["SMU%d"%(smu_index+1)]=="current":
+                        self.pyvisa_resource.write("IC%d, %.2f, %.6E"%(smu_index+1,smu_bias["SMU%d"%(smu_index+1)],smu_compliance["SMU%d"%(smu_index+1)]))
 
-                self.pyvisa_resource.write("RS 7") # This command sets the measurement resolution for all channels of a SM in number of bits
-                self.pyvisa_resource.write("RG 1, 10E-12") # This command sets the measurement resolution for all channels of a SM in number of bits
-                self.pyvisa_resource.write("RG 2, 10E-12") # This command sets the lowest current range of the SMU to be used when measuring.
-    
-                self.pyvisa_resource.write("SM")
-                self.pyvisa_resource.write("DM2")
-                self.pyvisa_resource.write("LI 'I1','I2','I3','I4'")
+            self.pyvisa_resource.write("RS 7") # This command sets the measurement resolution for all channels of a SM in number of bits
+            self.pyvisa_resource.write("RG 1, 10E-12") # This command sets the measurement resolution for all channels of a SM in number of bits
+            self.pyvisa_resource.write("RG 2, 10E-12") # This command sets the lowest current range of the SMU to be used when measuring.
+
+# =============================================================================
+#                          self.pyvisa_resource.write("SM")
+#             self.pyvisa_resource.write("DM1")
+#             self.pyvisa_resource.write("XN '%s%d', 1, %.1f, %.1f"%(smu_type["SMU%d"%smu_master][0].upper(),smu_master,sweep_param["start"],sweep_param["stop"]))
+# 
+#             list_display=""
+#             for smu_index in range(4):
+#                 if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+#                     if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+#                         self.pyvisa_resource.write("YA '%s%d', 3, 1e-15, 1e-6"%("I",smu_index+1))
+#                     elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+#                         self.pyvisa_resource.write("YA '%s%d', 3, 1e-15, 1e-6"%("V",smu_index+1))
+# =============================================================================
+            self.pyvisa_resource.write("SM")
+            self.pyvisa_resource.write("DM2")
+            list_display=""
+            for smu_index in range(4):
+                if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                    if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                        list_display+=",'%s%d'"%("I",smu_index+1)
+                    elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                        list_display+=",'%s%d'"%("V",smu_index+1)
+                        
+            self.pyvisa_resource.write("LI %s"%list_display[1:])
         except pyvisa.VisaIOError:
             print("/!\ VisaIOError : timeout expired")
             self.pyvisa_resource.close()
         
-        return {"mode":mode, "number_channels":number_channel, "sweep_param":sweep_param}
+        return 42
     
     def launch_measurements(self):
         
+        number_channel=0
+        for smu_index in range(4):
+            if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                number_channel+=1
+        sweep_list=np.round(np.arange(self.sweep_param["start"],self.sweep_param["stop"]+self.sweep_param["step"],self.sweep_param["step"]),6)
+        N_sweep=len(sweep_list)
+        data=np.zeros((N_sweep,number_channel+1))
+        data[:,0]=sweep_list
+
+        
         self.pyvisa_resource.write("MD") # This command controls measurements.
         self.pyvisa_resource.write("ME1") # Run a single trigger test and store readings in a cleared buffer: 1
-        time.sleep(10)
-        N=self.length_data        
-        
-        if self.mode=="voltage sweep":
-            v_list=np.round(np.arange(self.sweep_param["start"],self.sweep_param["stop"]+self.sweep_param["step"],self.sweep_param["step"]),6)
-
-            data=np.zeros((N,self.number_channel))
-            data[:,0]=v_list
-
-            count=0               
-            while (count<N):
-                data_ch1=np.float32(self.pyvisa_resource.query("RD 'I1', %d"%(count+1)))
-                if (data_ch1!=0.):
-                    data[count,1]=data_ch1
-                    for i in range(self.number_channel-1):
-                        data[count,i+2]=np.float32(self.pyvisa_resource.query("RD 'I%d', %d"%(i+2,count+1)))
-                    count+=1
-                time.sleep(0.1)
-        return data
+        time.sleep(1)
+        j=0               
+        while (j<N_sweep):
+            if self.smu_type["SMU%d"%(self.smu_master)]=="voltage":
+                data_master=np.float32(self.pyvisa_resource.query("RD 'I%d', %d"%(self.smu_master,j+1)))
+            elif self.smu_type["SMU%d"%(self.smu_master)]=="current":
+                data_master=np.float32(self.pyvisa_resource.query("RD 'V%d', %d"%(self.smu_master,j+1)))
+            if (data_master!=0.):
+                i=0
+                for smu_index in range(4):
+                    if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                        i+=1
+                        if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                            data[j,i]=np.float32(self.pyvisa_resource.query("RD 'I%d', %d"%(smu_index+1,j+1)))# Read measurements
+                        elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                            data[j,i]=np.float32(self.pyvisa_resource.query("RD 'V%d', %d"%(smu_index+1,j+1)))# Read measurements
+                            
+                j+=1
+            time.sleep(0.1)
+        header="%s%d"%(self.smu_type["SMU%d"%self.smu_master][0].upper(),self.smu_master)
+        for smu_index in range(4):
+            if self.smu_used["SMU%d"%(smu_index+1)]=="on":
+                if self.smu_type["SMU%d"%(smu_index+1)]=="voltage":
+                    header+=", %s%d"%("I",smu_index+1)
+                elif self.smu_type["SMU%d"%(smu_index+1)]=="current":
+                    header+=", %s%d"%("V",smu_index+1)
+        return data, header
     
 
         
\ No newline at end of file
diff --git a/equipment_control/kal100.py b/equipment_control/kal100.py
new file mode 100644
index 0000000000000000000000000000000000000000..d865a498613177662b4583f52761b31a9a23d646
--- /dev/null
+++ b/equipment_control/kal100.py
@@ -0,0 +1,51 @@
+import equipment_control.equipment as equipment
+import time
+import serial
+
+class kal100(equipment.equipment):
+    
+    """Class to control KAL100 pressure system"""
+    model="KAL100"
+    company="halstrup-walcher"
+    url="https://www.halstrup-walcher.de/en/products/KAL100.php"
+
+    units_dic={"kPa":0,"Pa":1,"hPa":0}
+    def __init__(self,port):
+        self.serial_resource = serial.Serial(
+            port=port,
+            baudrate=9600,
+            parity=serial.PARITY_NONE,
+            stopbits=serial.STOPBITS_ONE,
+            bytesize=serial.EIGHTBITS
+        )
+
+    def initialize(self,units="kPa",percentage=100, mode_operation="MS", mode_input="MI0"):    
+        
+        self.serial_resource.write(">PD%d"%self.units_dic[units])
+        time.sleep(1)
+        self.serial_resource.write(">PP%d"%percentage) # always 100% of the target 
+        time.sleep(1)
+
+        self.serial_resource.write("%s"%mode_input) # MI0: Positive P-input, MI1: Negative P-input, MI2: Differential pressure measurement 
+        time.sleep(1)
+
+        self.serial_resource.write("MZ") # mode zeroing
+        time.sleep(1)            
+        self.serial_resource.write("%s"%mode_operation) #MT: mode test, MZ: mode zeroing, MS: mode target value, MS: mode pressure measurement, 
+        time.sleep(1)            
+        
+        if mode_operation=="MS":
+            self.serial_resource.write("PS%3.5f"%0) #MT: mode test, MZ: mode zeroing, MS: mode target value, MS: mode pressure measurement, 
+            time.sleep(1)  
+            
+    def set_pressure(self,pressure, units="kPa"):
+        self.serial_resource.write("MS") 
+        time.sleep(1)
+        self.serial_resource.write(">PD%d"%self.units_dic[units])
+        time.sleep(1)
+        self.serial_resource.write("PS%3.5f"%0) #MT: mode test, MZ: mode zeroing, MS: mode target value, MS: mode pressure measurement, 
+        time.sleep(1)      
+            
+    def close_connection(self):
+        self.serial_resource.close()
+