diff --git a/ohmpi/hardware_components/mb_2023_0_X.py b/ohmpi/hardware_components/mb_2023_0_X.py
index 04a38fb2ed1c3c009c2c25dccb63144febf067b3..0adb42a24e4de351ff452d7ac1943790f8a2821b 100644
--- a/ohmpi/hardware_components/mb_2023_0_X.py
+++ b/ohmpi/hardware_components/mb_2023_0_X.py
@@ -1,6 +1,4 @@
 import datetime
-import importlib
-# from ohmpi.config import HARDWARE_CONFIG  # TODO: Remove references at config here -> move it in ohmpi_hardware as done for mux_2024
 import adafruit_ads1x15.ads1115 as ads  # noqa
 from adafruit_ads1x15.analog_in import AnalogIn  # noqa
 from adafruit_ads1x15.ads1x15 import Mode  # noqa
@@ -12,12 +10,6 @@ import numpy as np
 import os
 from ohmpi.hardware_components import TxAbstract, RxAbstract
 from ohmpi.utils import enforce_specs
-# ctl_name = HARDWARE_CONFIG['ctl'].pop('board_name', 'raspberry_pi')
-# ctl_connection = HARDWARE_CONFIG['ctl'].pop('connection', 'i2c')
-# ctl_module = importlib.import_module(f'ohmpi.hardware_components.{ctl_name}')
-
-# TX_CONFIG = HARDWARE_CONFIG['tx']
-# RX_CONFIG = HARDWARE_CONFIG['rx']
 
 # hardware characteristics and limitations
 # voltages are given in mV, currents in mA, sampling rates in Hz and data_rate in S/s
