diff --git a/configs/config_mb_2023.py b/configs/config_mb_2023.py
index 8bd970d8096ec3515ced1a1c9d11ea5e2aeabbc7..f3f566ba70a9fb3bf7797821b95578b28d48a232 100644
--- a/configs/config_mb_2023.py
+++ b/configs/config_mb_2023.py
@@ -17,14 +17,15 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2023_0_X',
-             'voltage_max': 12.,  # Maximum voltage supported by the TX board [V]
-             'adc_voltage_max': 4800.,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2.,  # Shunt resistance in Ohms
-             'interface_name': 'i2c',
+             'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
+             'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2023_0_X',
             'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
diff --git a/configs/config_mb_2023_3_mux_2024.py b/configs/config_mb_2023_3_mux_2024.py
index 892582abf4abc29a21b94f4821f5f06f7f95f856..8373edcbe9830a0d05fbbf0a8ce3ee02cb18ccda 100644
--- a/configs/config_mb_2023_3_mux_2024.py
+++ b/configs/config_mb_2023_3_mux_2024.py
@@ -17,14 +17,15 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
-    'pwr': {'model': 'pwr_batt', 'voltage': 12.,'interface_name':'none'},
+    'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2023_0_X',
-             'voltage_max': 12.,  # Maximum voltage supported by the TX board [V]
-             'adc_voltage_max': 4800.,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2.,  # Shunt resistance in Ohms
-             'interface_name': 'i2c',
+             'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
+             'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2023_0_X',
             'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
diff --git a/configs/config_mb_2023_4_mux_2023.py b/configs/config_mb_2023_4_mux_2023.py
index fa30ccaadc748d016cd2307bff9678217e04259d..40665972ec78fcbb165cf92d2b3b5fb2fe617836 100644
--- a/configs/config_mb_2023_4_mux_2023.py
+++ b/configs/config_mb_2023_4_mux_2023.py
@@ -17,14 +17,15 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2023_0_X',
-             'voltage_max': 12.,  # Maximum voltage supported by the TX board [V]
-             'adc_voltage_max': 4800.,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2.,  # Shunt resistance in Ohms
-             'interface_name': 'i2c',
+             'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
+             'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2023_0_X',
             'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
diff --git a/configs/config_mb_2023_4_mux_2024.py b/configs/config_mb_2023_4_mux_2024.py
index 19254ca112b0526895b64adb6afb23b1ace95ee0..f15f2af3127ea11b8469d20e109fbcc6120954d0 100644
--- a/configs/config_mb_2023_4_mux_2024.py
+++ b/configs/config_mb_2023_4_mux_2024.py
@@ -16,14 +16,15 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2023_0_X',
-             'voltage_max': 12.,  # Maximum voltage supported by the TX board [V]
-             'adc_voltage_max': 4800.,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2.,  # Shunt resistance in Ohms
-             'interface_name': 'i2c',
+             'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
+             'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2023_0_X',
             'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
diff --git a/configs/config_mb_2023__3_mux_2024_dps5005.py b/configs/config_mb_2023__3_mux_2024_dps5005.py
index 26c0dddcc158167b2f6a7a700eaf2098bb410e3d..b4d7d2cce647f725fe30c95e665f02f1e0c10f8c 100644
--- a/configs/config_mb_2023__3_mux_2024_dps5005.py
+++ b/configs/config_mb_2023__3_mux_2024_dps5005.py
@@ -17,14 +17,15 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
-    'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
+    'pwr': {'model': 'pwr_dps5005', 'voltage': 12., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2023_0_X',
-             'voltage_max': 12.,  # Maximum voltage supported by the TX board [V]
-             'adc_voltage_max': 4800.,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2.,  # Shunt resistance in Ohms
-             'interface_name': 'i2c',
+             'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
+             'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2023_0_X',
             'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
diff --git a/configs/config_mb_2024_0_2.py b/configs/config_mb_2024_0_2.py
index f99c214d235e821f4b55fca27db02d6b5bff2760..c73ecf4176c1b9f23935fe196370fb741ae89477 100644
--- a/configs/config_mb_2024_0_2.py
+++ b/configs/config_mb_2024_0_2.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__1_mux_2024.py b/configs/config_mb_2024_0_2__1_mux_2024.py
index a9a91e4d052bb426c4f5c9e3765578b0a7f73a19..ecc683c7d09c56a11ac44cbd4327784e40da45c4 100644
--- a/configs/config_mb_2024_0_2__1_mux_2024.py
+++ b/configs/config_mb_2024_0_2__1_mux_2024.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py
index 86f5a3b59abe9c0d1e56d88463b892688749078c..60f5bfc061e71e10431b20ffb1dd670d37997604 100644
--- a/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py
+++ b/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py
index 6466bc801ceace9ab4c1cbf89f7b9877b9ee4969..a0f08b7995d9f7e94ea552d787bda027094792fa 100644
--- a/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py
+++ b/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py
index 5b8f4f56a4aff2271e1be00f89a8ae79b86b68bb..8fa5f2421b868ae8638be841186eea7b6972a7e8 100644
--- a/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py
+++ b/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py
index f2c4026afd073212525010563b4728104872633f..103f537ed1488796a68bce96b2721c1ccba3199d 100644
--- a/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py
+++ b/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [mA]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py
index 21acb17afeb6429861a6acd5eff1101881e3277e..abba800afd622de78efddc9ff8fb62855863ab22 100644
--- a/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py
+++ b/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py
@@ -16,13 +16,14 @@ OHMPI_CONFIG = {
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
 
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.80/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
diff --git a/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py
index 4fd7c4c0c8d55fe865591568382a533566ce3136..31c2538e8a5923f963f0f0fbce254307a2be17a4 100644
--- a/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py
+++ b/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py
@@ -15,14 +15,14 @@ OHMPI_CONFIG = {
     'id': ohmpi_id,  # Unique identifier of the OhmPi board (string)
     'settings': 'ohmpi_settings.json',  # INSERT YOUR FAVORITE SETTINGS FILE HERE
 }
-
+r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
     'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
     'tx':  {'model': 'mb_2024_0_2',
              'voltage_max': 50.,  # Maximum voltage supported by the TX board [V]
-             'current_max': 4800,  # Maximum voltage read by the current ADC on the TX board [mA]
-             'r_shunt': 2,  # Shunt resistance in Ohms
+             'current_max': 4.8/(50*r_shunt),  # Maximum voltage read by the current ADC on the TX board [A]
+             'r_shunt': r_shunt,  # Shunt resistance in Ohms
              'interface_name': 'i2c'
             },
     'rx':  {'model': 'mb_2024_0_2',
@@ -42,7 +42,7 @@ HARDWARE_CONFIG = {
                       # 'mcp_1': '0x27',
                       'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'},
                       'cabling': {(i+8, j): ('mux_02', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)},
-                      'voltage_max': 12.},
+                      'voltage_max': 50.},
                 'mux_03':
                      {'model': 'mux_2024_0_X',
                       'tca_address': None,
@@ -53,7 +53,7 @@ HARDWARE_CONFIG = {
                       # 'mcp_1': '0x27',
                       'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'},
                       'cabling': {(i+24, j): ('mux_03', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)},
-                      'voltage_max': 12.},
+                      'voltage_max': 50.},
                  'mux_05':
                      {'model': 'mux_2024_0_X',
                       'tca_address': None,
@@ -62,7 +62,7 @@ HARDWARE_CONFIG = {
                       'addr1': 'down',
                       'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'},
                       'cabling': {(i+0, j): ('mux_05', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)},
-                      'voltage_max': 12.},
+                      'voltage_max': 50.},
                 'mux_06':
                      {'model': 'mux_2024_0_X',
                       'tca_address': None,
@@ -71,11 +71,12 @@ HARDWARE_CONFIG = {
                       'addr1': 'down',
                       'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'},
                       'cabling': {(i+16, j): ('mux_06', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)},
-                      'voltage_max': 12.},
+                      'voltage_max': 50.},
                  },
              'default': {'interface_name': 'i2c_ext',
                          'voltage_max': 100.,
-                         'current_max': 3.}
+                         'current_max': 3.
+                         }
             }
     }
 
