diff --git a/dev/test_mb_2023_4_mux_2023.py b/dev/test_mb_2023_4_mux_2023.py
index 59bc6377a5bcf59a70dcdb99595c657af5320239..80ff435b8795ec55cefa96ecccbd3564e43acaf8 100644
--- a/dev/test_mb_2023_4_mux_2023.py
+++ b/dev/test_mb_2023_4_mux_2023.py
@@ -87,9 +87,9 @@ if within_ohmpi:
     # k.get_data()
     k.load_sequence(os.path.join(os.path.dirname(__file__), '../sequences/test_circuit_1423.txt'))
     k.reset_mux()
-    k.run_multiple_sequences(sequence_delay=20, nb_meas=3)
+    # k.run_multiple_sequences(sequence_delay=20, nb_meas=3)
     # k.run_sequence(injection_duration=0.2)
-    # k.rs_check(tx_volt=4)
+    k.rs_check(tx_volt=4)
     # k.test_mux(mux_id=None, activation_time=0.2)
     # k._hw.switch_mux([A, B, M, N], state='on')
     # k._hw.vab_square_wave(12.,1., cycles=2)
diff --git a/index.html b/index.html
index 65ed3d53cd06e407221ad36d704db82298d43b20..7d7a3a4442b2ee1b2ec006a33980df3f8fc78cb0 100755
--- a/index.html
+++ b/index.html
@@ -220,8 +220,24 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
                     console.log('DATA LOG:', payload)
                     let ddic = JSON.parse(payload.split('INFO:')[1])
 
-                    // check cmd_id is any
-                    processMessage(ddic)
+                    // RS check data
+                    if ('rsdata' in ddic) {
+                        rsdata[0]['x'].push(ddic['rsdata']['A']), //, + '-' + ddic['rsdata']['B'],
+                        rsdata[0]['y'].push(ddic['rsdata']['rs']),
+                        Plotly.redraw('rs')
+                    
+                    } else if ('download' in ddic) {
+                        let dwl = document.getElementById('download')
+                        dwl.setAttribute('href', serverUrl + '/data.zip')
+                        dwl.setAttribute('download', 'data.zip')
+                        dwl.click()
+                    } else { // data or results from inversion
+                        processMessage(ddic)
+                    }
+
+                    if ('status' in  ddic) {
+                        document.getElementById('output').value = ddic['status']
+                    }
 
                     // usually these don't have a cmd_id so we are not sure when
 
@@ -488,7 +504,13 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         let surveySelect = document.getElementById('surveySelect')
 
         // bar chart for contact resistance
