diff --git a/mqtt_logger.py b/mqtt_logger.py
index 8bde814de52348a5d1c399899f3a7ffbe9a253e9..10cbbc9d10258ba80b7d26fab0fe4466ff56771a 100644
--- a/mqtt_logger.py
+++ b/mqtt_logger.py
@@ -44,7 +44,6 @@ class MQTTHandler(logging.Handler):
         self.tls = tls
         self.protocol = protocol
         self.transport = transport
-        print(f'init logger QoS={self.qos}')
 
     def emit(self, record):
         """
diff --git a/ohmpi.py b/ohmpi.py
index 83c28abcd8dea044c1bfe94a557517f0ff236974..dd652fb169a709866a79fafdaba64f840894d5f0 100644
--- a/ohmpi.py
+++ b/ohmpi.py
@@ -10,7 +10,7 @@ Olivier KAUFMANN (UMONS) and Guillaume BLANCHY (ILVO).
 import os
 import io
 import json
-import subprocess
+# import subprocess
 
 import numpy as np
 import csv
@@ -388,110 +388,116 @@ class OhmPi(object):
         """
         # TODO here we can add the current_injected or voltage_injected in mA or mV
         # check arguments
-        if nb_stack is None:
-            nb_stack = self.settings['nb_stack']
-        if injection_duration is None:
-            injection_duration = self.settings['injection_duration']
-
-        start_time = time.time()
-
-        # inner variable initialization
-        injection_current = 0
-        sum_vmn = 0
-        sum_ps = 0
-
-        # injection courant and measure
-        pin0 = self.mcp.get_pin(0)
-        pin0.direction = Direction.OUTPUT
-        pin1 = self.mcp.get_pin(1)
-        pin1.direction = Direction.OUTPUT
-        pin0.value = False
-        pin1.value = False
 
         self.exec_logger.debug('Starting measurement')
         self.exec_logger.info('Waiting for data')
 
-        # FUNCTION AUTOGAIN
-        # ADS1115 for current measurement (AB)
-        self.ads_current = ads.ADS1115(self.i2c, gain=2 / 3, data_rate=860, address=0x48)
-        # ADS1115 for voltage measurement (MN)
-        self.ads_voltage = ads.ADS1115(self.i2c, gain=2 / 3, data_rate=860, address=0x49)
-        # try auto gain
-        pin1.value = True
-        pin0.value = False
-        time.sleep(injection_duration)
-        gain_current = self.gain_auto(AnalogIn(self.ads_current, ads.P0))
-        gain_voltage = self.gain_auto(AnalogIn(self.ads_voltage, ads.P0, ads.P1))
-        pin0.value = False
-        pin1.value = False
-        print('gain current: {:.3f}, gain voltage: {:.3f}'.format(gain_current, gain_voltage))
-        self.ads_current = ads.ADS1115(self.i2c, gain=gain_current, data_rate=860, address=0x48)
-        self.ads_voltage = ads.ADS1115(self.i2c, gain=gain_voltage, data_rate=860, address=0x49)
-
-        # TODO I don't get why 3 + 2*nb_stack - 1? why not just range(nb_stack)?
-        # or do we consider 1 stack = one full polarity? do we discard the first 3 readings?
-        for n in range(0, 3 + 2 * nb_stack - 1):
-            # current injection
-            if (n % 2) == 0:
-                pin1.value = True
-                pin0.value = False  # current injection polarity nr1
-            else:
-                pin0.value = True
-                pin1.value = False  # current injection nr2
-            start_delay = time.time()  # stating measurement time
-            time.sleep(injection_duration)  # delay depending on current injection duration
-
-            # measurement of current i and voltage u
-            # sampling for each stack at the end of the injection
-            meas = np.zeros((self.nb_samples, 3))
-            for k in range(0, self.nb_samples):
-                # reading current value on ADS channel A0
-                meas[k, 0] = (AnalogIn(self.ads_current, ads.P0).voltage * 1000) / (50 * self.r_shunt)  # TODO: replace 50 by factor depending on INA model specifed in config.py
-                # reading voltage value on ADS channel A2
-                meas[k, 1] = -AnalogIn(self.ads_voltage, ads.P0, ads.P1).voltage * self.coef_p2 * 1000  # NOTE: Changed sign
-
-            # stop current injection
+        if self.on_pi:
+            if nb_stack is None:
+                nb_stack = self.settings['nb_stack']
+            if injection_duration is None:
+                injection_duration = self.settings['injection_duration']
+
+            start_time = time.time()
+
+            # inner variable initialization
+            injection_current = 0
+            sum_vmn = 0
+            sum_ps = 0
+
+            # injection courant and measure
+            pin0 = self.mcp.get_pin(0)
+            pin0.direction = Direction.OUTPUT
+            pin1 = self.mcp.get_pin(1)
+            pin1.direction = Direction.OUTPUT
+            pin0.value = False
             pin1.value = False