diff --git a/dev/test_mb_2024_4_mux_2024.py b/dev/test_mb_2024_4_mux_2024.py
index 259ac9b7f747ce210ceae5c687d22ea5c7ed4b3e..bf541f13dba999db195c51e00fffd48860e8d044 100644
--- a/dev/test_mb_2024_4_mux_2024.py
+++ b/dev/test_mb_2024_4_mux_2024.py
@@ -40,32 +40,36 @@ if stand_alone:
     rx = rx_module.Rx(**HARDWARE_CONFIG['rx'])
     tx = tx_module.Tx(**HARDWARE_CONFIG['tx'])
     pwr = pwr_module.Pwr(**HARDWARE_CONFIG['pwr'])
-    mux_ids = ['mux_02', 'mux_05']
-    for m,mux_id in enumerate(mux_ids):
-        mux_module = importlib.import_module(
-            f'ohmpi.hardware_components.{HARDWARE_CONFIG["mux"]["boards"][mux_id].pop("model")}')
-
-        MUX_CONFIG = HARDWARE_CONFIG['mux']['boards'][mux_id]
-
-        MUX_CONFIG.update({'ctl': ctl, 'connection': MUX_CONFIG.pop('connection', ctl.interfaces[
-                                           MUX_CONFIG.pop('interface_name', 'i2c_ext')]), 'exec_logger': ctl.exec_logger,
-                       'soh_logger': ctl.soh_logger})
-        MUX_CONFIG.update({'id': mux_id})
-        mux = mux_module.Mux(**MUX_CONFIG)
-
-        # tx.polarity = 1
-        # time.sleep(1)
-        # tx.polarity = 0
-        # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='on')
-        # time.sleep(1)
-        # voltage = rx.voltage
-        # current = tx.current
-        # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='off')
-        # print(f'Resistance: {voltage / current :.2f} ohm, voltage: {voltage:.2f} mV, current: {current:.2f} mA')
-        mux.reset()
-        mux.test({'A': [i+8*m for i in range(1, 9)], 'B': [i+8*m for i in range(1, 9)],
-                  'M': [i+8*m for i in range(1, 9)], 'N': [i+8*m for i in range(1, 9)]}, activation_time=.1)
-        mux.reset()
+    # mux_ids = ['mux_02', 'mux_05']
+    # for m,mux_id in enumerate(mux_ids):
+    #     mux_module = importlib.import_module(
+    #         f'ohmpi.hardware_components.{HARDWARE_CONFIG["mux"]["boards"][mux_id].pop("model")}')
+    #
+    #     MUX_CONFIG = HARDWARE_CONFIG['mux']['boards'][mux_id]
+    #
+    #     MUX_CONFIG.update({'ctl': ctl, 'connection': MUX_CONFIG.pop('connection', ctl.interfaces[
+    #                                        MUX_CONFIG.pop('interface_name', 'i2c_ext')]), 'exec_logger': ctl.exec_logger,
+    #                    'soh_logger': ctl.soh_logger})
+    #     MUX_CONFIG.update({'id': mux_id})
+    #     mux = mux_module.Mux(**MUX_CONFIG)
+    #
+    #     # tx.polarity = 1
+    #     # time.sleep(1)
+    #     # tx.polarity = 0
+    #     # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='on')
+    #     # time.sleep(1)
+    #     # voltage = rx.voltage
+    #     # current = tx.current
+    #     # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='off')
+    #     # print(f'Resistance: {voltage / current :.2f} ohm, voltage: {voltage:.2f} mV, current: {current:.2f} mA')
+    #     mux.reset()
+    #     mux.test({'A': [i+8*m for i in range(1, 9)], 'B': [i+8*m for i in range(1, 9)],
+    #               'M': [i+8*m for i in range(1, 9)], 'N': [i+8*m for i in range(1, 9)]}, activation_time=.1)
+    #     mux.reset()
+    for pol in [1,0,-1,0]:
+        tx.polarity = pol
+        print(pol)
+        time.sleep(5)
 
 # mux as part of a OhmPiHardware system
 if part_of_hardware_system:
@@ -105,14 +109,15 @@ if within_ohmpi:
     # k._hw.switch_mux([A, B, M, N], state='off')
     # print(f'OhmPiHardware Resistance: {k._hw.last_rho :.2f} ohm, dev. {k._hw.last_dev:.2f} %, rx bias: {k._hw.rx._bias:.2f} mV')
     # k._hw._plot_readings()