-        let rsdata = []
+        let rsdata = [{
+            'x': [],
+            'y': [],
+            name: 'RS',
+            type: 'bar',
+            }
+        ]
         let rslayout = {
             title: 'Contact resistances',
             yaxis: {
@@ -518,7 +540,12 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         
         // clear RS graph
         function rsClearBtnFunc() {
-            rsdata = []
+            rsdata = [{
+            'x': [],
+            'y': [],
+            name: 'RS',
+            type: 'bar',
+            }]
             Plotly.newPlot('rs', rsdata, rslayout, {responsive: true})
         }
         let rsClearBtn = document.getElementById('rsClearBtn')
@@ -539,7 +566,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
             //if (('status' in ddic) | ('data' in ddic)) {
             if (ddic.constructor == Object) {  // it's a dictionnary
                 // acquisition related
-                processData(ddic)
+                processData(ddic)                
             } else {
                 // inversion related
                 invertedData = ddic
@@ -769,11 +796,8 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl
         
         // download data
         function downloadBtnFunc() {
-            sendCommand('{"cmd": "download"}', function(x) {
-                let dwl = document.getElementById('download')
-                dwl.setAttribute('href', serverUrl + '/data.zip')
-                dwl.setAttribute('download', 'data.zip')
-                dwl.click()
+            sendCommand('{"cmd": "download_data"}', function(x) {
+                console.log(x)
             })
         }
         let downloadBtn = document.getElementById('downloadBtn')
diff --git a/ohmpi/http_interface.py b/ohmpi/http_interface.py
index 7fd04e37d9e8ae509f56a8e85ea043bd6b22ac73..2b7e6a6534495a6757ba03890fa4220f512cde8a 100644
--- a/ohmpi/http_interface.py
+++ b/ohmpi/http_interface.py
@@ -2,77 +2,74 @@ from http.server import SimpleHTTPRequestHandler, HTTPServer
 import os
 import json
 import uuid
-from config import MQTT_CONTROL_CONFIG, OHMPI_CONFIG
-from termcolor import colored
-import pandas as pd
+# from config import MQTT_CONTROL_CONFIG, OHMPI_CONFIG
+# from termcolor import colored
+# import pandas as pd
 import shutil
 import time
-import numpy as np
+# import numpy as np
 from io import StringIO
 import threading
-import paho.mqtt.client as mqtt_client
-import paho.mqtt.publish as publish
+# import paho.mqtt.client as mqtt_client
+# import paho.mqtt.publish as publish
 
 hostName = "0.0.0.0"  # for AP mode (not AP-STA)
-serverPort = 8080
+serverPort = 8000
 
 # https://gist.github.com/MichaelCurrie/19394abc19abd0de4473b595c0e37a3a
 
-ctrl_broker = MQTT_CONTROL_CONFIG['hostname']
-publisher_config = MQTT_CONTROL_CONFIG.copy()
-publisher_config['topic'] = MQTT_CONTROL_CONFIG['ctrl_topic']
-publisher_config.pop('ctrl_topic')
-
-print(colored(f"Sending commands control topic {MQTT_CONTROL_CONFIG['ctrl_topic']} on {MQTT_CONTROL_CONFIG['hostname']} broker."))
-cmd_id = None
-received = False
-rdic = {}
-
-
-# set controller globally as __init__ seem to be called for each request and so we subscribe again each time (=overhead)
-controller = mqtt_client.Client(f"ohmpi_{OHMPI_CONFIG['id']}_interface_http", clean_session=False)  # create new instance
-print(colored(f"Connecting to control topic {MQTT_CONTROL_CONFIG['ctrl_topic']} on {MQTT_CONTROL_CONFIG['hostname']} broker", 'blue'))
-trials = 0
-trials_max = 10
-broker_connected = False
-while trials < trials_max:
-    try:
-        controller.username_pw_set(MQTT_CONTROL_CONFIG['auth'].get('username'),
-                                        MQTT_CONTROL_CONFIG['auth']['password'])
-        controller.connect(MQTT_CONTROL_CONFIG['hostname'])
-        trials = trials_max
-        broker_connected = True
-    except Exception as e:
-        print(f'Unable to connect control broker: {e}')
-        print('trying again to connect to control broker...')
-        time.sleep(2)
-        trials += 1
-if broker_connected:
-    print(f"Subscribing to control topic {MQTT_CONTROL_CONFIG['ctrl_topic']}")
-    controller.subscribe(MQTT_CONTROL_CONFIG['ctrl_topic'], MQTT_CONTROL_CONFIG['qos'])
-else:
-    print(f"Unable to connect to control broker on {MQTT_CONTROL_CONFIG['hostname']}")
-    controller = None
-
-
-# start a listener for acknowledgement
-def _control():
-    def on_message(client, userdata, message):
-        global cmd_id, rdic, received
-
-        command = json.loads(message.payload.decode('utf-8'))
-        #print('++++', cmd_id, received, command)
-        if ('reply' in command.keys()) and (command['cmd_id'] == cmd_id):
-            print(f'Acknowledgement reception of command {command} by OhmPi')
-           # print('oooooooooook', command['reply'])
-            received = True
-            #rdic = command
-
-    controller.on_message = on_message
-    controller.loop_forever()
+# ctrl_broker = MQTT_CONTROL_CONFIG['hostname']
+# publisher_config = MQTT_CONTROL_CONFIG.copy()
+# publisher_config['topic'] = MQTT_CONTROL_CONFIG['ctrl_topic']
+# publisher_config.pop('ctrl_topic')
+
+# print(colored(f"Sending commands control topic {MQTT_CONTROL_CONFIG['ctrl_topic']} on {MQTT_CONTROL_CONFIG['hostname']} broker."))
+# cmd_id = None
+# received = False
+# rdic = {}
+
+
+# # set controller globally as __init__ seem to be called for each request and so we subscribe again each time (=overhead)
+# controller = mqtt_client.Client(f"ohmpi_{OHMPI_CONFIG['id']}_interface_http", clean_session=False)  # create new instance
+# print(colored(f"Connecting to control topic {MQTT_CONTROL_CONFIG['ctrl_topic']} on {MQTT_CONTROL_CONFIG['hostname']} broker", 'blue'))
+# trials = 0
+# trials_max = 10
+# broker_connected = False
+# while trials < trials_max:
+#     try:
+#         controller.username_pw_set(MQTT_CONTROL_CONFIG['auth'].get('username'),
+#                                         MQTT_CONTROL_CONFIG['auth']['password'])
+#         controller.connect(MQTT_CONTROL_CONFIG['hostname'])
+#         trials = trials_max
+#         broker_connected = True
+#     except Exception as e:
+#         print(f'Unable to connect control broker: {e}')
+#         print('trying again to connect to control broker...')
+#         time.sleep(2)
+#         trials += 1
+# if broker_connected:
+#     print(f"Subscribing to control topic {MQTT_CONTROL_CONFIG['ctrl_topic']}")
+#     controller.subscribe(MQTT_CONTROL_CONFIG['ctrl_topic'], MQTT_CONTROL_CONFIG['qos'])
+# else:
+#     print(f"Unable to connect to control broker on {MQTT_CONTROL_CONFIG['hostname']}")
+#     controller = None
+
+
+# # start a listener for acknowledgement
+# def _control():
+#     def on_message(client, userdata, message):
+#         global cmd_id, rdic, received
+
+#         command = json.loads(message.payload.decode('utf-8'))
+#         if ('reply' in command.keys()) and (command['cmd_id'] == cmd_id):
+#             print(f'Acknowledgement reception of command {command} by OhmPi')
+#             received = True
+
+#     controller.on_message = on_message
+#     controller.loop_forever()
     
-t = threading.Thread(target=_control)
-t.start()
+# t = threading.Thread(target=_control)
+# t.start()
 
 
 class MyServer(SimpleHTTPRequestHandler):
@@ -124,64 +121,64 @@ class MyServer(SimpleHTTPRequestHandler):
         cmd_id = uuid.uuid4().hex
         dic = json.loads(self.rfile.read(int(self.headers['Content-Length'])))
         rdic = {} # response dictionary
-        if dic['cmd'] == 'run_multiple_sequences':
-            payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'run_multiple_sequences'})
-            publish.single(payload=payload, **publisher_config)
-        elif dic['cmd'] == 'interrupt':
-            payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'interrupt'})
-            publish.single(payload=payload, **publisher_config)
-        elif dic['cmd'] == 'getData':
-            # get all .csv file in data folder
-            fnames = [fname for fname in os.listdir('data/') if fname[-4:] == '.csv']
-            ddic = {}
-            for fname in fnames:
-                if ((fname != 'readme.txt')
-                    and ('_rs' not in fname)
-                    and (fname.replace('.csv', '') not in dic['surveyNames'])):
-                    df = pd.read_csv('data/' + fname)
-                    ddic[fname.replace('.csv', '')] = {
-                        'a': df['A'].tolist(),
-                        'b': df['B'].tolist(),
-                        'm': df['M'].tolist(),
-                        'n': df['N'].tolist(),
-                        'rho': df['R [ohm]'].tolist(),
-                    }
-            rdic['data'] = ddic
-        elif dic['cmd'] == 'removeData':
-            shutil.rmtree('data')
-            os.mkdir('data')
-        elif dic['cmd'] == 'update_settings':
-            if 'sequence' in dic['config'].keys() and dic['config']['sequence'] is not None:
-                sequence = dic['config'].pop('sequence', None)
-                sequence = np.loadtxt(StringIO(sequence)).astype(int).tolist()  # list of list
-                # we pass the sequence as a list of list as this object is easier to parse for the json.loads()
-                # of ohmpi._process_commands()
-                payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'set_sequence', 'kwargs': {'sequence': sequence}})
-                print('payload ===', payload)
-                publish.single(payload=payload, **publisher_config)
-            payload = json.dumps({'cmd_id': cmd_id + '_settings', 'cmd': 'update_settings', 'kwargs': {'config': dic['config']}})
-            cdic = dic['config']
-            publish.single(payload=payload, **publisher_config)
-        elif dic['cmd'] == 'invert':
-            pass
-        elif dic['cmd'] == 'getResults':
-            pass
-        elif dic['cmd'] == 'rsCheck':
-            payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'rs_check'})
-            publish.single(payload=payload, **publisher_config)
-
-        elif dic['cmd'] == 'getRsCheck':
-            fnames = sorted([fname for fname in os.listdir('data/') if fname[-7:] == '_rs.csv'])
-            if len(fnames) > 0:
-                df = pd.read_csv('data/' + fnames[-1])
-                ddic = {
-                    'AB': (df['A'].astype('str') + '-' + df['B'].astype(str)).tolist(),
-                    'res': df['RS [kOhm]'].tolist()
-                }
-            else:
-                ddic = {}
-            rdic['data'] = ddic
-        elif dic['cmd'] == 'download':
+        # if dic['cmd'] == 'run_multiple_sequences':
+        #     payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'run_multiple_sequences'})
+        #     publish.single(payload=payload, **publisher_config)
+        # elif dic['cmd'] == 'interrupt':
+        #     payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'interrupt'})
+        #     publish.single(payload=payload, **publisher_config)
+        # elif dic['cmd'] == 'getData':
+        #     # get all .csv file in data folder
+        #     fnames = [fname for fname in os.listdir('data/') if fname[-4:] == '.csv']
+        #     ddic = {}
+        #     for fname in fnames:
+        #         if ((fname != 'readme.txt')
+        #             and ('_rs' not in fname)
+        #             and (fname.replace('.csv', '') not in dic['surveyNames'])):
+        #             df = pd.read_csv('data/' + fname)
+        #             ddic[fname.replace('.csv', '')] = {
+        #                 'a': df['A'].tolist(),
+        #                 'b': df['B'].tolist(),
+        #                 'm': df['M'].tolist(),
+        #                 'n': df['N'].tolist(),
+        #                 'rho': df['R [ohm]'].tolist(),
+        #             }
+        #     rdic['data'] = ddic
+        # elif dic['cmd'] == 'removeData':
+        #     shutil.rmtree('data')
+        #     os.mkdir('data')
+        # elif dic['cmd'] == 'update_settings':
+        #     if 'sequence' in dic['config'].keys() and dic['config']['sequence'] is not None:
+        #         sequence = dic['config'].pop('sequence', None)
+        #         sequence = np.loadtxt(StringIO(sequence)).astype(int).tolist()  # list of list
+        #         # we pass the sequence as a list of list as this object is easier to parse for the json.loads()
+        #         # of ohmpi._process_commands()
+        #         payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'set_sequence', 'kwargs': {'sequence': sequence}})
+        #         print('payload ===', payload)
+        #         publish.single(payload=payload, **publisher_config)
+        #     payload = json.dumps({'cmd_id': cmd_id + '_settings', 'cmd': 'update_settings', 'kwargs': {'config': dic['config']}})
+        #     cdic = dic['config']
+        #     publish.single(payload=payload, **publisher_config)
+        # elif dic['cmd'] == 'invert':
+        #     pass
+        # elif dic['cmd'] == 'getResults':
+        #     pass
+        # elif dic['cmd'] == 'rsCheck':
+        #     payload = json.dumps({'cmd_id': cmd_id, 'cmd': 'rs_check'})
+        #     publish.single(payload=payload, **publisher_config)
+
+        # elif dic['cmd'] == 'getRsCheck':
+        #     fnames = sorted([fname for fname in os.listdir('data/') if fname[-7:] == '_rs.csv'])
+        #     if len(fnames) > 0:
+        #         df = pd.read_csv('data/' + fnames[-1])
+        #         ddic = {
+        #             'AB': (df['A'].astype('str') + '-' + df['B'].astype(str)).tolist(),
+        #             'res': df['RS [kOhm]'].tolist()
+        #         }
+        #     else:
+        #         ddic = {}
+        #     rdic['data'] = ddic
+        if dic['cmd'] == 'download':
             shutil.make_archive('data', 'zip', 'data')
         elif dic['cmd'] == 'shutdown':
             print('shutting down...')
diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py
index d75f076683fafa70aa7e4f7466f13ba783a09c42..5599f10aa2c9378412dd83a66e85ce162171e7a4 100644
--- a/ohmpi/ohmpi.py
+++ b/ohmpi/ohmpi.py
@@ -15,7 +15,7 @@ from copy import deepcopy
 import numpy as np
 import csv
 import time
-from shutil import rmtree
+from shutil import rmtree, make_archive
 from threading import Thread
 from inspect import getmembers, isfunction
 from datetime import datetime
@@ -435,6 +435,28 @@ class OhmPi(object):
         else:
             self.exec_logger.warning('Not on Raspberry Pi, skipping reboot...')
 
+    def download_data(self, cmd_id=None):
+        """Create a zip of the data folder.
+        """
+        datadir = os.path.join(os.path.dirname(__file__), '../data/')
+        make_archive(datadir, 'zip', 'data')
+        self.data_logger.info(json.dumps({'download': 'ready'}))
+
+    def shutdown(self, cmd_id=None):
+        """Shutdown the Raspberry Pi
+
+        Parameters
+        ----------
+        cmd_id : str, optional
+            Unique command identifier
+        """
+
+        if self.on_pi:
+            self.exec_logger.info(f'Restarting pi following command {cmd_id}...')
+            os.system('poweroff')
+        else:
+            self.exec_logger.warning('Not on Raspberry Pi, skipping shutdown...')
+
     def run_measurement(self, quad=None, nb_stack=None, injection_duration=None, duty_cycle=None,
                         autogain=True, strategy='constant', tx_volt=5., best_tx_injtime=0.1,
                         cmd_id=None, **kwargs):