+
+            # FUNCTION AUTOGAIN
+            # ADS1115 for current measurement (AB)
+            self.ads_current = ads.ADS1115(self.i2c, gain=2 / 3, data_rate=860, address=0x48)
+            # ADS1115 for voltage measurement (MN)
+            self.ads_voltage = ads.ADS1115(self.i2c, gain=2 / 3, data_rate=860, address=0x49)
+            # try auto gain
+            pin1.value = True
             pin0.value = False
-            end_delay = time.time()
-
-            # take average from the samples per stack, then sum them all
-            # average for all stack is done outside the loop
-            injection_current = injection_current + (np.mean(meas[:, 0]))
-            vmn1 = np.mean(meas[:, 1]) - np.mean(meas[:, 2])
-            if (n % 2) == 0:
-                sum_vmn = sum_vmn - vmn1
-                sum_ps = sum_ps + vmn1
-            else:
-                sum_vmn = sum_vmn + vmn1
-                sum_ps = sum_ps + vmn1
-
-            # TODO get battery voltage and warn if battery is running low
-            # TODO send a message on SOH stating the battery level
-            end_calc = time.time()
-
-            # TODO I am not sure I understand the computation below
-            # wait twice the actual injection time between two injection
-            # so it's a 50% duty cycle right?
-            time.sleep(2 * (end_delay - start_delay) - (end_calc - start_delay))
-
-        # create a dictionary and compute averaged values from all stacks
-        d = {
-            "time": datetime.now().isoformat(),
-            "A": quad[0],
-            "B": quad[1],
-            "M": quad[2],
-            "N": quad[3],
-            "inj time [ms]": (end_delay - start_delay) * 1000,
-            "Vmn [mV]": (sum_vmn / (3 + 2 * nb_stack - 1)),
-            "I [mA]": (injection_current / (3 + 2 * nb_stack - 1)),
-            "R [ohm]": (sum_vmn / (3 + 2 * nb_stack - 1) / (injection_current / (3 + 2 * nb_stack - 1))),
-            "Ps [mV]": (sum_ps / (3 + 2 * nb_stack - 1)),
-            "nbStack": nb_stack,
-            "CPU temp [degC]": CPUTemperature().temperature,
-            "Time [s]": (-start_time + time.time()),
-            "Nb samples [-]": self.nb_samples
-        }
+            time.sleep(injection_duration)
+            gain_current = self.gain_auto(AnalogIn(self.ads_current, ads.P0))
+            gain_voltage = self.gain_auto(AnalogIn(self.ads_voltage, ads.P0, ads.P1))
+            pin0.value = False
+            pin1.value = False
+            print('gain current: {:.3f}, gain voltage: {:.3f}'.format(gain_current, gain_voltage))
+            self.ads_current = ads.ADS1115(self.i2c, gain=gain_current, data_rate=860, address=0x48)
+            self.ads_voltage = ads.ADS1115(self.i2c, gain=gain_voltage, data_rate=860, address=0x49)
+
+            # TODO I don't get why 3 + 2*nb_stack - 1? why not just range(nb_stack)?
+            # or do we consider 1 stack = one full polarity? do we discard the first 3 readings?
+            for n in range(0, 3 + 2 * nb_stack - 1):
+                # current injection
+                if (n % 2) == 0:
+                    pin1.value = True
+                    pin0.value = False  # current injection polarity nr1
+                else:
+                    pin0.value = True
+                    pin1.value = False  # current injection nr2
+                start_delay = time.time()  # stating measurement time
+                time.sleep(injection_duration)  # delay depending on current injection duration
+
+                # measurement of current i and voltage u
+                # sampling for each stack at the end of the injection
+                meas = np.zeros((self.nb_samples, 3))
+                for k in range(0, self.nb_samples):
+                    # reading current value on ADS channel A0
+                    meas[k, 0] = (AnalogIn(self.ads_current, ads.P0).voltage * 1000) / (50 * self.r_shunt)  # TODO: replace 50 by factor depending on INA model specifed in config.py
+                    # reading voltage value on ADS channel A2
+                    meas[k, 1] = -AnalogIn(self.ads_voltage, ads.P0, ads.P1).voltage * self.coef_p2 * 1000  # NOTE: Changed sign
+
+                # stop current injection
+                pin1.value = False
+                pin0.value = False
+                end_delay = time.time()
+
+                # take average from the samples per stack, then sum them all
+                # average for all stack is done outside the loop
+                injection_current = injection_current + (np.mean(meas[:, 0]))
+                vmn1 = np.mean(meas[:, 1]) - np.mean(meas[:, 2])
+                if (n % 2) == 0:
+                    sum_vmn = sum_vmn - vmn1
+                    sum_ps = sum_ps + vmn1
+                else:
+                    sum_vmn = sum_vmn + vmn1
+                    sum_ps = sum_ps + vmn1
+
+                # TODO get battery voltage and warn if battery is running low
+                # TODO send a message on SOH stating the battery level
+                end_calc = time.time()
+
+                # TODO I am not sure I understand the computation below
+                # wait twice the actual injection time between two injection
+                # so it's a 50% duty cycle right?
+                time.sleep(2 * (end_delay - start_delay) - (end_calc - start_delay))
+
+            # create a dictionary and compute averaged values from all stacks
+            d = {
+                "time": datetime.now().isoformat(),
+                "A": quad[0],
+                "B": quad[1],
+                "M": quad[2],
+                "N": quad[3],
+                "inj time [ms]": (end_delay - start_delay) * 1000,
+                "Vmn [mV]": (sum_vmn / (3 + 2 * nb_stack - 1)),
+                "I [mA]": (injection_current / (3 + 2 * nb_stack - 1)),
+                "R [ohm]": (sum_vmn / (3 + 2 * nb_stack - 1) / (injection_current / (3 + 2 * nb_stack - 1))),
+                "Ps [mV]": (sum_ps / (3 + 2 * nb_stack - 1)),
+                "nbStack": nb_stack,
+                "CPU temp [degC]": CPUTemperature().temperature,
+                "Time [s]": (-start_time + time.time()),
+                "Nb samples [-]": self.nb_samples
+            }
+        else:  # for testing, generate random data
+            d = {'time': datetime.now().isoformat(), 'A': quad[0], 'B': quad[1], 'M': quad[2], 'N': quad[3],
+                'R [ohm]': np.abs(np.random.randn(1))
+            }
 
         # round number to two decimal for nicer string output
         output = [f'{k}\t' for k in d.keys()]