-    # k.load_sequence('sequences/9991_GRAD_16_s1_a1.txt')
-    # k.run_sequence(tx_volt=5., injection_duration=1., nb_stack=2, duty_cycle=0.5)
+    k.load_sequence('sequences/9991_GRAD_16_s1_a1.txt')
+    k.run_sequence(tx_volt=5, injection_duration=1., nb_stack=2, duty_cycle=0.5)
     print('using OhmPi')
-    d = k.run_measurement([A, B, M, N], injection_duration=1., nb_stack=2, duty_cycle=0.5)
+    # d = k.run_measurement([A, B, M, N], injection_duration=1., nb_stack=2, duty_cycle=0.5, tx_volt=5.)
     # print(d)
-    k._hw._plot_readings()
+    # k._hw._plot_readings()
     print(f'OhmPiHardware: Resistance: {k._hw.last_resistance() :.2f} ohm, dev. {k._hw.last_dev():.2f} %, sp: {k._hw.sp:.2f} mV, rx bias: {k._hw.rx._bias:.2f} mV')
     print(f'OhmPi: Resistance: {d["R [Ohm]"] :.2f} ohm, dev. {d["R_std [%]"]:.2f} %, rx bias: {k._hw.rx._bias:.2f} mV')
     # k._hw._plot_readings(save_fig=False)
     # plot_exec_log('ohmpi/logs/exec.log')
 change_config('../configs/config_default.py', verbose=False)
+
diff --git a/ohmpi/hardware_components/abstract_hardware_components.py b/ohmpi/hardware_components/abstract_hardware_components.py
index 3ae488e1efd2f8a183580eeb3823d63231239879..be1e51e2c2712e249988d975d014503f8b1eacc7 100644
--- a/ohmpi/hardware_components/abstract_hardware_components.py
+++ b/ohmpi/hardware_components/abstract_hardware_components.py
@@ -55,6 +55,7 @@ class PwrAbstract(ABC):
         self._current_max = kwargs.pop('current_max', 0.)
         self._voltage_min = kwargs.pop('voltage_min', 0.)
         self._voltage_max = kwargs.pop('voltage_max', 0.)
+        self._switchable = False
         self.connection = kwargs.pop('connection', None)
         self._battery_voltage = np.nan
 
@@ -93,6 +94,8 @@ class PwrAbstract(ABC):
             self._pwr_state = 'off'
             self.exec_logger.debug(f'{self.model} cannot be switched off')
 
+    def reload_settings(self):
+        pass
 
     @property
     @abstractmethod
@@ -278,6 +281,7 @@ class TxAbstract(ABC):
             self.soh_logger = create_stdout_logger('soh_tx')
         self.connection = kwargs.pop('connection', None)
         self.pwr = kwargs.pop('pwr', None)
+        self._voltage = 0.
         self._polarity = 0
         self._injection_duration = None
         self._gain = 1.
@@ -302,6 +306,17 @@ class TxAbstract(ABC):
         self._gain = value
         self.exec_logger.debug(f'Setting TX gain to {value}')
 
+    @property
+    @abstractmethod
+    def current(self):
+        """ Gets the current IAB in Amps
+        """
+        pass
+
+    @current.setter
+    @abstractmethod
+    def current(self, value):
+        pass
 
     @abstractmethod
     def current_pulse(self, **kwargs):
@@ -370,6 +385,18 @@ class TxAbstract(ABC):
     def tx_bat(self):
         pass
 
+    @property
+    def voltage(self):
+        """ Gets the voltage VAB in Volts
+        """
+        return self._voltage
+
+    @voltage.setter
+    def voltage(self, value):
+        assert value >= 0.
+        self._voltage = value
+        self.pwr.voltage = value
+
     def voltage_pulse(self, voltage=0., length=None, polarity=1):
         """ Generates a square voltage pulse
 
@@ -396,7 +423,9 @@ class TxAbstract(ABC):
     def pwr_state(self, state):
         if state == 'on':
             self._pwr_state = 'on'
-            self.exec_logger.debug(f'{self.model} cannot switch on power source')
+            if not self.pwr.switchable:
+                self.exec_logger.debug(f'{self.model} cannot switch on power source')
+            self.pwr.reload_settings()
         elif state == 'off':
             self._pwr_state = 'off'
             self.exec_logger.debug(f'{self.model} cannot switch off power source')
diff --git a/ohmpi/hardware_components/mb_2023_0_X.py b/ohmpi/hardware_components/mb_2023_0_X.py
index dff4eaa494fa791ed68e402665a40c09f5276d88..f9ae9368f2ec997d3fdf598b97a4644993e061de 100644
--- a/ohmpi/hardware_components/mb_2023_0_X.py
+++ b/ohmpi/hardware_components/mb_2023_0_X.py
@@ -78,7 +78,7 @@ class Tx(TxAbstract):
             self.exec_logger.event(f'{self.model}\ttx_init\tbegin\t{datetime.datetime.utcnow()}')
         assert isinstance(self.connection, I2C)
         kwargs.update({'pwr': kwargs.pop('pwr', SPECS['tx']['compatible_power_sources']['default'][0])})
-        if (kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['default']):
+        if kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['default']:
             self.exec_logger.warning(f'Incompatible power source specified check config')
             assert kwargs['pwr'] in SPECS['tx']
         self._activation_delay = kwargs['activation_delay']
@@ -95,7 +95,7 @@ class Tx(TxAbstract):
         self._ads_current = ads.ADS1115(self.connection, gain=self._adc_gain, data_rate=self._ads_current_data_rate,
                                         address=self._ads_current_address)
         self._ads_current.mode = Mode.CONTINUOUS
-        self.r_shunt = kwargs['r_shunt']
+        self._r_shunt = kwargs['r_shunt']
         self.adc_voltage_min = kwargs['adc_voltage_min']
         self.adc_voltage_max = kwargs['adc_voltage_max']
 
@@ -138,13 +138,13 @@ class Tx(TxAbstract):
     def current(self):
         """ Gets the current IAB in Amps
         """
-        iab = AnalogIn(self._ads_current, ads.P0).voltage * 1000. / (50 * self.r_shunt)  # measure current
-        self.exec_logger.debug(f'Reading TX current:  {iab} mA')
+        iab = AnalogIn(self._ads_current, ads.P0).voltage * 1000. / (50 * self._r_shunt)  # measure current
+        self.exec_logger.debug(f'Reading TX current: {iab} mA')
         return iab
 
     @ current.setter
     def current(self, value):
-        assert self.adc_voltage_min / (50 * self.r_shunt)  <= value <= self.adc_voltage_max / (50 * self.r_shunt)
+        assert self.adc_voltage_min / (50 * self._r_shunt) <= value <= self.adc_voltage_max / (50 * self._r_shunt)
         self.exec_logger.warning(f'Current pulse is not implemented for the {self.model} board')
 
     def gain_auto(self):
@@ -190,7 +190,6 @@ class Tx(TxAbstract):
         else:
             return self.pwr.battery_voltage
 
-
     def voltage_pulse(self, voltage=None, length=None, polarity=1):
         """ Generates a square voltage pulse
 