@@ -736,7 +758,9 @@ class OhmPi(object):
     #  -> might be a problem at B (cf what we did with WofE)
     def rs_check(self, tx_volt=5., cmd_id=None):
         # TODO: add a default value for rs-check in config.py import it in ohmpi.py and add it in rs_check definition
-        """Checks contact resistances
+        """Checks contact resistances.
+        Strategy: we just open A and B, measure the current and using vAB set or
+        assumed (12V assumed for battery), we compute Rab.
 
         Parameters
         ----------
@@ -751,7 +775,7 @@ class OhmPi(object):
         # create custom sequence where MN == AB
         # we only check the electrodes which are in the sequence (not all might be connected)
         if self.sequence is None:
-            quads = np.array([[1, 2, 1, 2]], dtype=np.uint32)
+            quads = np.array([[1, 2, 0, 0]], dtype=np.uint32)
         else:
             elec = np.sort(np.unique(self.sequence.flatten()))  # assumed order
             quads = np.vstack([
@@ -776,27 +800,40 @@ class OhmPi(object):
         # measure all quad of the RS sequence
         for i in range(0, quads.shape[0]):
             quad = quads[i, :]  # quadrupole
-            self.switch_mux_on(quad, bypass_check=True)  # put before raising the pins (otherwise conflict i2c)
-            d = self.run_measurement(quad=quad, nb_stack=1, injection_duration=0.2, tx_volt=tx_volt, autogain=False,
-                                     bypass_check=True)
+            self._hw.switch_mux(electrodes=list(quads[i, :2]), roles=['A', 'B'], state='on')
+            self._hw._vab_pulse(duration=0.2)
+            current = self._hw.readings[-1, 3]
+            voltage = self._hw.tx.pwr.voltage * 1000
+            time.sleep(0.2)
+
+            # self.switch_mux_on(quad, bypass_check=True)  # put before raising the pins (otherwise conflict i2c)
+            # d = self.run_measurement(quad=quad, nb_stack=1, injection_duration=0.2, tx_volt=tx_volt, autogain=False,
+            #                          bypass_check=True)
 
             # if self._hw.tx.voltage_adjustable:
             #     voltage = self._hw.tx.voltage  # imposed voltage on dps
             # else:
             #     voltage = self._hw.rx.voltage
 
-            voltage = self._hw.rx.voltage
-            current = self._hw.tx.current
+            # voltage = self._hw.rx.voltage
+            # current = self._hw.tx.current
 
             # compute resistance measured (= contact resistance)
-            resist = abs(voltage / current) / 1000.
+            resist = abs(voltage / current) / 1000 # kOhm
             # print(str(quad) + '> I: {:>10.3f} mA, V: {:>10.3f} mV, R: {:>10.3f} kOhm'.format(
             #    current, voltage, resist))
-            msg = f'Contact resistance {str(quad):s}: I: {current * 1000.:>10.3f} mA, ' \
-                  f'V: {voltage :>10.3f} mV, ' \
-                  f'R: {resist :>10.3f} kOhm'
-
-            self.exec_logger.info(msg)
+            # msg = f'Contact resistance {str(quad):s}: I: {current :>10.3f} mA, ' \
+            #       f'V: {voltage :>10.3f} mV, ' \
+            #       f'R: {resist :>10.3f} kOhm'
+            # create a message as dictionnary to be used by the html interface
+            msg = {
+                'rsdata': {
+                    'A': int(quad[0]),
+                    'B': int(quad[1]),
+                    'rs': resist,  # in kOhm
+                }
+            }
+            self.data_logger.info(json.dumps(msg))
 
             # if contact resistance = 0 -> we have a short circuit!!
             if resist < 1e-5:
@@ -845,7 +882,7 @@ class OhmPi(object):
         quadrupole : list of 4 int
             List of 4 integers representing the electrode numbers.
         bypass_check: bool, optional
-            Bypasses checks for A==M or A==M or B==M or B==N (i.e. used for rs-check)
+            Bypasses checks for A==M or A==N or B==M or B==N (i.e. used for rs-check)
         """
         assert len(quadrupole) == 4
         if (self._hw.tx.pwr.voltage > self._hw.rx._voltage_max) and bypass_check:
diff --git a/run_http_interface.sh b/run_http_interface.sh
index 956067d067460056cf3d8ac18b6d519bc7413dfe..f98f082f9b176adf1a1a0afa429146ab9fb33c16 100755
--- a/run_http_interface.sh
+++ b/run_http_interface.sh
@@ -1,7 +1,7 @@
 #!bin/bash
-USER="pi"  # change if other username
+export PYTHONPATH=/home/$USER/OhmPi
 cd /home/$USER/OhmPi
 source /home/$USER/OhmPi/ohmpy/bin/activate
-python ohmpi.py &  # run ohmpi.py to capture the commands
-python http_interface.py  # run http_interface to serve the web GUI
+python dev/start_mqtt_html.py &  # run ohmpi.py to capture the commands
+python3 -m http.server  # run web GUI