diff --git a/dev/start_mqtt_html.py b/dev/start_mqtt_html.py
index 5c846e5fe08e5e44c17a0c378b4c02b28572f3eb..4c88810bbadc1b2f9fcf73a9f079bf7d6345b38b 100644
--- a/dev/start_mqtt_html.py
+++ b/dev/start_mqtt_html.py
@@ -2,12 +2,10 @@
 # we need to start the OhmPi instance so that it listens
 # to message from the MQTT broker
 
-import subprocess
-# launch webserver
-
 from ohmpi.utils import change_config
-#change_config('../configs/config_mb_2023.py', verbose=False)
-change_config('../configs/config_mb_2024_0_2__4_mux_2023_dps5005.py', verbose=False)
+change_config('../configs/config_mb_2023.py', verbose=False)
+#change_config('../configs/config_mb_2023_4_mux_2023.py', verbose=False)
+#change_config('../configs/config_mb_2024_0_2__4_mux_2023_dps5005.py', verbose=False)
 
 from ohmpi.ohmpi import OhmPi
 from ohmpi.config import OHMPI_CONFIG
diff --git a/dev/test_inv.py b/dev/test_inv.py
index 40a5791e541d8e8a1412ed8c53209de23f4297bb..2b9d9cef0570b5dc52ac3e5b8b306f531191eefe 100644
--- a/dev/test_inv.py
+++ b/dev/test_inv.py
@@ -14,8 +14,7 @@ k = OhmPi()
 
 # batch inversion
 xzv = k.run_inversion([
-    'measurement_20220206T194752.csv',
-    'measurement_20220206T194852.csv',
+    'measurement_20231014T133508.csv'
 ], reg_mode=0)
 
 # make a contour figure with the output
@@ -24,8 +23,8 @@ axs = [axs] if len(xzv) == 1 else axs
 for i, dic in enumerate(xzv):
     ax = axs[i]
     x, z = np.meshgrid(dic['x'], dic['z'])
-    cax = ax.contourf(x, z, dic['rho'])
-    fig.colorbar(cax, ax=ax, label=r'$\rho$ [$\Omega$.m]')
+    cax = ax.contourf(x, z, np.log10(dic['rho']))
+    fig.colorbar(cax, ax=ax, label=r'$\log_{10}(\rho)$ [$\Omega$.m]')
 plt.show(block=True)
 
 # restore default config
diff --git a/env.sh b/env.sh
index c32402b17072a3840f8da8da28be101a3695717b..395285f96200717649905de2c45829d2085431cd 100755
--- a/env.sh
+++ b/env.sh
@@ -1,3 +1,3 @@
 # execute this file with "source env.sh"
-PYTHONPATH=`pwd`
-source ./ohmpy/bin/activate
+export PYTHONPATH=`pwd`
+source ohmpy/bin/activate
diff --git a/index.html b/index.html
index 2d8c4eb18c74556192c743c7c11acc60a58d8f20..88914ca66ea3ce37f1ac43f43d8eb224504ba276 100755
--- a/index.html
+++ b/index.html
@@ -135,9 +135,9 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                             </div>
                           </div>
                           <div class="form-group row">
-                            <label for="elecSpacing" class="col-sm-2 col-form-label">Electrode spacing [m]</label>
+                            <label for="elec_spacing" class="col-sm-2 col-form-label">Electrode spacing [m]</label>
                             <div class="col-sm-10">
-                              <input type="number" class="form-control" id="elecSpacing", value="1">
+                              <input type="number" class="form-control" id="elec_spacing", value="1">
                             </div>
                           </div>
                       </form>
@@ -181,7 +181,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         let topic_exec = topic + '/exec'
         let topic_data = topic + '/data'
         let hostname = location.hostname
-        let port = 9001
+        let port = 9001  // corresponding listener for the broker
         let clientId = 'ohmpi_0001_html'
         let message = null
         let msg = ''