diff --git a/ohmpi/hardware_components/mb_2024_0_2.py b/ohmpi/hardware_components/mb_2024_0_2.py
index 0cef544ec18787d829ace411cc3379a3658f6d3b..33fe7ee461234b44c7a711558b96b85f5dc0742f 100644
--- a/ohmpi/hardware_components/mb_2024_0_2.py
+++ b/ohmpi/hardware_components/mb_2024_0_2.py
@@ -21,17 +21,18 @@ SPECS = {'rx': {'model': {'default': os.path.basename(__file__).rstrip('.py')},
                 'mcp_address': {'default': 0x27},
                 'ads_address': {'default': 0x49},
                 'voltage_min': {'default': 10.0},
+                'dg411_gain_ratio': {'default': 1/2},  # lowest resistor value over sum of resistor values
                 'vmn_hardware_offset': {'default': 2500.},
                 },
          'tx': {'model': {'default': os.path.basename(__file__).rstrip('.py')},
                 'adc_voltage_min': {'default': 10.},  # Minimum voltage value used in vmin strategy
                 'adc_voltage_max': {'default': 4500.},  # Maximum voltage on ads1115 used to measure current
-                'voltage_max': {'min': 0., 'default': 12., 'max': 12.},  # Maximum input voltage
+                'voltage_max': {'min': 0., 'default': 12., 'max': 50.},  # Maximum input voltage
                 'data_rate': {'default': 860.},
                 'mcp_address': {'default': 0x21},
                 'ads_address': {'default': 0x48},
                 'compatible_power_sources': {'default': ['pwr_batt', 'dps5005']},
-                'r_shunt':  {'min': 0., 'default': 2.},
+                'r_shunt':  {'min': 0.001, 'default': 2.},
                 'activation_delay': {'default': 0.010},  # Max turn on time of OMRON G5LE-1 5VDC relays
                 'release_delay': {'default': 0.005},  # Max turn off time of OMRON G5LE-1 5VDC relays = 1ms
                 'pwr_latency': {'default': 4.}
@@ -86,10 +87,10 @@ class Tx(Tx_mb_2023):
         self.pin6 = self.mcp_board.get_pin(6)
         self.pin6.direction = Direction.OUTPUT
         self.pin6.value = False
-        self.pin2 = self.mcp_board.get_pin(2) # dsp -
+        self.pin2 = self.mcp_board.get_pin(2)  # dps -
         self.pin2.direction = Direction.OUTPUT
         self.pin2.value = False
-        self.pin3 = self.mcp_board.get_pin(3) # dsp -
+        self.pin3 = self.mcp_board.get_pin(3)  # dps -
         self.pin3.direction = Direction.OUTPUT
         self.pin3.value = False
 
@@ -144,7 +145,9 @@ class Rx(Rx_mb_2023):
         # ADS1115 for voltage measurement (MN)
         self._coef_p2 = 1.
         # Define default DG411 gain
-        self._dg411_gain = 1/2
+        self._dg411_gain_ratio = kwargs['dg411_gain_ratio']
+        self._dg411_gain = self._dg411_gain_ratio
+
         # Define pins for DG411
         self.pin_DG0 = self.mcp_board.get_pin(0)
         self.pin_DG0.direction = Direction.OUTPUT
@@ -170,7 +173,7 @@ class Rx(Rx_mb_2023):
         if self.voltage < self._vmn_hardware_offset :
             self._dg411_gain = 1.
         else:
-            self._dg411_gain = 1/2
+            self._dg411_gain = self._dg411_gain_ratio
         self.exec_logger.debug(f'Setting RX DG411 gain automatically to {self._dg411_gain}')
 
     @property
@@ -184,7 +187,7 @@ class Rx(Rx_mb_2023):
         if self._dg411_gain == 1.:
             self.pin_DG1.value = False  # closed gain 1 active
             self.pin_DG2.value = True  # open gain 0.5 inactive
-        elif self._dg411_gain == 1/2:
+        elif self._dg411_gain == self._dg411_gain_ratio:
             self.pin_DG1.value = True  # closed gain 1 active
             self.pin_DG2.value = False  # open gain 0.5 inactive
 
diff --git a/ohmpi/hardware_components/mux_2024_0_X.py b/ohmpi/hardware_components/mux_2024_0_X.py
index 49c528a19e38c54c56733da2ffa476d46051429f..9334bb032b00518b450fb29598773437feeeb992 100644
--- a/ohmpi/hardware_components/mux_2024_0_X.py
+++ b/ohmpi/hardware_components/mux_2024_0_X.py
@@ -72,9 +72,9 @@ class Mux(MuxAbstract):
         self._roles = kwargs.pop('roles', None)
         if self._roles is None:
             self._roles = {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}  # NOTE: defaults to 4-roles
-        if np.alltrue([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['4_roles'].keys())])]):
+        if np.all([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['4_roles'].keys())])]):
             self._mode = '4_roles'
-        elif np.alltrue([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['2_roles'].keys())])]):
+        elif np.all([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['2_roles'].keys())])]):
             self._mode = '2_roles'
         else:
             self.exec_logger.error(f'Invalid role assignment for {self.model}: {self._roles} !')
diff --git a/ohmpi/hardware_components/pwr_dps5005.py b/ohmpi/hardware_components/pwr_dps5005.py
index dd2b0d8e85c638c40b3dd27feea931303ba13d1b..13fed777042690c38fc74104e46bbbd54028014f 100644
--- a/ohmpi/hardware_components/pwr_dps5005.py
+++ b/ohmpi/hardware_components/pwr_dps5005.py
@@ -11,10 +11,10 @@ SPECS = {'model': {'default': os.path.basename(__file__).rstrip('.py')},
          'voltage': {'default': 12., 'max': 50., 'min': 0.},
          'voltage_min': {'default': 0},
          'voltage_max': {'default': 0},
-         'current_max': {'default': 100.},
+         'current_max': {'default': 60.},
          'current_adjustable': {'default': False},
          'voltage_adjustable': {'default': True},
-         'pwr_latency': {'default': .3}
+         'pwr_latency': {'default': .5}
          }
 
 # TODO: Complete this code... handle modbus connection