@@ -40,48 +32,7 @@ SPECS = {'rx': {'sampling_rate': {'min': 2., 'default': 10., 'max': 100.},
 
 # TODO: move low_battery spec in pwr
 
-# *** RX ***
-# ADC for voltage
-# voltage_adc_voltage_min = 10.  # mV
-# voltage_adc_voltage_max = 4500.  # mV
-# sampling_rate = 20.  # Hz
-# data_rate = 860.  # S/s?
-
-# RX_CONFIG['voltage_min'] = np.min([voltage_adc_voltage_min, RX_CONFIG.pop('voltage_min', np.inf)])  # mV
-# RX_CONFIG['voltage_max'] = np.min([voltage_adc_voltage_max, RX_CONFIG.pop('voltage_max', np.inf)])  # mV
-# RX_CONFIG['sampling_rate'] = RX_CONFIG.pop('sampling_rate', sampling_rate)
-# RX_CONFIG['data_rate'] = RX_CONFIG.pop('data_rate', data_rate)
-# RX_CONFIG['coef_p2'] = RX_CONFIG.pop('coef_p2', 2.5)
-# RX_CONFIG['latency'] = RX_CONFIG.pop('latency', 0.01)
-# RX_CONFIG['bias'] = RX_CONFIG.pop('bias', 0.)
-
-
-# *** TX ***
-# ADC for current
-# current_adc_voltage_min = 10.  # mV
-# current_adc_voltage_max = 4500.  # mV
-# low_battery = 12.  # V (conventional value as it is not measured on this board)
-# tx_mcp_board_address = 0x20  #
-# pwr_voltage_max = 12.  # V
-# pwr_default_voltage = 12.  # V
-# pwr_switch_on_warmup = 0.  # seconds
-
-# TX_CONFIG['current_min'] = np.min([current_adc_voltage_min / (TX_CONFIG['r_shunt'] * 50),
-#                                    TX_CONFIG.pop('current_min', np.inf)])  # mA
-# TX_CONFIG['current_max'] = np.min([current_adc_voltage_max / (TX_CONFIG['r_shunt'] * 50),
-#                                    TX_CONFIG.pop('current_max', np.inf)])  # mA
-# # TX_CONFIG['voltage_max'] = np.min([pwr_voltage_max, TX_CONFIG.pop('voltage_max', np.inf)])  # V
-# TX_CONFIG['voltage_max'] = TX_CONFIG.pop('voltage_max', np.inf)  # V
-# TX_CONFIG['voltage_min'] = -TX_CONFIG['voltage_max']  # V
-# TX_CONFIG['default_voltage'] = np.min([TX_CONFIG.pop('default_voltage', np.inf), TX_CONFIG['voltage_max']])  # V
-# # TX_CONFIG['pwr_switch_on_warm_up'] = TX_CONFIG.pop('pwr_switch_on_warmup', pwr_switch_on_warmup)
-# TX_CONFIG['mcp_board_address'] = TX_CONFIG.pop('mcp_board_address', tx_mcp_board_address)
-# TX_CONFIG['low_battery'] = TX_CONFIG.pop('low_battery', low_battery)
-# TX_CONFIG['latency'] = TX_CONFIG.pop('latency', 0.01)
-# TX_CONFIG['bias'] = TX_CONFIG.pop('bias', 0.)
-
-
-def _gain_auto(channel):
+def _ads_1115_gain_auto(channel):  # Make it a class method ?
     """Automatically sets the gain on a channel
 
     Parameters
@@ -119,7 +70,6 @@ class Tx(TxAbstract):
                 and kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['other']):
             self.exec_logger.warning(f'Incompatible power source specified check config')
             assert kwargs['pwr'] in SPECS['tx']
-        #self.pwr = None  # TODO: set a list of compatible power system with the tx
         self.exec_logger.event(f'{self.board_name}\ttx_init\tbegin\t{datetime.datetime.utcnow()}')
         # self.voltage_max = kwargs['voltage_max']  # TODO: check if used
         self._activation_delay = kwargs['activation_delay']
@@ -148,9 +98,9 @@ class Tx(TxAbstract):
         self.gain = 2 / 3
 
         # MCP23008 pins for LEDs
-        self.pin4 = self.mcp_board.get_pin(4)  # TODO: Delete me? No LED on this version of the board
-        self.pin4.direction = Direction.OUTPUT
-        self.pin4.value = True
+        # self.pin4 = self.mcp_board.get_pin(4)  # TODO: Delete me? No LED on this version of the board
+        # self.pin4.direction = Direction.OUTPUT
+        # self.pin4.value = True
 
         self.exec_logger.event(f'{self.board_name}\ttx_init\tend\t{datetime.datetime.utcnow()}')
 
@@ -170,7 +120,7 @@ class Tx(TxAbstract):
 
     def _adc_gain_auto(self):
         self.exec_logger.event(f'{self.board_name}\ttx_adc_auto_gain\tbegin\t{datetime.datetime.utcnow()}')
-        gain = _gain_auto(AnalogIn(self._ads_current, ads.P0))
+        gain = _ads_1115_gain_auto(AnalogIn(self._ads_current, ads.P0))
         self.exec_logger.debug(f'Setting TX ADC gain automatically to {gain}')
         self.gain = gain
         self.exec_logger.event(f'{self.board_name}\ttx_adc_auto_gain\tend\t{datetime.datetime.utcnow()}')
@@ -294,8 +244,8 @@ class Rx(RxAbstract):
 
     def _adc_gain_auto(self):
         self.exec_logger.event(f'{self.board_name}\trx_adc_auto_gain\tbegin\t{datetime.datetime.utcnow()}')
-        gain_0 = _gain_auto(AnalogIn(self._ads_voltage, ads.P0))
-        gain_2 = _gain_auto(AnalogIn(self._ads_voltage, ads.P2))
+        gain_0 = _ads_1115_gain_auto(AnalogIn(self._ads_voltage, ads.P0))
+        gain_2 = _ads_1115_gain_auto(AnalogIn(self._ads_voltage, ads.P2))
         gain = np.min([gain_0, gain_2])
         self.exec_logger.debug(f'Setting RX ADC gain automatically to {gain}')
         self.gain = gain
diff --git a/ohmpi/hardware_components/mb_2024_0_2.py b/ohmpi/hardware_components/mb_2024_0_2.py
index dc8adbfdd1e02c70275617d6df79562be85a3de3..ffd13b6bc086cefb04b1ae534a64e43101a60fb6 100644
--- a/ohmpi/hardware_components/mb_2024_0_2.py
+++ b/ohmpi/hardware_components/mb_2024_0_2.py
@@ -1,24 +1,12 @@
 import datetime
-import importlib
-from ohmpi.config import HARDWARE_CONFIG  # TODO: Remove references at config here -> move it in ohmpi_hardware as done for mux_2024
 import adafruit_ads1x15.ads1115 as ads  # noqa
 from adafruit_ads1x15.analog_in import AnalogIn  # noqa
 from adafruit_ads1x15.ads1x15 import Mode  # noqa
 from adafruit_mcp230xx.mcp23008 import MCP23008  # noqa
 from digitalio import Direction  # noqa
-import minimalmodbus  # noqa
 from busio import I2C  # noqa
-import time
-import numpy as np
-import os
-from ohmpi.hardware_components import TxAbstract, RxAbstract
-from ohmpi.utils import enforce_specs
-# ctl_name = HARDWARE_CONFIG['ctl'].pop('board_name', 'raspberry_pi')
-# ctl_connection = HARDWARE_CONFIG['ctl'].pop('connection', 'i2c')
-# ctl_module = importlib.import_module(f'ohmpi.hardware_components.{ctl_name}')
-#
-# TX_CONFIG = HARDWARE_CONFIG['tx']
-# RX_CONFIG = HARDWARE_CONFIG['rx']
+from ohmpi.hardware_components.mb_2023_0_X import Tx as Tx_mb_2023
+from ohmpi.hardware_components.mb_2023_0_X import Rx as Rx_mb_2023
 
 # hardware characteristics and limitations
 # voltages are given in mV, currents in mA, sampling rates in Hz and data_rate in S/s
@@ -27,6 +15,7 @@ SPECS = {'rx': {'sampling_rate': {'min': 2., 'default': 10., 'max': 100.},
                 'bias':  {'min': -5000., 'default': 0., 'max': 5000.},
                 'coef_p2': {'default': 2.50},
                 'voltage_min': {'default': 10.0},
+                'vmn_hardware_offset' : {'default': 2500.},
                 },
          'tx': {'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
@@ -34,56 +23,13 @@ SPECS = {'rx': {'sampling_rate': {'min': 2., 'default': 10., 'max': 100.},
                 'data_rate': {'default': 860.},
                 'compatible_power_sources': {'default': 'pwr_batt', 'others' : ['dps5005']},
                 'r_shunt':  {'min': 0., 'default': 2. },
-                'activation_delay': {'default': 0.005},  # Max turn on time of 211EH relays = 5ms
-                'release_delay': {'default': 0.001},  # Max turn off time of 211EH relays = 1ms
+                '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
                 }}
 
 # TODO: move low_battery spec in pwr
-#
-# # hardware characteristics and limitations
-# # *** RX ***
-# # ADC for voltage
-# voltage_adc_voltage_min = 10.  # mV
-# voltage_adc_voltage_max = 4500.  # mV
-# sampling_rate = 20.  # Hz
-# data_rate = 860.  # S/s?
-# rx_mcp_board_address = 0x27
-# RX_CONFIG['voltage_min'] = np.min([voltage_adc_voltage_min, RX_CONFIG.pop('voltage_min', np.inf)])  # mV
-# RX_CONFIG['voltage_max'] = np.min([voltage_adc_voltage_max, RX_CONFIG.pop('voltage_max', np.inf)])  # mV
-# RX_CONFIG['sampling_rate'] = RX_CONFIG.pop('sampling_rate', sampling_rate)
-# RX_CONFIG['data_rate'] = RX_CONFIG.pop('data_rate', data_rate)
-# # RX_CONFIG['coef_p2'] = RX_CONFIG.pop('coef_p2', 2.5)
-# RX_CONFIG['latency'] = RX_CONFIG.pop('latency', 0.01)
-# RX_CONFIG['bias'] = RX_CONFIG.pop('bias', 0.)
-# RX_CONFIG['mcp_board_address'] = TX_CONFIG.pop('mcp_board_address', tx_mcp_board_address)
-#
-#
-# # *** TX ***
-# # ADC for current
-# current_adc_voltage_min = 10.  # mV
-# current_adc_voltage_max = 4500.  # mV
-# low_battery = 12.  # V (conventional value as it is not measured on this board)
-# tx_mcp_board_address = 0x21  #
-# # pwr_voltage_max = 12.  # V
-# # pwr_default_voltage = 12.  # V
-# # pwr_switch_on_warmup = 0.  # seconds
-#
-# TX_CONFIG['current_min'] = np.min([current_adc_voltage_min / (TX_CONFIG['r_shunt'] * 50),
-#                                    TX_CONFIG.pop('current_min', np.inf)])  # mA
-# TX_CONFIG['current_max'] = np.min([current_adc_voltage_max / (TX_CONFIG['r_shunt'] * 50),
-#                                    TX_CONFIG.pop('current_max', np.inf)])  # mA
-# # TX_CONFIG['voltage_max'] = np.min([pwr_voltage_max, TX_CONFIG.pop('voltage_max', np.inf)])  # V
-# TX_CONFIG['voltage_max'] = TX_CONFIG.pop('voltage_max', np.inf)  # V
-# TX_CONFIG['voltage_min'] = -TX_CONFIG['voltage_max']  # V
-# TX_CONFIG['default_voltage'] = np.min([TX_CONFIG.pop('default_voltage', np.inf), TX_CONFIG['voltage_max']])  # V
-# # TX_CONFIG['pwr_switch_on_warm_up'] = TX_CONFIG.pop('pwr_switch_on_warmup', pwr_switch_on_warmup)
-# TX_CONFIG['mcp_board_address'] = TX_CONFIG.pop('mcp_board_address', tx_mcp_board_address)
-# TX_CONFIG['low_battery'] = TX_CONFIG.pop('low_battery', low_battery)
-# TX_CONFIG['latency'] = TX_CONFIG.pop('latency', 0.01)
-# TX_CONFIG['bias'] = TX_CONFIG.pop('bias', 0.)
 
-
-def _gain_auto(channel):
+def _ads_1115_gain_auto(channel):  # Make it a class method ?
     """Automatically sets the gain on a channel
 
     Parameters
@@ -109,246 +55,83 @@ def _gain_auto(channel):
     return gain
 
 
-class Tx(TxAbstract):
+class Tx(Tx_mb_2023):
     def __init__(self, **kwargs):
-        for key in SPECS['tx'].keys():
-            kwargs = enforce_specs(kwargs, SPECS['tx'], key)
-        kwargs.update({'board_name': os.path.basename(__file__).rstrip('.py')})
         super().__init__(**kwargs)
-        assert isinstance(self.connection, I2C)
-        kwargs.update({'pwr': kwargs.pop('pwr', SPECS['tx']['compatible_power_sources']['default'])})
-        if (kwargs['pwr'] != SPECS['tx']['compatible_power_sources']['default']
-                and kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['other']):
-            self.exec_logger.warning(f'Incompatible power source specified check config')
-            assert kwargs['pwr'] in SPECS['tx']
-        # self.pwr = None  # TODO: set a list of compatible power system with the tx
-        self.exec_logger.event(f'{self.board_name}\ttx_init\tbegin\t{datetime.datetime.utcnow()}')
-        # self.voltage_max = kwargs['voltage_max']  # TODO: check if used
-        self._activation_delay = kwargs['activation_delay']
-        self._release_delay = kwargs['release_delay']
-        self.voltage_adjustable = False
-        self.current_adjustable = False
-
         # I2C connexion to MCP23008, for current injection
         self.mcp_board = MCP23008(self.connection, address=0x21)
-        # ADS1115 for current measurement (AB)
-        self._ads_current_address = 0x48
-        self._ads_current_data_rate = kwargs['data_rate']
-        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.adc_voltage_min = kwargs['adc_voltage_min']
-        self.adc_voltage_max = kwargs['adc_voltage_max']
-
-        # Relays for pulse polarity
-        self.pin0 = self.mcp_board.get_pin(0)
-        self.pin0.direction = Direction.OUTPUT
-        self.pin1 = self.mcp_board.get_pin(1)
-        self.pin1.direction = Direction.OUTPUT
-        self.polarity = 0
-        self.gain = 2 / 3
 
         # Initialize LEDs
         self.pin4 = self.mcp_board.get_pin(4)  # Ohmpi_run
         self.pin4.direction = Direction.OUTPUT
         self.pin4.value = True
-
-        self._latency = kwargs.pop('latency', TX_CONFIG['latency'])
-        self._bias = kwargs.pop('bias', TX_CONFIG['bias'])
+        self.pin6 = self.mcp_board.get_pin(6)
+        self.pin6.direction = Direction.OUTPUT
+        self.pin6.value = False
         self.exec_logger.event(f'{self.board_name}\ttx_init\tend\t{datetime.datetime.utcnow()}')
 
-    @property
-    def gain(self):
-        return self._adc_gain
-
-    @gain.setter
-    def gain(self, value):
-        assert value in [2/3, 2, 4, 8, 16]
-        self._adc_gain = value
-        self._ads_current = ads.ADS1115(self.connection, gain=self.adc_gain,
-                                        data_rate=SPECS['tx']['data_rate']['default'],
-                                        address=self._ads_current_address)
-        self._ads_current.mode = Mode.CONTINUOUS
-        self.exec_logger.debug(f'Setting TX ADC gain to {value}')
-
-    def _adc_gain_auto(self):
-        self.exec_logger.event(f'{self.board_name}\ttx_adc_auto_gain\tbegin\t{datetime.datetime.utcnow()}')
-        gain = _gain_auto(AnalogIn(self._ads_current, ads.P0))
-        self.exec_logger.debug(f'Setting TX ADC gain automatically to {gain}')
-        self.gain = gain
-        self.exec_logger.event(f'{self.board_name}\ttx_adc_auto_gain\tend\t{datetime.datetime.utcnow()}')
-
-    def current_pulse(self, **kwargs):
-        TxAbstract.current_pulse(self, **kwargs)
-        self.exec_logger.warning(f'Current pulse is not implemented for the {self.board_name} board')
-
-    @property
-    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')
-        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)
-        self.exec_logger.warning(f'Current pulse is not implemented for the {self.board_name} board')
-
-    def gain_auto(self):
-        self._adc_gain_auto()
-
     def inject(self, polarity=1, injection_duration=None):
         self.polarity = polarity
-        TxAbstract.inject(self, polarity=polarity, injection_duration=injection_duration)
-
-    @property
-    def polarity(self):
-        return self._polarity
-
-    @polarity.setter
-    def polarity(self, polarity):
-        assert polarity in [-1, 0, 1]
-        self._polarity = polarity
-        if polarity == 1:
-            self.pin0.value = True
-            self.pin1.value = False
-            time.sleep(self._activation_delay)  # Max turn on time of 211EH relays = 5ms
-        elif polarity == -1:
-            self.pin0.value = False
-            self.pin1.value = True
-            time.sleep(self._activation_delay)  # Max turn on time of 211EH relays = 5ms
-        else:
-            self.pin0.value = False
-            self.pin1.value = False
-            time.sleep(self._release_delay)  # Max turn off time of 211EH relays = 1ms
-
-    def turn_off(self):
-        self.pwr.turn_off(self)
-
-    def turn_on(self):
-        self.pwr.turn_on(self)
-
-    @property
-    def tx_bat(self):
-        self.soh_logger.warning(f'Cannot get battery voltage on {self.board_name}')
-        self.exec_logger.debug(f'{self.board_name} cannot read battery voltage. Returning default battery voltage.')
-        return self.pwr.voltage
-
-    def voltage_pulse(self, voltage=None, length=None, polarity=1):
-        """ Generates a square voltage pulse
-
-        Parameters
-        ----------
-        voltage: float, optional
-            Voltage to apply in volts, tx_v_def is applied if omitted.
-        length: float, optional
-            Length of the pulse in seconds
-        polarity: 1,0,-1
-            Polarity of the pulse
-        """
-        self.exec_logger.event(f'{self.board_name}\ttx_voltage_pulse\tbegin\t{datetime.datetime.utcnow()}')
-        # self.exec_logger.info(f'injection_duration: {length}')  # TODO: delete me
-        if length is None:
-            length = self.injection_duration
-        if voltage is not None:
-            self.pwr.voltage = voltage
-        self.exec_logger.debug(f'Voltage pulse of {polarity*self.pwr.voltage:.3f} V for {length:.3f} s')
-        self.inject(polarity=polarity, injection_duration=length)
-        self.exec_logger.event(f'{self.board_name}\ttx_voltage_pulse\tend\t{datetime.datetime.utcnow()}')
+        # add leds?
+        self.pin6.value=True
+        Tx_mb_2023.inject(self, polarity=polarity, injection_duration=injection_duration)
+        self.pin6.value = False
 
 
-class Rx(RxAbstract):
+class Rx(Rx_mb_2023):
     def __init__(self, **kwargs):
-        for key in SPECS['rx'].keys():
-            kwargs = enforce_specs(kwargs, SPECS['rx'], key)
-        kwargs.update({'board_name': os.path.basename(__file__).rstrip('.py')})
         super().__init__(**kwargs)
-        assert isinstance(self.connection, I2C)
-
-        self.exec_logger.event(f'{self.board_name}\trx_init\tbegin\t{datetime.datetime.utcnow()}')
-
-        # I2C connexion to MCP23008, for DG411
+        # I2C connexion to MCP23008, for current injection
         self.mcp_board = MCP23008(self.connection, address=0x27)
-
         # ADS1115 for voltage measurement (MN)
-        self._ads_voltage_address = 0x49
-        self._adc_gain = 2/3
-        self._ads_voltage = ads.ADS1115(self.connection, gain=self._adc_gain,
-                                        data_rate=SPECS['rx']['data_rate']['default'],
-                                        address=self._ads_voltage_address)
-        self._ads_voltage.mode = Mode.CONTINUOUS
-        self._coef_p2 = kwargs['coef_p2']
-        # self._voltage_max = kwargs['voltage_max']
-        self._sampling_rate = kwargs['sampling_rate']
-        self._bias = kwargs['bias']
-        self.exec_logger.event(f'{self.board_name}\trx_init\tend\t{datetime.datetime.utcnow()}')
-
+        self._coef_p2 = 1.
+        # Define default DG411 gain
+        self._dg411_gain = 1/2
+        # Define pins for DG411
         self.pin_DG0 = self.mcp_board.get_pin(0)
         self.pin_DG0.direction = Direction.OUTPUT
         self.pin_DG1 = self.mcp_board.get_pin(1)
         self.pin_DG1.direction = Direction.OUTPUT
         self.pin_DG2 = self.mcp_board.get_pin(2)
         self.pin_DG2.direction = Direction.OUTPUT
-
+        # TODO: try to only log this event and not the one created by super()
+        self.exec_logger.event(f'{self.board_name}\trx_init\tend\t{datetime.datetime.utcnow()}')
         self.pin_DG0.value = True  # open
         self.pin_DG1.value = True  # open gain 1 inactive
         self.pin_DG2.value = False  # close gain 0.5 active
-        self._voltage_gain = 0.5
+        self.gain = 1/3
+
+    def _dg411_gain_auto(self):
+        u = ((AnalogIn(self.ads_voltage, ads.P0).voltage * 1000) - self._vmn_hardware_offset) / self.voltage_gain
+        if u < self._vmn_hardware_offset :
+            self.voltage_gain = 1
+        else:
+            self.voltage_gain = 0.5
 
     @property
     def gain(self):
-        return self._adc_gain
+        return self._adc_gain*self._dg411_gain
 
     @gain.setter
     def gain(self, value):
-        assert value in [2/3, 2, 4, 8, 16]
-        self._adc_gain = value
-        self._ads_voltage = ads.ADS1115(self.connection, gain=self.adc_gain,
-                                        data_rate=SPECS['rx']['data_rate']['default'],
-                                        address=self._ads_voltage_address)
-        self._ads_voltage.mode = Mode.CONTINUOUS
-        self.exec_logger.debug(f'Setting RX ADC gain to {value}')
+        assert value in [1/3, 2/3]
+        self._dg411_gain = value / self._adc_gain
+        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:
+            self.pin_DG1.value = True  # closed gain 1 active
+            self.pin_DG2.value = False  # open gain 0.5 inactive
 
-    def _adc_gain_auto(self):
-        self.exec_logger.event(f'{self.board_name}\trx_adc_auto_gain\tbegin\t{datetime.datetime.utcnow()}')
-        gain_0 = _gain_auto(AnalogIn(self._ads_voltage, ads.P0))
-        gain_2 = _gain_auto(AnalogIn(self._ads_voltage, ads.P2))
-        gain = np.min([gain_0, gain_2])
-        self.exec_logger.debug(f'Setting RX ADC gain automatically to {gain}')
-        self.gain = gain
-        self.exec_logger.event(f'{self.board_name}\trx_adc_auto_gain\tend\t{datetime.datetime.utcnow()}')
 
     def gain_auto(self):
-        self._adc_gain_auto()
+        self._dg411_gain_auto()
+
     @property
     def voltage(self):
         """ Gets the voltage VMN in Volts
         """
         self.exec_logger.event(f'{self.board_name}\trx_voltage\tbegin\t{datetime.datetime.utcnow()}')
-        u = -AnalogIn(self._ads_voltage, ads.P0, ads.P1).voltage * self._coef_p2 * 1000. - self._bias  # TODO: check if it should be negated
+        u = (AnalogIn(self._ads_voltage, ads.P0).voltage * self._coef_p2 * 1000. - self._vmn_hardware_offset) / self._dg411_gain - self._bias  # TODO: check how to handle bias and _vmn_hardware_offset
         self.exec_logger.event(f'{self.board_name}\trx_voltage\tend\t{datetime.datetime.utcnow()}')
         return u
-
-    @property
-    def voltage_gain(self):
-        return self._voltage_gain
-
-    @voltage_gain.setter
-    def voltage_gain(self,value):
-        assert value in [0.5, 1]
-        self._voltage_gain = value
-        if self._voltage_gain == 1:
-            self.pin_DG1.value = False  # closed gain 1 active
-            self.pin_DG2.value = True  # open gain 0.5 inactive
-        elif self._voltage_gain == 0.5:
-            self.pin_DG1.value = True  # closed gain 1 active
-            self.pin_DG2.value = False  # open gain 0.5 inactive
-
-    def voltage_gain_auto(self):
-        u = ((AnalogIn(self.ads_voltage, ads.P0).voltage * 1000) - self.vmn_hardware_offset) / self.voltage_gain
-        if abs(vmn1) < 2500 and abs(vmn2) < 2500:  ###TODO change voltage gain auto logic
-            self.voltage_gain = 1
-        else:
-            self.voltage_gain = 0.5
diff --git a/ohmpi/hardware_components/mux_2023_0_X.py b/ohmpi/hardware_components/mux_2023_0_X.py
index be1ec5a1ac30ab4f686e015a0c652fe863e274ee..0686a044a8483fa35d85391022d672ab070b7e6b 100644
--- a/ohmpi/hardware_components/mux_2023_0_X.py
+++ b/ohmpi/hardware_components/mux_2023_0_X.py
@@ -1,12 +1,10 @@
-import time
-
-from ohmpi.config import HARDWARE_CONFIG
 import os
 import numpy as np
 from ohmpi.hardware_components import MuxAbstract
 import adafruit_tca9548a  # noqa
 from adafruit_mcp230xx.mcp23017 import MCP23017  # noqa
 from digitalio import Direction  # noqa
+from busio import I2C  # noqa
 
 # hardware characteristics and limitations
 SPECS = {'voltage_max': 50., 'current_max': 3., 'activation_delay': 0.01, 'release_delay': 0.005}
diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py
index 46332b0a65e4b51bf16a30c35a9200c7d55f455f..7436bf21fb9934998a6dd65883cb251b90164a43 100644
--- a/ohmpi/hardware_system.py
+++ b/ohmpi/hardware_system.py
@@ -295,7 +295,7 @@ 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,
+    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