@@ -504,6 +510,7 @@ class OhmPi(object):
                 output += f'{val}\t'
         output = output[:-1]
         self.exec_logger.debug(output)
+        self.data_logger.info(json.loads(d))
         time.sleep(1)  # NOTE: why this?
 
         return d
@@ -572,14 +579,12 @@ class OhmPi(object):
             msg = f'Contact resistance {str(quad):s}: I: {current * 1000.:>10.3f} mA, V: {voltage * 1000.:>10.3f} mV, ' \
                   f'R: {resistance /1000.:>10.3f} kOhm'
 
-            print(msg)
             self.exec_logger.debug(msg)
 
             # if contact resistance = 0 -> we have a short circuit!!
             if resistance < 1e-2:
                 msg = f'!!!SHORT CIRCUIT!!! {str(quad):s}: {resistance / 1000.:.3f} kOhm'
                 self.exec_logger.warning(msg)
-                print(msg)
 
             # save data and print in a text file
             self.append_and_save(export_path_rs, {
@@ -628,16 +633,17 @@ class OhmPi(object):
                 # last_measurement.to_csv(f, header=True)
 
     def process_commands(self):
-        tcp_port = CONTROL_CONFIG['tcp_port']
         context = zmq.Context()
+        tcp_port = CONTROL_CONFIG["tcp_port"]
         socket = context.socket(zmq.REP)
         socket.bind(f'tcp://*:{tcp_port}')
+
         print(colored(f'Listening to commands on tcp port {tcp_port}.'
                       f' Make sure your client interface is running and bound to this port...', 'blue'))
         self.exec_logger.debug(f'Start listening for commands on port {tcp_port}')
         while True:
             message = socket.recv()
-            print(f'Received command: {message}')
+            self.exec_logger.debug(f'Received command: {message}')
             e = None
             try:
                 cmd_id = None
@@ -652,7 +658,8 @@ class OhmPi(object):
                         self._update_acquisition_settings(args)
                     elif cmd == 'start':
                         self.measure(cmd_id)
-                        self.stop()
+                        while not self.status == 'idle':
+                            time.sleep(0.1)
                         status = True
                     elif cmd == 'stop':
                         self.stop()
@@ -683,7 +690,7 @@ class OhmPi(object):
             finally:
                 reply = {'cmd_id': cmd_id, 'status': status}
                 reply = json.dumps(reply)
-                print(reply)
+                self.exec_logger.debug(f'Execution report: {reply}')
                 self.exec_logger.debug(reply)
                 reply = bytes(reply, 'utf-8')
                 socket.send(reply)
@@ -722,25 +729,20 @@ class OhmPi(object):
                     self.switch_mux_on(quad)
 
                     # run a measurement
-                    if self.on_pi:
-                        current_measurement = self.run_measurement(quad, self.settings["nb_stack"],
+                    acquired_data = self.run_measurement(quad, self.settings["nb_stack"],
                                                                    self.settings["injection_duration"])
-                    else:  # for testing, generate random data
-                        current_measurement = {
-                            'A': [quad[0]], 'B': [quad[1]], 'M': [quad[2]], 'N': [quad[3]],
-                            'R [ohm]': np.abs(np.random.randn(1))
-                        }
 
                     # switch mux off
                     self.switch_mux_off(quad)
 
                     # add command_id in dataset
-                    current_measurement.update({'cmd_id': cmd_id})
+                    acquired_data.update({'cmd_id': cmd_id})
                     # log data to the data logger
-                    self.data_logger.info(f'{current_measurement}')
+                    self.data_logger.info(f'{acquired_data}')
+                    print(f'{acquired_data}')
                     # save data and print in a text file
-                    self.append_and_save(filename, current_measurement)
-                    self.exec_logger.debug('{:d}/{:d}'.format(i + 1, self.sequence.shape[0]))
+                    self.append_and_save(filename, acquired_data)
+                    self.exec_logger.debug(f'{i+1:d}/{self.sequence.shape[0]:d}')
 
                 # compute time needed to take measurement and subtract it from interval
                 # between two sequence run (= sequence_delay)