@@ -54,14 +54,8 @@ class Pwr(PwrAbstract):
     def current(self, value, **kwargs):
         self.exec_logger.debug(f'Current cannot be set on {self.model}')
 
-    # def turn_off(self):
-    #     self.connection.write_register(0x09, 0)
-    #     self.exec_logger.debug(f'{self.model} is off')
-    #
-    # def turn_on(self):
-    #     self.connection.write_register(0x09, 1)
-    #     self.exec_logger.debug(f'{self.model} is on')
-    #     time.sleep(.3)
+    def _retrieve_voltage(self):
+        self._voltage = self.connection.read_register(0x0002, 2)
 
     @property
     def voltage(self):
@@ -103,3 +97,7 @@ class Pwr(PwrAbstract):
             self.connection.write_register(0x09, 0)
             self._pwr_state = 'off'
             self.exec_logger.debug(f'{self.model} is off')
+
+    def reload_settings(self):
+        # self.voltage(self._voltage)
+        self.current_max(self._current_max)
diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py
index 883412fb7371244dc5160fc61aa384c77d1ecb8b..4c817bacc10f4eb28ce23162319ebde91b98c8af 100644
--- a/ohmpi/hardware_system.py
+++ b/ohmpi/hardware_system.py
@@ -43,7 +43,7 @@ for k, v in rx_module.SPECS['rx'].items():
     except Exception as e:
         print(f'Cannot set value {v} in RX_CONFIG[{k}]:\n{e}')
 
-current_max = np.min([TX_CONFIG['voltage_max']/50/TX_CONFIG['r_shunt'],  # TODO: replace 50 by a TX config
+current_max = np.min([TX_CONFIG['current_max'],  # TODO: replace 50 by a TX config
                       np.min(np.hstack((np.inf, [MUX_CONFIG[i].pop('current_max', np.inf) for i in MUX_CONFIG.keys()])))])
 voltage_max = np.min([TX_CONFIG['voltage_max'],
                       np.min(np.hstack((np.inf, [MUX_CONFIG[i].pop('voltage_max', np.inf) for i in MUX_CONFIG.keys()])))])
@@ -191,7 +191,7 @@ class OhmPiHardware:
         self.exec_logger.event(f'OhmPiHardware\ttx_rx_gain_auto\tbegin\t{datetime.datetime.utcnow()}')
         current, voltage = 0., 0.
         if self.tx.pwr.voltage_adjustable:
-            self.tx.pwr.voltage = vab
+            self.tx.voltage = vab
         if self.tx.pwr.pwr_state == 'off':
             self.tx.pwr.pwr_state = 'on'
             switch_pwr_off = True
@@ -317,94 +317,46 @@ class OhmPiHardware:
             sp = np.mean(mean_vmn[np.ix_(polarity == 1)] + mean_vmn[np.ix_(polarity == -1)]) / 2
             return sp
 
-    # def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5.,
-    #                      vab_max=voltage_max, vmn_min=voltage_min):
-    #     """Estimates best Tx voltage based on different strategies.
-    #     At first a half-cycle is made for a short duration with a fixed
-    #     known voltage. This gives us Iab and Rab. We also measure Vmn.
-    #     A constant c = vmn/iab is computed (only depends on geometric
-    #     factor and ground resistivity, that doesn't change during a
-    #     quadrupole). Then depending on the strategy, we compute which
-    #     vab to inject to reach the minimum/maximum Iab current or
-    #     min/max Vmn.
-    #     This function also compute the polarity on Vmn (on which pin
-    #     of the ADS1115 we need to measure Vmn to get the positive value).
-    #
-    #     Parameters
-    #     ----------
-    #     pulse_duration : float, optional
-    #         Time in seconds for the pulse used to compute Rab.
-    #     strategy : str, optional
-    #         Either:
-    #         - vmax : compute Vab to reach a maximum Iab without exceeding vab_max
-    #         - vmin : compute Vab to reach at least vmn_min
-    #         - constant : apply given Vab
-    #     tx_volt : float, optional
-    #         Voltage to apply for guessing the best voltage. 5 V applied
-    #         by default. If strategy "constant" is chosen, constant voltage
-    #         to applied is "tx_volt".
-    #     vab_max : float, optional
-    #         Maximum injection voltage to apply to tx (used by all strategies)
-    #     vmn_min : float, optional
-    #         Minimum voltage target for rx (used by vmin strategy)
-    #
-    #     Returns
-    #     -------
-    #     vab : float
-    #         Proposed Vab according to the given strategy.
-    #     polarity:
-    #         Polarity of VMN relative to polarity of VAB
-    #     rab : float
-    #         Resistance between injection electrodes
-    #     """
-    #
-    #     vab_max = np.abs(vab_max)
-    #     vmn_min = np.abs(vmn_min)
-    #     vab = np.min([np.abs(tx_volt), vab_max])
-    #     # self.tx.turn_on()
-    #     switch_pwr_off, switch_tx_pwr_off = False, False #TODO: check if these should be moved in kwargs
-    #     if self.tx.pwr_state == 'off':
-    #         self.tx.pwr_state = 'on'
-    #         switch_tx_pwr_off = True
-    #     if self.tx.pwr.pwr_state == 'off':
-    #         self.tx.pwr.pwr_state = 'on'
-    #         switch_pwr_off = True
-    #     if 1. / self.rx.sampling_rate > pulse_duration:
-    #         sampling_rate = 1. / pulse_duration  # TODO: check this...
-    #     else:
-    #         sampling_rate = self.tx.sampling_rate
-    #     self._vab_pulse(vab=vab, duration=pulse_duration, sampling_rate=sampling_rate)  # TODO: use a square wave pulse?
-    #     vmn = np.mean(self.readings[:, 4])
-    #     iab = np.mean(self.readings[:, 3])
-    #     # if np.abs(vmn) is too small (smaller than voltage_min), strategy is not constant and vab < vab_max ,
-    #     # then we could call _compute_tx_volt with a tx_volt increased to np.min([vab_max, tx_volt*2.]) for example
-    #     if strategy == 'vmax':
-    #         # implement different strategies
-    #         if vab < vab_max and iab < current_max:
-    #             vab = vab * np.min([0.9 * vab_max / vab, 0.9 * current_max / iab])  # TODO: check if setting at 90% of max as a safety margin is OK
-    #         self.tx.exec_logger.debug(f'vmax strategy: setting VAB to {vab} V.')
-    #     elif strategy == 'vmin':
-    #         if vab <= vab_max and iab < current_max:
-    #             vab = vab * np.min([0.9 * vab_max / vab, vmn_min / np.abs(vmn), 0.9 * current_max / iab])  # TODO: check if setting at 90% of max as a safety margin is OK
-    #     elif strategy != 'constant':
-    #         self.tx.exec_logger.warning(f'Unknown strategy {strategy} for setting VAB! Using {vab} V')
-    #     else:
-    #         self.tx.exec_logger.debug(f'Constant strategy for setting VAB, using {vab} V')
-    #     # self.tx.turn_off()
-    #     if switch_pwr_off:
-    #         self.tx.pwr.pwr_state = 'off'
-    #     if switch_tx_pwr_off:
-    #         self.tx.pwr_state = 'off'
-    #     rab = (np.abs(vab) * 1000.) / iab
-    #     self.exec_logger.debug(f'RAB = {rab:.2f} Ohms')
-    #     if vmn < 0:
-    #         polarity = -1  # TODO: check if we really need to return polarity
-    #     else:
-    #         polarity = 1
-    #     return vab, polarity, rab
-
-    def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5.,
-                         vab_max=voltage_max, vmn_min=voltage_min, polarities=(1, -1), delay=0.050):
+    def _find_vab(self, vab, iab, vmn, p_max, vab_max, iab_max, vmn_max):
+        iab_mean = np.mean(iab)
+        iab_std = np.std(iab)
+        vmn_mean = np.mean(vmn)
+        vmn_std = np.std(vmn)
+        print(f'iab: ({iab_mean:.5f}, {iab_std:5f}), vmn: ({vmn_mean:.4f}, {vmn_std:.4f})')
+        # bounds on iab
+        iab_upper_bound = iab_mean + 2 * iab_std
+        iab_lower_bound = np.max([0.00001, iab_mean - 2 * iab_std])
+        # bounds on vmn
+        vmn_upper_bound = vmn_mean + 2 * vmn_std
+        vmn_lower_bound = np.max([0.000001, vmn_mean - 2 * vmn_std])
+        # bounds on rab
+        rab_lower_bound = np.max([0.1, np.abs(vab / iab_upper_bound)])
+        rab_upper_bound = np.max([0.1, np.abs(vab / iab_lower_bound)])
+        # bounds on r
+        r_lower_bound = np.max([0.1, np.abs(vmn_lower_bound / iab_upper_bound)])
+        r_upper_bound = np.max([0.1, np.abs(vmn_upper_bound / iab_lower_bound)])
+        # conditions for vab update
+        cond_vmn_max = rab_lower_bound / r_upper_bound * vmn_max
+        cond_p_max = np.sqrt(p_max * rab_lower_bound)
+        cond_iab_max = rab_lower_bound * iab_max
+        print(f'Rab: [{rab_lower_bound:.1f}, {rab_upper_bound:.1f}], R: [{r_lower_bound:.1f},{r_upper_bound:.1f}]')
+        print(f'{k}: [{vab_max:.1f}, {cond_vmn_max:.1f}, {cond_p_max:.1f}, {cond_iab_max:.1f}]')
+        new_vab = np.min([vab_max, cond_vmn_max, cond_p_max, cond_iab_max])
+        if new_vab == vab_max:
+            print('Vab bounded by Vab max')
+        elif new_vab == cond_p_max:
+            print('Vab bounded by P max')
+        elif new_vab == cond_iab_max:
+            print('Vab bounded by Iab max')
+        else:
+            assert new_vab == cond_vmn_max
+            print('Vab bounded by Vmn max')
+
+        return new_vab
+
+    def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5., vab_max=voltage_max,
+                         iab_max=current_max, vmn_max=5., vmn_min=voltage_min, polarities=(1, -1), delay=0.050):
+        # TODO: Optimise how to pass iab_max, vab_max, vmn_min
         """Estimates best Tx voltage based on different strategies.
         At first a half-cycle is made for a short duration with a fixed
         known voltage. This gives us Iab and Rab. We also measure Vmn.
@@ -444,105 +396,64 @@ class OhmPiHardware:
             Resistance between injection electrodes
         """
 