@@ -209,6 +209,8 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         function onConnectionLost(responseObject) {
             if (responseObject.errorCode !== 0)
                 console.log("onConnectionLost:" + responseObject.errorMessage)
+                console.log("trying to reconnect...")
+                client.connect({onSuccess: onConnect})
         }
         
         function onMessageArrived(message) {
@@ -403,7 +405,8 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                 size: 40,
                 color: [],
                 colorbar: {
-                    title: 'App. res. [Ohm.m]',
+                    title: 'Apparent resistivity [Ohm.m]',
+                    titleside: 'right',
                     cmin: 0,
                     cmax: 100,
                 }
@@ -413,7 +416,6 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
             title: 'Pseudo-section',
             yaxis: {
                 title: 'Pseudo-depth',
-                autorange: 'reversed'
             },
             xaxis: {
                 title: 'X'
@@ -462,7 +464,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
 
         // callback function to draw the plot
         function surveySelectFunc(el) {
-            let elecSpacing = parseFloat(document.getElementById('elecSpacing').value)
+            let elec_spacing = parseFloat(document.getElementById('elec_spacing').value)
             let surveyName = el['target'].value
             let df = data[surveyName]
             if (df != undefined) {
@@ -478,15 +480,15 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                 let app = []
                 for (let i = 0; i < a.length; i++) {
                    
-                    let emin = Math.min(...[a[i], b[i], m[i], n[i]])
-                    let emax = Math.max(...[a[i], b[i], m[i], n[i]])
+                    let emin = Math.min(...[a[i], b[i], m[i], n[i]]) * elec_spacing
+                    let emax = Math.max(...[a[i], b[i], m[i], n[i]]) * elec_spacing
                     let dist = Math.abs(emax - emin)
                     xpos.push(emin + dist/2)
-                    ypos.push(Math.sqrt(2)/2 * dist)
-                    let am = Math.abs(a[i] - m[i])
-                    let bm = Math.abs(b[i] - m[i])
-                    let an = Math.abs(a[i] - n[i])
-                    let bn = Math.abs(a[i] - n[i])
+                    ypos.push(- Math.sqrt(2)/2 * dist)
+                    let am = Math.abs(a[i] - m[i]) * elec_spacing
+                    let bm = Math.abs(b[i] - m[i]) * elec_spacing
+                    let an = Math.abs(a[i] - n[i]) * elec_spacing
+                    let bn = Math.abs(a[i] - n[i]) * elec_spacing
                     let K = (2*Math.PI)/((1/am)-(1/an)-(1/an)+(1/bn))
                     app.push(df['rho'][i]*K)
                     
@@ -496,10 +498,10 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                     // let n = df['n'][i]
 
                     // // compute geometric factor assuming flat 2D surface
-                    // let am = Math.abs(a - m)*elecSpacing
-                    // let bm = Math.abs(b - m)*elecSpacing
-                    // let an = Math.abs(a - n)*elecSpacing
-                    // let bn = Math.abs(b - n)*elecSpacing
+                    // let am = Math.abs(a - m)*elec_spacing
+                    // let bm = Math.abs(b - m)*elec_spacing
+                    // let an = Math.abs(a - n)*elec_spacing
+                    // let bn = Math.abs(b - n)*elec_spacing
                     // let K = 2*Math.PI/((1/am)-(1/bm)-(1/an)+(1/bn))
                     // app.push(df['rho'][i]*K)
                     // //console.log(K) // same as resipy for the wenner case
@@ -511,8 +513,8 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                     // let ab = (abmn[0] + abmn[1])/2
                     // let mn = (abmn[2] + abmn[3])/2
                     // let dist = Math.abs(ab - mn)
-                    // xpos.push((Math.min(ab, mn) + dist/2)*elecSpacing)
-                    // ypos.push((Math.sqrt(2)/2*dist)*elecSpacing)
+                    // xpos.push((Math.min(ab, mn) + dist/2)*elec_spacing)
+                    // ypos.push(- (Math.sqrt(2)/2*dist)*elec_spacing)
                 }
                 console.log('========', app, xpos, ypos)
                 // update the trace and redraw the figure
@@ -718,21 +720,44 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         
         // plot inverted data
         function showInvFunc() {
-            let cmin = document.getElementById('cminInv').value
-            let cmax = document.getElementById('cmaxInv').value
-            
+            let cmin = parseFloat(document.getElementById('cminInv').value)
+            let cmax = parseFloat(document.getElementById('cmaxInv').value)
+            let autocontour = false
+            if (isNaN(cmin) | isNaN(cmax)) {
+                autocontour = true
+            }
+
+            // convert rho to log10(rho)
+            let log10rho = []
+            for (let i = 0; i < invertedData[0]['rho'].length; i++) {
+                let row = invertedData[0]['rho'][i]
+                var arr = []
+                for (let j = 0; j < row.length; j++) {
+                    arr.push(Math.log10(row[j]))
+                }
+                log10rho.push(arr)
+            }
+
             var invData = [{
-                z: invertedData[0]['rho'],
+                z: log10rho,
                 x: invertedData[0]['x'],
                 y: invertedData[0]['z'],
                 type: 'contour',
                 colorscale: 'Viridis',
-                autocontour: true, // set to false if cmin is given
+                autocontour: autocontour,
                 contours: {
                     start: cmin,
                     end: cmax,
-                    size: 10
+                    size: 10,
                 },
+                colorbar:{
+                    title: 'Resistivity (log10) [Ohm.m]',
+                    titleside: 'right',
+                    titlefont: {
+                        size: 14,
+                        family: 'Arial, sans-serif'
+                    }
+                }
             }]
 
             var invLayout = {
@@ -742,7 +767,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                 },
                 xaxis: {
                     title: 'X [m]'
-                }   
+                },
             }
             
             Plotly.newPlot('inv', invData, invLayout, {responsive: true})
@@ -759,10 +784,15 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
             var btn = document.getElementById('invertBtn')
             btn.innerText = 'Inverting...'
             btn.className = 'btn btn-warning'
+            var elec_spacing = parseFloat(document.getElementById('elec_spacing').value)
+            if (isNaN(elec_spacing)) {
+                elec_spacing = 1
+            }
             sendCommand(JSON.stringify({
                     'cmd': 'run_inversion',
                     'kwargs': {
-                        'survey_names': [survey_name + '.csv']
+                        'survey_names': [survey_name + '.csv'],
+                        'elec_spacing': elec_spacing,
                     }
                 }), function(x) {
                     console.log('inversion results', x)
diff --git a/install.sh b/install.sh
index f9835d0c3d4352a0a901b10d71c25b34e76904b2..b63860c8553c9903be2aa8f88bc02f0adc1e05fa 100755
--- a/install.sh
+++ b/install.sh
@@ -32,9 +32,11 @@ sudo systemctl enable mosquitto.service
 echo -e "\n${txtgrn}>>> Broker is installed. Starting now...${txtdef}"
 mosquitto -v 
 
-echo -e "\n${txtgrn}>>> Updating configuration to allow anonymous remote connections...${txtdef}"
+echo -e "\n${txtgrn}>>> Updating configuration to allow anonymous remote connections and websockets...${txtdef}"
+echo "listener 9001" | sudo tee -a /etc/mosquitto/mosquitto.conf
 echo "listener 1883" | sudo tee -a /etc/mosquitto/mosquitto.conf
+echo "protocol websockets" | sudo tee -a /etc/mosquitto/mosquitto.conf
+echo "socket_domain ipv4" | sudo tee -a /etc/mosquitto/mosquitto.conf
 echo "allow_anonymous true" | sudo tee -a /etc/mosquitto/mosquitto.conf
 echo -e "\n${txtgrn}>>> Current configuration stored in /etc/mosquitto/mosquitto.conf is displayed below${txtdef}" 
 cat /etc/mosquitto/mosquitto.conf
-echo -e "\n${txtylw}>>> Adapt it according to your needs!${txtdef}\n"
diff --git a/ohmpi/config.py b/ohmpi/config.py
index abba800afd622de78efddc9ff8fb62855863ab22..f3f566ba70a9fb3bf7797821b95578b28d48a232 100644
--- a/ohmpi/config.py
+++ b/ohmpi/config.py
@@ -1,5 +1,6 @@
 import logging
 from ohmpi.utils import get_platform
+
 from paho.mqtt.client import MQTTv31  # noqa
 
 _, on_pi = get_platform()
@@ -19,55 +20,33 @@ OHMPI_CONFIG = {
 r_shunt = 2.
 HARDWARE_CONFIG = {
     'ctl': {'model': 'raspberry_pi'},
-    'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'},
-    'tx':  {'model': 'mb_2024_0_2',
+    'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'},
+    'tx':  {'model': 'mb_2023_0_X',
              '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',
-             'coef_p2': 1.00,  # slope for conversion for ADS, measurement in V/V
-             'latency': 0.010,  # latency in seconds in continuous mode
-             'sampling_rate': 50,  # number of samples per second
-             'interface_name': 'i2c'
+    'rx':  {'model': 'mb_2023_0_X',
+            'coef_p2': 2.50,  # slope for conversion for ADS, measurement in V/V
+            'sampling_rate': 50.,  # number of samples per second
+            'interface_name': 'i2c',
             },
-    'mux': {'boards':
-                {'mux_A':
-                     {'model': 'mux_2023_0_X',
-                      'mux_tca_address': 0x70,
-                      'roles': {'A': 'X'},
-                      'cabling': {(i, j): ('mux_A', i) for j in ['A'] for i in range(1, 65)},
-                      'voltage_max': 12.},
-                 'mux_B':
-                     {'model': 'mux_2023_0_X',
-                      'mux_tca_address': 0x71,
-                      'roles': {'B': 'X'},
-                      'cabling': {(i, j): ('mux_B', i) for j in ['B'] for i in range(1, 65)},
-                      'voltage_max': 12.},
-                 'mux_M':
-                     {'model': 'mux_2023_0_X',
-                      'mux_tca_address': 0x72,
-                      'roles': {'M': 'X'},
-                      'cabling': {(i, j): ('mux_M', i) for j in ['M'] for i in range(1, 65)},
-                      'voltage_max': 12.},
-                 'mux_N':
-                     {'model': 'mux_2023_0_X',
-                      'mux_tca_address': 0x73,
-                      'roles': {'N': 'X'},
-                      'cabling': {(i, j): ('mux_N', i) for j in ['N'] for i in range(1, 65)},
-                      'voltage_max': 12.},
-                 },
-             'default': {'interface_name': 'i2c_ext',
+    'mux':  # default properties given in config are system properties that will be
+            # overwritten by properties defined in each the board dict below.
+            # if 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
+            {'boards': {},
+             'default': {'interface_name': 'i2c',
                          'voltage_max': 100.,
                          'current_max': 3.}
-            }
-    }
+             }
+}
 
 # SET THE LOGGING LEVELS, MQTT BROKERS AND MQTT OPTIONS ACCORDING TO YOUR NEEDS
 # Execution logging configuration
 EXEC_LOGGING_CONFIG = {
-    'logging_level': logging.INFO,
+    'logging_level': logging.DEBUG,  # TODO: set logging level back to INFO
     'log_file_logging_level': logging.DEBUG,
     'logging_to_console': True,
     'file_name': f'exec{logging_suffix}.log',
diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py
index f3b73220a86e18f5a09aa098f21cac544b808464..dd3c97c308b3d84d062a510b4673366ecdb9d309 100644
--- a/ohmpi/ohmpi.py
+++ b/ohmpi/ohmpi.py
@@ -1061,7 +1061,7 @@ class OhmPi(object):
         elif len(survey_names) > 0 and reg_mode > 0:
             k.createTimeLapseSurvey(fnames, parser=ohmpiParser)
         self.exec_logger.info('ResIPy: generate mesh')
-        k.createMesh('trian')
+        k.createMesh('trian', cl=elec_spacing/5)
         self.exec_logger.info('ResIPy: invert survey')
         k.invert(param=kwargs)
 
@@ -1074,20 +1074,20 @@ class OhmPi(object):
             x = np.linspace(df['X'].min(), df['X'].max(), 20)
             z = np.linspace(df['Z'].min(), df['Z'].max(), 20)
             grid_x, grid_z = np.meshgrid(x, z)
-            grid_z = griddata(df[['X', 'Z']].values, df['Resistivity(ohm.m)'].values,
-                              (grid_x, grid_z), method='linear')
+            grid_v = griddata(df[['X', 'Z']].values, df['Resistivity(ohm.m)'].values,
+                              (grid_x, grid_z), method='nearest')
             
             # set nan to -1
-            inan = np.isnan(grid_z)
-            grid_z[inan] = -1
+            inan = np.isnan(grid_v)
+            grid_v[inan] = -1
 
             xzv.append({
                 'x': x.tolist(),
                 'z': z.tolist(),
-                'rho': grid_z.tolist(),
+                'rho': grid_v.tolist(),
             })
         
-        self.data_logger.info(json.dumps(xzv))  # limited to one survey
+        self.data_logger.info(json.dumps(xzv))
         return xzv
 
     # Properties
diff --git a/run_http_interface.sh b/run_http_interface.sh
index f98f082f9b176adf1a1a0afa429146ab9fb33c16..faa4924d61a7f83f76439c26130c3bdcd560a416 100755
--- a/run_http_interface.sh
+++ b/run_http_interface.sh
@@ -1,7 +1,5 @@
-#!bin/bash
-export PYTHONPATH=/home/$USER/OhmPi
-cd /home/$USER/OhmPi
-source /home/$USER/OhmPi/ohmpy/bin/activate
+export PYTHONPATH=`pwd`
+source $PYTHONPATH/ohmpy/bin/activate
 python dev/start_mqtt_html.py &  # run ohmpi.py to capture the commands
-python3 -m http.server  # run web GUI
+python -m http.server  # run web GUI