diff --git a/ohmpi/config.py b/ohmpi/config.py
index 1c889c6385dbd4ba2d84c32300df5c5e2a70564f..411cad0432beea238964192e620b155581d159bf 100644
--- a/ohmpi/config.py
+++ b/ohmpi/config.py
@@ -17,58 +17,49 @@ OHMPI_CONFIG = {
 }
 
 r_shunt = 2.
-
-# default properties of system components that will be
-# overwritten by properties defined in each the board dict below.
-# if bounds are defined in board specs, values out of specs will be bounded to remain in specs
-# omitted properties in config will be set to board specs default values if they exist
-
 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': 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',
-                 'vmn_hardware_offset': 2500.
-                },
+             '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_2024_0_2',
-                 'latency': 0.010,  # latency in seconds in continuous mode
-                 'sampling_rate': 50,  # number of samples per second
-                 'interface_name': 'i2c',
-                },
+             'latency': 0.010,  # latency in seconds in continuous mode
+             'sampling_rate': 200,  # number of samples per second
+             'interface_name': 'i2c'
+            },
     'mux': {'boards':
-                 {'mux_A':
-                         {'model': 'mux_2023_0_X',
-                          'mux_tca_address': 0x70,
-                          'roles': 'A',
-                          'electrodes': range(1, 65),
-                          },
+                {'mux_A':
+                     {'model': 'mux_2023_0_X',
+                      'mux_tca_address': 0x70,
+                      'roles': 'A',
+                      'electrodes': range(1, 65)},
                  'mux_B':
-                         {'model': 'mux_2023_0_X',
-                          'mux_tca_address': 0x71,
-                          'roles': 'B',
-                          'electrodes': range(1, 65),
-                          },
+                     {'model': 'mux_2023_0_X',
+                      'mux_tca_address': 0x71,
+                      'roles': 'B',
+                      'electrodes': range(1, 65)},
                  'mux_M':
-                         {'model': 'mux_2023_0_X',
-                          'mux_tca_address': 0x72,
-                          'roles': 'M',
-                          'electrodes': range(1, 65),
-                          },
+                     {'model': 'mux_2023_0_X',
+                      'mux_tca_address': 0x72,
+                      'roles': 'M',
+                      'electrodes': range(1, 65)},
                  'mux_N':
-                         {'model': 'mux_2023_0_X',
-                          'mux_tca_address': 0x73,
-                          'roles': 'N',
-                          'electrodes': range(1, 65),
-                          }
+                     {'model': 'mux_2023_0_X',
+                      'mux_tca_address': 0x73,
+                      'roles': 'N',
+                      'electrodes': range(1, 65),
+                      }
                  },
-            'default': {'interface_name': 'i2c',
-                             'voltage_max': 50.,
-                             'current_max': 3.}
-                }
-}
+             'default': {'interface_name': 'i2c_ext',
+                         'voltage_max': 50.,
+                         'current_max': 3.}
+            }
+    }
+
 # SET THE LOGGING LEVELS, MQTT BROKERS AND MQTT OPTIONS ACCORDING TO YOUR NEEDS
 # Execution logging configuration
 EXEC_LOGGING_CONFIG = {
@@ -97,7 +88,7 @@ DATA_LOGGING_CONFIG = {
 SOH_LOGGING_CONFIG = {
     'logging_level': logging.INFO,
     'logging_to_console': True,
-    'log_file_logging_level': logging.INFO,
+    'log_file_logging_level': logging.DEBUG,
     'file_name': f'soh{logging_suffix}.log',
     'max_bytes': 16777216,
     'backup_count': 1024,
diff --git a/ohmpi/hardware_components/abstract_hardware_components.py b/ohmpi/hardware_components/abstract_hardware_components.py
index d79142540f3d32375e796b1e3dfbd5e00c237389..439ce114a4d1463ba4e2041fe2dfd517473cba4a 100644
--- a/ohmpi/hardware_components/abstract_hardware_components.py
+++ b/ohmpi/hardware_components/abstract_hardware_components.py
@@ -463,6 +463,17 @@ class TxAbstract(ABC):
     def measuring(self, mode="off"):
         self._measuring = mode
 
+    def discharge_pwr(self, latency=None):
+        if self.pwr.voltage_adjustable:
+            if latency is None:
+                latency = self.pwr._pwr_discharge_latency
+            self.exec_logger.debug(f'Pwr discharge initiated for {latency} s')
+
+            time.sleep(latency)
+
+        else:
+            self.exec_logger.debug(f'Pwr discharge not supported by {self.pwr.model}')
+
     @property
     def polarity(self):
         return self._polarity
diff --git a/ohmpi/hardware_components/mb_2024_0_2.py b/ohmpi/hardware_components/mb_2024_0_2.py
index 104a47503ecc6fc893063ed62199cf5d7800d0f2..036c74c89fb8534ad41624ba7049d810a27cebe1 100644
--- a/ohmpi/hardware_components/mb_2024_0_2.py
+++ b/ohmpi/hardware_components/mb_2024_0_2.py
@@ -36,7 +36,6 @@ SPECS = {'rx': {'model': {'default': os.path.basename(__file__).rstrip('.py')},
                 '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.}
                 }}
 
 # TODO: move low_battery spec in pwr
@@ -80,8 +79,7 @@ class Tx(Tx_mb_2023):
         super().__init__(**kwargs)
         if not subclass_init:
             self.exec_logger.event(f'{self.model}\ttx_init\tbegin\t{datetime.datetime.utcnow()}')
-        self._pwr_latency = kwargs['pwr_latency']
-        self._current = 0
+
         # Initialize LEDs
         if self.connect:
             self.pin4 = self.mcp_board.get_pin(4)  # OhmPi_run
@@ -117,6 +115,13 @@ class Tx(Tx_mb_2023):
         elif mode == "off":
             self.pin5.value = False
 
+    def discharge_pwr(self, latency=None):
+        if latency is None:
+            latency = self.pwr._pwr_discharge_latency
+
+        time.sleep(latency)
+
+
     def inject(self, polarity=1, injection_duration=None):
         # add leds?
         self.pin6.value = True
@@ -141,7 +146,8 @@ class Tx(Tx_mb_2023):
             self.pin3.value = True
             self.exec_logger.debug(f'Switching DPS on')
             self._pwr_state = 'on'
-            time.sleep(self._pwr_latency) # from pwr specs
+            time.sleep(self.pwr._pwr_latency) # from pwr specs
+
         elif state == 'off':
             self.pin2.value = False
             self.pin3.value = False
diff --git a/ohmpi/hardware_components/mb_2024_1_X.py b/ohmpi/hardware_components/mb_2024_1_X.py
new file mode 100644
index 0000000000000000000000000000000000000000..93fd1fd1a29ea9bfb950eeec31b4b4b4bd49e20b
--- /dev/null
+++ b/ohmpi/hardware_components/mb_2024_1_X.py
@@ -0,0 +1,127 @@
+import datetime
+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
+from busio import I2C  # noqa
+import os
+import time
+from ohmpi.utils import enforce_specs
+from ohmpi.hardware_components.mb_2024_0_2 import Tx as Tx_mb_2024_0_2
+from ohmpi.hardware_components.mb_2024_0_2 import Rx as Rx_mb_2024_0_2
+
+# hardware characteristics and limitations
+# voltages are given in mV, currents in mA, sampling rates in Hz and data_rate in S/s
+SPECS = {'rx': {'model': {'default': os.path.basename(__file__).rstrip('.py')},
+                'sampling_rate': {'min': 0., 'default': 100., 'max': 500.},
+                'data_rate': {'default': 860.},
+                'bias':  {'min': -5000., 'default': 0., 'max': 5000.},
+                'coef_p2': {'default': 1.00},
+                'mcp_address': {'default': 0x27},
+                'ads_address': {'default': 0x49},
+                'voltage_min': {'default': 10.0},
+                'voltage_max': {'default': 5000.0},  # [mV]
+                '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': 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.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
+                }}
+
+# TODO: move low_battery spec in pwr
+
+
+def _ads_1115_gain_auto(channel):  # Make it a class method ?
+    """Automatically sets the gain on a channel
+
+    Parameters
+    ----------
+    channel : ads.ADS1x15
+        Instance of ADS where voltage is measured.
+
+    Returns
+    -------
+    gain : float
+        Gain to be applied on ADS1115.
+    """
+
+    gain = 2 / 3
+    if (abs(channel.voltage) < 2.048) and (abs(channel.voltage) >= 1.024):
+        gain = 2
+    elif (abs(channel.voltage) < 1.024) and (abs(channel.voltage) >= 0.512):
+        gain = 4
+    elif (abs(channel.voltage) < 0.512) and (abs(channel.voltage) >= 0.256):
+        gain = 8
+    elif abs(channel.voltage) < 0.256:
+        gain = 16
+    return gain
+
+
+class Tx(Tx_mb_2024_0_2):
+    """TX Class"""
+    def __init__(self, **kwargs):
+        if 'model' not in kwargs.keys():
+            for key in SPECS['tx'].keys():
+                kwargs = enforce_specs(kwargs, SPECS['tx'], key)
+            subclass_init = False
+        else:
+            subclass_init = True
+        super().__init__(**kwargs)
+        if not subclass_init:
+            self.exec_logger.event(f'{self.model}\ttx_init\tbegin\t{datetime.datetime.utcnow()}')
+
+        self.pin5 = self.mcp_board.get_pin(5)  # power_discharge_relay
+        self.pin5.direction = Direction.OUTPUT
+        self.pin5.value = False
+
+        if not subclass_init:
+            self.exec_logger.event(f'{self.model}\ttx_init\tend\t{datetime.datetime.utcnow()}')
+
+    @property
+    def measuring(self):
+        return self._measuring
+
+    @measuring.setter
+    def measuring(self, mode="off"):
+        self._measuring = mode
+
+
+    def discharge_pwr(self, latency=None):
+        if self.pwr.voltage_adjustable:
+            if latency is None:
+                latency = self.pwr._pwr_discharge_latency
+            self.exec_logger.debug(f'Pwr discharge initiated for {latency} s')
+
+            self.exec_logger.event(f'{self.model}\tpwr_discharge\tend\t{datetime.datetime.utcnow()}')
+            self.pin5.value = True
+            time.sleep(self._activation_delay)
+
+            time.sleep(latency)
+
+            if self.pwr.voltage_adjustable:
+                self.pin5.value = False
+                time.sleep(self._release_delay)
+            self.exec_logger.event(f'{self.model}\tpwr_discharge\tend\t{datetime.datetime.utcnow()}')
+        else:
+            self.exec_logger.debug(f'Pwr discharge not supported by {self.pwr.model}')
+
+class Rx(Rx_mb_2024_0_2):
+    """RX Class"""
+    def __init__(self, **kwargs):
+        if 'model' not in kwargs.keys():
+            for key in SPECS['rx'].keys():
+                kwargs = enforce_specs(kwargs, SPECS['rx'], key)
+            subclass_init = False
+        else:
+            subclass_init = True
+        super().__init__(**kwargs)
diff --git a/ohmpi/hardware_components/pwr_dps5005.py b/ohmpi/hardware_components/pwr_dps5005.py
index fb975984d66d00b9ff22984a87eed5855e0e46b1..edbef03a5b46e0c2e2f0f9aa16ad2894e9823f95 100644
--- a/ohmpi/hardware_components/pwr_dps5005.py
+++ b/ohmpi/hardware_components/pwr_dps5005.py
@@ -16,7 +16,8 @@ SPECS = {'model': {'default': os.path.basename(__file__).rstrip('.py')},
          'current_max_tolerance': {'default': 20}, # in %
          'current_adjustable': {'default': False},
          'voltage_adjustable': {'default': True},
-         'pwr_latency': {'default': 0.}
+         'pwr_latency': {'default': 4.},
+         'pwr_discharge_latency': {'default': 1.}
          }
 
 
@@ -50,8 +51,9 @@ class Pwr(PwrAbstract):
         self.voltage_adjustable = True
         self.current_adjustable = False
         self._current = np.nan
-
+        self._pwr_state = 'off'
         self._pwr_latency = kwargs['pwr_latency']
+        self._pwr_discharge_latency = kwargs['pwr_discharge_latency']
         if not subclass_init:
             self.exec_logger.event(f'{self.model}\tpwr_init\tend\t{datetime.datetime.utcnow()}')
 
@@ -85,6 +87,7 @@ class Pwr(PwrAbstract):
         self.exec_logger.event(f'{self.model}\tset_voltage\tbegin\t{datetime.datetime.utcnow()}')
         if value != self._voltage:
             self.connection.write_register(0x0000, np.round(value, 2), 2)
+            time.sleep(max([0,1 - (self._voltage/value)]))  # wait to enable DPS to reach new voltage as a function of difference between new and previous voltage
         self.exec_logger.event(f'{self.model}\tset_voltage\tend\t{datetime.datetime.utcnow()}')
         self._voltage = value
 
@@ -149,9 +152,9 @@ class Pwr(PwrAbstract):
                 self.exec_logger.event(f'{self.model}\tpwr_state_on\tend\t{datetime.datetime.utcnow()}')
                 # self.current_max(self._current_max)
                 self._pwr_state = 'on'
-                self.exec_logger.event(f'{self.model}\tpwr_latency\tbegin\t{datetime.datetime.utcnow()}')
-                time.sleep(self._pwr_latency)
-                self.exec_logger.event(f'{self.model}\tpwr_latency\tend\t{datetime.datetime.utcnow()}')
+                # self.exec_logger.event(f'{self.model}\tpwr_latency\tbegin\t{datetime.datetime.utcnow()}')
+                # time.sleep(self._pwr_latency)
+                # self.exec_logger.event(f'{self.model}\tpwr_latency\tend\t{datetime.datetime.utcnow()}')
             self.exec_logger.debug(f'{self.model} is on')
 
         elif state == 'off':
diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py
index 000611345f1f2a1b7e123c218a8fc1064a8dda14..be50fedb821195aaf59d84561df66c01168593a1 100644
--- a/ohmpi/hardware_system.py
+++ b/ohmpi/hardware_system.py
@@ -152,7 +152,7 @@ class OhmPiHardware:
         self.tx.pwr = self.pwr
 
         if not self.tx.pwr.voltage_adjustable:
-            self.tx._pwr_latency = 0
+            self.tx.pwr._pwr_latency = 0
         if self.tx.specs['connect']:
             self.tx.polarity = 0
         self.tx.pwr._current_max = self.current_max
@@ -606,10 +606,16 @@ class OhmPiHardware:
             ### if discharge relay manually add on mb_2024_0_2, then should not activate AB relays but simply wait for automatic discharge
             ### if mb_20240_1_X then TX should handle the pwr discharge
 
-            time.sleep(1.0)
+            # time.sleep(1.0)
+            self.tx.discharge_pwr()
 
     def _plot_readings(self, save_fig=False, filename=None):
         # Plot graphs
+        flag = False
+        if self.sp is None:
+            flag = True
+            print('self.sp is None, setting it 0')
+            self.sp = 0
         warnings.filterwarnings("ignore", category=DeprecationWarning)
         fig, ax = plt.subplots(nrows=5, sharex=True)
         ax[0].plot(self.readings[:, 0], self.readings[:, 3], '-r', marker='.', label='iab')
@@ -624,6 +630,8 @@ class OhmPiHardware:
         ax[3].set_ylabel('R [ohm]')
         ax[4].plot(self.readings[v, 0], np.ones_like(self.readings[v, 0]) * self.sp, '-k', marker='.', label='SP [mV]')
         ax[4].set_ylabel('SP [mV]')
+        if flag:  # if it was None, we put it back to None to not interfere with the rest
+            self.sp = None
         # fig.legend()
         if save_fig:
             if filename is None:
diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py
index c5dda7e1977ac3de4196e4146db6b10259b258de..0282c66793f20f6fc46ebdd1ba458ec2cd22da06 100644
--- a/ohmpi/ohmpi.py
+++ b/ohmpi/ohmpi.py
@@ -441,9 +441,9 @@ class OhmPi(object):
     def download_data(self, cmd_id=None):
         """Create a zip of the data folder to then download it easily.
         """
-        datadir = os.path.split(self.settings['export_path'])
-        # datadir = os.path.join(os.path.dirname(__file__), '../data/')
-        make_archive(datadir, 'zip', 'data')
+        datadir, _ = os.path.split(self.settings['export_path'])
+        zippath = os.path.abspath(os.path.join(os.path.dirname(__file__), '../data'))
+        make_archive(zippath, 'zip', datadir)
         self.data_logger.info(json.dumps({'download': 'ready'}))
 
     def shutdown(self, cmd_id=None):
@@ -1065,6 +1065,75 @@ class OhmPi(object):
             export_dir = os.path.split(os.path.dirname(__file__))[0]
             self.settings['export_path'] = os.path.join(export_dir, self.settings['export_path'])
 
+    def export(self, fnames=None, outputdir=None, ftype='bert', elec_spacing=1):
+        """Export surveys stored in the 'data/' folder into an output
+        folder.
+
+        Parameters
+        ----------
+        fnames : list of str, optional
+            List of path (not filename) to survey in ohmpi format to be converted.
+        outputdir : str, optional
+            Path of the output directory where the new files are stored. If None,
+            a directory called 'output' is created in OhmPi.
+        ftype : str, optional
+            Type of export. To be chosen between:
+            - bert (same as pygimli)
+            - pygimli (same as bert)
+            - protocol (for resipy, R2 codes)
+        elec_spacing : float, optional
+            Electrode spacing in meters. Same electrode spacing is assumed.
+        """
+        # handle parameters default values
+        if fnames is None:
+            datadir = os.path.join(os.path.dirname(__file__), '../data/')
+            fnames = [os.path.join(datadir, f) for f in os.listdir(datadir) if f[-4:] == '.csv']
+        if outputdir is None:
+            outputdir = os.path.join(os.path.dirname(__file__), '../output/')
+            if os.path.exists(outputdir) is False:
+                os.mkdir(outputdir)
+        
+        # define parser
+        def ohmpi_parser(fname):
+            df = pd.read_csv(fname)
+            df = df.rename(columns={'A': 'a', 'B': 'b', 'M': 'm', 'N': 'n'})
+            df['vp'] = df['Vmn [mV]']
+            df['i'] = df['I [mA]']
+            df['resist'] = df['vp']/df['i']
+            df['ip'] = np.nan
+            emax = np.max(df[['a', 'b', 'm', 'n']].values)
+            elec = np.zeros((emax, 3))
+            elec[:, 0] = np.arange(emax) * elec_spacing
+            return elec, df[['a', 'b', 'm', 'n', 'vp', 'i', 'resist', 'ip']]
+        
+        # read all files and save them in the desired format
+        for fname in tqdm(fnames):
+            try:
+                elec, df = ohmpi_parser(fname)
+                fout = os.path.join(outputdir, os.path.basename(fname).replace('.csv', ''))
+                if ftype == 'protocol':
+                    fout = fout + '.dat'
+                    with open(fout, 'w') as f:
+                        f.write('{:d}\n'.format(df.shape[0]))
+                    with open(fout, 'a') as f:
+                        df['index'] = np.arange(1, df.shape[0]+1)
+                        df[['index', 'a', 'b', 'm', 'n', 'resist']].to_csv(
+                            f, index=False, sep=' ', header=False)
+                elif ftype == 'bert' or ftype == 'pygimli':
+                    fout = fout + '.dat'
+                    with open(fout, 'w') as f:
+                        f.write('{:d} # positions electrodes\n'.format(elec.shape[0]))
+                        f.write('#\tx\ty\tz\n')
+                        for j in range(elec.shape[0]):
+                            f.write('{:.2f}\t{:.2f}\t{:.2f}\n'.format(*elec[j, :]))
+                        f.write('{:d} # number of data\n'.format(df.shape[0]))
+                        f.write('#\ta\tb\tm\tn\tR\n')
+                    with open(fout, 'a') as f:
+                        df[['a', 'b', 'm', 'n', 'resist']].to_csv(
+                            f, index=False, sep='\t', header=False)
+            except Exception as e:
+                print('export(): could not save file', fname)
+
     def run_inversion(self, survey_names=None, elec_spacing=1, **kwargs):
         """Run a simple 2D inversion using ResIPy (https://gitlab.com/hkex/resipy).
         
@@ -1108,7 +1177,7 @@ class OhmPi(object):
             from scipy.interpolate import griddata  # noqa
             import pandas as pd  # noqa
             import sys
-            sys.path.append(os.path.join(pdir, '/home/pi/resipy/src'))
+            sys.path.append(os.path.join(pdir, '../../resipy/src'))
             from resipy import Project  # noqa
         except Exception as e:
             self.exec_logger.error('Cannot import ResIPy, scipy or Pandas, error: ' + str(e))