-        # TODO: Get those values from components
-        p_max = 2.5
-        vmn_max = 5.
-        vab_max = 50.
-
-        # define a sill
-        diff_vab_lim = 2.5
-        n_steps = 4
-
-        # Set gain at min
-        self.rx.reset_gain()
-
-        vab_max = np.abs(vab_max)
-        vmn_min = np.abs(vmn_min)
-        k = 0
-        vab_list = np.zeros(n_steps + 1) * np.nan
-        vab = np.min([np.abs(tx_volt), vab_max])
-        vab_list[k] = vab
-        # self.tx.turn_on()
-        switch_pwr_off, switch_tx_pwr_off = False, False  # TODO: check if these should be moved in kwargs
-        if self.tx.pwr_state == 'off':
-            self.tx.pwr_state = 'on'
-            switch_tx_pwr_off = True
-        if self.tx.pwr.pwr_state == 'off':
-            self.tx.pwr.pwr_state = 'on'
-            switch_pwr_off = True
-        if 1. / self.rx.sampling_rate > pulse_duration:
-            sampling_rate = 1. / pulse_duration  # TODO: check this...
-        else:
-            sampling_rate = self.rx.sampling_rate
-        current, voltage = 0., 0.
         if self.tx.pwr.voltage_adjustable:
-            self.tx.pwr.voltage = vab
-        if self.tx.pwr.pwr_state == 'off':
-            self.tx.pwr.pwr_state = 'on'
-            switch_pwr_off = True
-        diff_vab = np.inf
-        while (k < n_steps) and (diff_vab > diff_vab_lim):
-            vabs = []
-            for pol in polarities:
-                # self.tx.polarity = pol
-                # set gains automatically
-                injection = Thread(target=self._inject, kwargs={'injection_duration': 0.2, 'polarity': pol})
-                readings = Thread(target=self._read_values)
-                injection.start()
-                self.tx_sync.wait()
-                readings.start()
-                readings.join()
-                injection.join()
-                v = np.where((self.readings[:, 0] > delay) & (self.readings[:, 2] != 0))[0]  # NOTE : discard data aquired in the first x ms
-                iab = self.readings[v, 3]/1000.
-                vmn = np.abs(self.readings[v, 4]/1000. * self.readings[v, 2])
-                iab_mean = np.mean(iab)
-                iab_std = np.std(iab)
-                vmn_mean = np.mean(vmn)
-                vmn_std = np.std(vmn)
-                print(f'iab: ({iab_mean:.5f}, {iab_std:5f}), vmn: ({vmn_mean:.4f}, {vmn_std:.4f})')
-                # bounds on iab
-                iab_upper_bound = iab_mean + 2 * iab_std
-                iab_lower_bound = np.max([0.00001, iab_mean - 2 * iab_std])
-                # bounds on vmn
-                vmn_upper_bound = vmn_mean + 2 * vmn_std
-                vmn_lower_bound = np.max([0.000001, vmn_mean - 2 * vmn_std])
-                # ax.plot([vab[k]] * 2, [vmn_lower_bound, vmn_upper_bound], '-b')
-                # ax.plot([0, vab_max], [0, vmn_upper_bound * vab_max / vab[k]], '-r', alpha=(k + 1) / n_steps)
-                # ax.plot([0, vab_max], [0, vmn_lower_bound * vab_max / vab[k]], '-g', alpha=(k + 1) / n_steps)
-                # bounds on rab
-                print(f'rab_lb: {vab_list[k] / iab_upper_bound}')
-                rab_lower_bound = np.min([0.1, np.abs(vab_list[k] / iab_upper_bound)])
-                rab_upper_bound = np.min([0.1, np.abs(vab_list[k] / iab_lower_bound)])
-                # bounds on r
-                r_lower_bound = np.min([0.01, np.abs(vmn_lower_bound / iab_upper_bound)])
-                r_upper_bound = np.min([0.01, np.abs(vmn_upper_bound / iab_lower_bound)])
-                # conditions for vab update
-                cond_vmn_max = rab_lower_bound / r_upper_bound * vmn_max
-                cond_p_max = np.sqrt(p_max * rab_lower_bound)
-                new_vab = np.min([vab_max, cond_vmn_max, cond_p_max])
-                diff_vab = np.abs(new_vab - vab_list[k])
-                print(f'Rab: [{rab_lower_bound:.1f}, {rab_upper_bound:.1f}], R: [{r_lower_bound:.1f},{r_upper_bound:.1f}]')
-                print(
-                    f'{k}: [{vab_max:.1f}, {cond_vmn_max:.1f}, {cond_p_max:.1f}], new_vab: {new_vab}, diff_vab: {diff_vab}\n')
-                if new_vab == vab_max:
-                    print('Vab bounded by Vab max')
-                elif new_vab == cond_p_max:
-                    print('Vab bounded by Pmax')
-                elif new_vab == cond_vmn_max:
-                    print('Vab bounded by Vmn max')
-                else:
-                    print('Next step')
-                vabs.append(new_vab)
-                if diff_vab < diff_vab_lim:
-                    print('stopped on vab increase too small')
-                else:
-                    print('stopped on maximum number of steps reached')
-            k = k + 1
-            vab_list[k] = np.min(vabs)
-        vab_opt = vab_list[k]
-        print(f'Selected Vab: {vab_opt:.2f}')
-
+            # Get those values from components
+            p_max = vab_max * iab_max
+
+            # define a sill
+            diff_vab_lim = 2.5
+            n_steps = 4
+
+            # Set gain at min
+            self.rx.reset_gain()
+
+            vab_max = np.abs(vab_max)
+            vmn_min = np.abs(vmn_min)
+            k = 0
+            vab_list = np.zeros(n_steps + 1) * np.nan
+            vab = np.min([np.abs(tx_volt), vab_max])
+            vab_list[k] = vab
+            # self.tx.turn_on()
+            switch_pwr_off, switch_tx_pwr_off = False, False  # TODO: check if these should be moved in kwargs
+            if self.pwr_state == 'off':
+                self.pwr_state = 'on'
+                switch_tx_pwr_off = True
+            self.tx.voltage = vab
+            if self.tx.pwr.pwr_state == 'off':
+                self.tx.pwr.pwr_state = 'on'
+                switch_pwr_off = True
+            if 1. / self.rx.sampling_rate > pulse_duration:
+                sampling_rate = 1. / pulse_duration  # TODO: check this...
+            else:
+                sampling_rate = self.rx.sampling_rate
+            current, voltage = 0., 0.
+            diff_vab = np.inf
+            while (k < n_steps) and (diff_vab > diff_vab_lim):
+                vabs = []
+                self._vab_pulses(vab_list[k], sampling_rate=self.rx.sampling_rate, durations=[0.2, 0.2], polarities=[1, -1])
+                for pulse in range(2):
+                    v = np.where((self.readings[:, 0] > delay) & (self.readings[:, 2] != 0) & (self.readings[:, 1]==pulse))[0]  # NOTE : discard data aquired in the first x ms
+                    iab = self.readings[v, 3]/1000.
+                    vmn = np.abs(self.readings[v, 4]/1000. * self.readings[v, 2])
+                    new_vab = self._find_vab(vab_list[k], iab, vmn, p_max, vab_max, iab_max, vmn_max)
+                    diff_vab = np.abs(new_vab - vab_list[k])
+                    vabs.append(new_vab)
+                    print(f'new_vab: {new_vab}, diff_vab: {diff_vab}\n')
+                    if diff_vab < diff_vab_lim:
+                        print('stopped on vab increase too small')
+                    else:
+                        print('stopped on maximum number of steps reached')
+                k = k + 1
+                vab_list[k] = np.min(vabs)
+                time.sleep(0.5)
+                if self.tx.pwr.voltage_adjustable:
+                    self.tx.voltage = vab_list[k]
+            vab_opt = vab_list[k]
+            # print(f'Selected Vab: {vab_opt:.2f}')
+            # if switch_pwr_off:
+            #     self.tx.pwr.pwr_state = 'off'
+        else:
+            vab_opt = tx_volt
         # if strategy == 'vmax':
         #     # implement different strategies
         #     if vab < vab_max and iab < current_max:
@@ -566,7 +477,7 @@ class OhmPiHardware:
         #     polarity = -1  # TODO: check if we really need to return polarity
         # else:
         #     polarity = 1
-        return vab_opt, None, None
+        return vab_opt
 
     def _plot_readings(self, save_fig=False):
         # Plot graphs
@@ -631,10 +542,10 @@ class OhmPiHardware:
         if sampling_rate is None:
             sampling_rate = RX_CONFIG['sampling_rate']
         if self.tx.pwr.voltage_adjustable:
-            if self.tx.pwr.voltage != vab:
-                self.tx.pwr.voltage = vab
+            if self.tx.voltage != vab:
+                self.tx.voltage = vab
         else:
-            vab = self.tx.pwr.voltage
+            vab = self.tx.voltage
         # reads current and voltage during the pulse
         injection = Thread(target=self._inject, kwargs={'injection_duration': duration, 'polarity': polarity})
         readings = Thread(target=self._read_values, kwargs={'sampling_rate': sampling_rate, 'append': append})
@@ -652,9 +563,9 @@ class OhmPiHardware:
         n_pulses = len(durations)
         self.exec_logger.debug(f'n_pulses: {n_pulses}')
         if self.tx.pwr.voltage_adjustable:
-            self.tx.pwr.voltage = vab
+            self.tx.voltage = vab
         else:
-            vab = self.tx.pwr.voltage
+            vab = self.tx.voltage
         if self.tx.pwr.pwr_state == 'off':
             self.tx.pwr.pwr_state = 'on'
             switch_pwr_off = True
diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py
index 5599f10aa2c9378412dd83a66e85ce162171e7a4..b8fd249e6a55713569123f78bde7a0e0e4374b3a 100644
--- a/ohmpi/ohmpi.py
+++ b/ohmpi/ohmpi.py
@@ -517,7 +517,7 @@ class OhmPi(object):
         bypass_check = kwargs['bypass_check'] if 'bypass_check' in kwargs.keys() else False
         d = {}
         if self.switch_mux_on(quad, bypass_check=bypass_check, cmd_id=cmd_id):
-            #tx_volt,_ ,_ = self._hw._compute_tx_volt(tx_volt=tx_volt, strategy=strategy)
+            tx_volt = self._hw._compute_tx_volt(tx_volt=.5, strategy=strategy, vab_max=50., vmn_max=1.)  # TODO: use tx_volt and vmn_max instead of hardcoded values
             self._hw.vab_square_wave(tx_volt, cycle_duration=injection_duration*2/duty_cycle, cycles=nb_stack, duty_cycle=duty_cycle)
             if 'delay' in kwargs.keys():
                 delay = kwargs['delay']
@@ -536,7 +536,7 @@ class OhmPi(object):
                 "B": quad[1],
                 "M": quad[2],
                 "N": quad[3],
-                "inj time [ms]": injection_duration,  # NOTE: check this
+                "inj time [ms]": injection_duration * 1000.,  # NOTE: check this
                 "Vmn [mV]": Vmn,
                 "I [mA]": I,
                 "R [Ohm]": R,
@@ -545,7 +545,7 @@ class OhmPi(object):
                 "nbStack": nb_stack,
                 "Tx [V]": tx_volt,
                 "CPU temp [degC]": self._hw.ctl.cpu_temperature,
-                "Nb samples [-]": len(self._hw.readings),  # TODO: use only samples after a delay in each pulse
+                "Nb samples [-]": len(self._hw.readings[x,2]),  # TODO: use only samples after a delay in each pulse
                 "fulldata": self._hw.readings[:, [0, -2, -1]],
                 # "I_stack [mA]": i_stack_mean,
                 "I_std [%]": I_std,
@@ -699,26 +699,27 @@ class OhmPi(object):
             if self.on_pi:
                 acquired_data = self.run_measurement(quad=quad, **kwargs)
             else:  # for testing, generate random data
-                sum_vmn = np.random.rand(1)[0] * 1000.
-                sum_i = np.random.rand(1)[0] * 100.
-                cmd_id = np.random.randint(1000)
-                acquired_data = {
-                    "time": datetime.now().isoformat(),
-                    "A": quad[0],
-                    "B": quad[1],
-                    "M": quad[2],
-                    "N": quad[3],
-                    "inj time [ms]": self.settings['injection_duration'] * 1000.,
-                    "Vmn [mV]": sum_vmn,
-                    "I [mA]": sum_i,
-                    "R [ohm]": sum_vmn / sum_i,
-                    "Ps [mV]": np.random.randn(1)[0] * 100.,
-                    "nbStack": self.settings['nb_stack'],
-                    "Tx [V]": np.random.randn(1)[0] * 5.,
-                    "CPU temp [degC]": np.random.randn(1)[0] * 50.,
-                    "Nb samples [-]": self.nb_samples,
-                }
-                self.data_logger.info(acquired_data)
+                # sum_vmn = np.random.rand(1)[0] * 1000.
+                # sum_i = np.random.rand(1)[0] * 100.
+                # cmd_id = np.random.randint(1000)
+                # acquired_data = {
+                #     "time": datetime.now().isoformat(),
+                #     "A": quad[0],
+                #     "B": quad[1],
+                #     "M": quad[2],
+                #     "N": quad[3],
+                #     "inj time [ms]": self.settings['injection_duration'] * 1000.,
+                #     "Vmn [mV]": sum_vmn,
+                #     "I [mA]": sum_i,
+                #     "R [ohm]": sum_vmn / sum_i,
+                #     "Ps [mV]": np.random.randn(1)[0] * 100.,
+                #     "nbStack": self.settings['nb_stack'],
+                #     "Tx [V]": np.random.randn(1)[0] * 5.,
+                #     "CPU temp [degC]": np.random.randn(1)[0] * 50.,
+                #     "Nb samples [-]": self.nb_samples,
+                # }
+                pass
+            self.data_logger.info(acquired_data)
 
             # # switch mux off
             # self.switch_mux_off(quad)
@@ -1023,11 +1024,11 @@ class OhmPi(object):
         pdir = os.path.dirname(__file__)
         # import resipy if available
         try:
-            from scipy.interpolate import griddata
-            import pandas as pd
+            from scipy.interpolate import griddata  # noqa
+            import pandas as pd  #noqa
             import sys
             sys.path.append(os.path.join(pdir, '../../resipy/src/'))
-            from resipy import Project
+            from resipy import Project  # noqa
         except Exception as e:
             self.exec_logger.error('Cannot import ResIPy, scipy or Pandas, error: ' + str(e))
             return []