diff --git a/Ohmpi_4elec_mqtt.py b/Ohmpi_4elec_mqtt.py
new file mode 100644
index 0000000000000000000000000000000000000000..743501536bd17731f3306cde8589de54688ce19c
--- /dev/null
+++ b/Ohmpi_4elec_mqtt.py
@@ -0,0 +1,281 @@
+"""
+created on december, 2021
+Update january 2022
+Ohmpi_4elec.py is a program to control a low-cost and open hardware resistivity meter OhmPi that has been developed
+ by Rémi CLEMENT(INRAE),Vivien DUBOIS(INRAE),Hélène GUYARD(IGE), Nicolas FORQUET (INRAE),
+    Oliver KAUFMANN (UMONS) and Yannick FARGIER (IFSTTAR).
+"""
+from settings import OHMPI_CONFIG
+try:
+    import board, busio
+    import adafruit_tca9548a
+    import adafruit_ads1x15.ads1115 as ADS
+    from adafruit_ads1x15.analog_in import AnalogIn
+    from adafruit_mcp230xx.mcp23008 import MCP23008
+    from adafruit_mcp230xx.mcp23017 import MCP23017
+    import digitalio
+    from digitalio import Direction
+    from gpiozero import CPUTemperature
+except:
+    pass
+
+from pandas import DataFrame
+from datetime import datetime
+import time
+import numpy as np
+import sys
+import json
+# import glob
+from os import path, statvfs
+from threading import Thread
+from logging_setup import setup_loggers
+from mqtt_setup import mqtt_client_setup
+
+# Initialization
+version = "1.01"
+
+print('\033[1m'+'\033[31m'+' ________________________________')
+print('|  _  | | | ||  \/  || ___ \_   _|')
+print('| | | | |_| || .  . || |_/ / | |' )
+print('| | | |  _  || |\/| ||  __/  | |')
+print('\ \_/ / | | || |  | || |    _| |_')
+print(' \___/\_| |_/\_|  |_/\_|    \___/ ')
+print('\033[0m')
+print('OhmPi 4 elec MQTT start' )
+print(f'Vers: {version}')
+
+msg_logger, msg_log_filename, data_logger, data_log_filename, logging_level = setup_loggers()
+mqtt_client, measurement_topic = mqtt_client_setup()
+
+msg_logger.info(f'publishing mqtt to topic {measurement_topic}')
+
+# Remaining initialization
+status = True
+
+"""
+hardware parameters
+"""
+print(f'\033[1m \033[31m The maximum current cannot be higher than {OHMPI_CONFIG["Imax"]} mA \033[0m')
+# offset_p2= 0
+# offset_p3= 0
+integer = 2  # Max value 10 TODO: explain this
+nb_elec = 4  # TODO: Improve this
+meas = np.zeros((3, integer))
+
+"""
+import parameters
+"""
+
+with open('ohmpi_param.json') as json_file:
+    pardict = json.load(json_file)
+
+
+i2c = busio.I2C(board.SCL, board.SDA) #activation du protocle I2C
+mcp = MCP23008(i2c, address=0x20) #connexion I2C MCP23008, injection de courant
+ads_current = ADS.ADS1115(i2c, gain=2/3,data_rate=860, address=0X48)# connexion ADS1115, pour la mesure de courant
+ads_voltage = ADS.ADS1115(i2c, gain=2/3,data_rate=860, address=0X49)# connexion ADS1115, pour la mesure de voltage
+
+#initialisation des voies pour la polarité
+pin0 = mcp.get_pin(0)
+pin0.direction = Direction.OUTPUT
+pin1 = mcp.get_pin(1)
+pin1.direction = Direction.OUTPUT
+pin0.value = False
+pin1.value = False
+
+
+def switch_mux(electrode_nr, state, role):
+    """select the right channel for the multiplexer cascade for a given electrode"""
+    board_address = {'A': 0x76, 'B': 0X71, 'M': 0x74, 'N': 0x70}
+
+    tca = adafruit_tca9548a.TCA9548A(i2c, board_address[role])  # choose MUX A B M or N
+    i2c_address = None
+    if electrode_nr < 17:
+        i2c_address = 7
+        relay_nr = electrode_nr
+    elif 16 < electrode_nr < 33:
+        i2c_address = 6
+        relay_nr = electrode_nr - 16
+    elif 32 < electrode_nr < 49:
+        i2c_address = 5
+        relay_nr = electrode_nr - 32
+    elif 48 < electrode_nr < 65:
+        i2c_address = 4
+        relay_nr = electrode_nr - 48
+
+    if i2c_address is not None:
+        mcp2 = MCP23017(tca[i2c_address])
+        mcp2.get_pin(relay_nr-1).direction=digitalio.Direction.OUTPUT
+        if state == 'on':
+            mcp2.get_pin(relay_nr-1).value = True
+        else:
+            mcp2.get_pin(relay_nr-1).value = False
+        msg_logger.debug(f'Switching relay {relay_nr} {state} for electrode {electrode_nr}')
+    else:
+        msg_logger.warn(f'Unable to address electrode nr {electrode_nr}')
+
+
+def switch_mux_on(quadrupole):
+    """switch on multiplexer relays for quadrupole"""
+    roles = ['A', 'B', 'M', 'N']
+    for i in range(0, 4):
+        switch_mux(quadrupole[i], 'on', roles[i])
+
+
+def switch_mux_off(quadrupole):
+    """switch off multiplexer relays for quadrupole"""
+    roles = ['A', 'B', 'M', 'N']
+    for i in range(0, 4):
+        switch_mux(quadrupole[i], 'off', roles[i])
+
+
+def reset_mux():
+    """switch off all multiplexer relays"""
+    global nb_elec
+    roles = ['A', 'B', 'M', 'N']
+    for i in range(0, 4):
+        for j in range(1, nb_elec + 1):
+            switch_mux(j, 'off', roles[i])
+
+# function to find rows with identical values in different columns
+def find_identical_in_line(array_object):
+    output = []
+    if array_object.ndim == 1:
+        temp = np.zeros(4)
+        for i in range(len(array_object)):
+            temp[i] = np.count_nonzero(array_object == array_object[i])
+        if any(temp > 1):
+            output.append(0)
+    else:
+        for i in range(len(array_object[:,1])):
+            temp = np.zeros(len(array_object[1,:]))
+            for j in range(len(array_object[1,:])):
+                temp[j] = np.count_nonzero(array_object[i,:] == array_object[i,j])
+            if any(temp > 1):
+                output.append(i)
+    return output
+
+
+def read_quad(filename, nb_elec):
+    """read quadripole file and apply tests"""
+    output = np.loadtxt(filename, delimiter=" ",dtype=int) # load quadripole file
+    # locate lines where the electrode index exceeds the maximum number of electrodes
+    test_index_elec = np.array(np.where(output > nb_elec))
+    # locate lines where an electrode is referred twice
+    test_same_elec = find_identical_in_line(output)
+    # if statement with exit cases (rajouter un else if pour le deuxième cas du ticket #2)
+    if test_index_elec.size != 0:
+        for i in range(len(test_index_elec[0,:])):
+            print("Error: An electrode index at line "+ str(test_index_elec[0,i]+1)+" exceeds the maximum number of electrodes")
+        sys.exit(1)
+    elif len(test_same_elec) != 0:
+        for i in range(len(test_same_elec)):
+            print("Error: An electrode index is used twice at line " + str(test_same_elec[i]+1))
+        sys.exit(1)
+    else:
+        return output
+
+
+def run_measurement(nb_stack, injection_deltat, r_shunt, coefp2, coefp3):
+    start_time=time.time()
+    # inner variable initialization
+    injection_current=0
+    sum_vmn=0
+    sum_ps=0
+    # injection courant and measure
+    mcp = MCP23008(i2c, address=0x20)
+    pin0 = mcp.get_pin(0)
+    pin0.direction = Direction.OUTPUT
+    pin1 = mcp.get_pin(1)
+    pin1.direction = Direction.OUTPUT
+    pin0.value = False
+    pin1.value = False
+    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_deltat)  # delay depending on current injection duration
+        
+    # mesureament of i and u
+        for k in range(0, integer):
+          meas[0,k] = (AnalogIn(ads_current,ADS.P0).voltage*1000)/(50*r_shunt) # reading current value on ADS channel A0
+          meas[1,k] = AnalogIn(ads_voltage,ADS.P0).voltage*coefp2*1000
+          meas[2,k] = AnalogIn(ads_voltage,ADS.P1).voltage*coefp3*1000  # reading voltage value on ADS channel A2
+        # stop current injection
+        pin1.value = False
+        pin0.value = False
+        end_delay = time.time()
+        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
+        
+        cpu = CPUTemperature()
+        
+        end_calc = time.time()
+        time.sleep(2*(end_delay-start_delay)-(end_calc-start_delay))
+        #end_sleep2=time.time()
+        #print(['sleep=',((end_sleep2-start_delay))])
+
+        #print(['true delta=',((end_delay-start_delay)-injection_deltat)])
+        #print(['time stop=',((2*(end_delay-start_delay)-(end_calc-start_delay)))])
+    # return averaged values
+#     cpu= CPUTemperature()
+    output = DataFrame({
+        "time": [datetime.now()],
+        "A": [(1)],
+        "B": [(2)],
+        "M": [(3)],
+        "N": [(4)],
+        "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 [°C]": [cpu.temperature],
+        "Time [s]": [(-start_time + time.time())],
+        "Integer [-]": [integer]
+
+     
+     
+      # Dead time equivalent to the duration of the current injection pulse   
+    })
+    output = output.round(2)
+    print(output.to_string())
+    time.sleep(1)
+    return output
+
+
+def append_and_save(data_path, last_measurement):
+    """Save data"""
+    if path.isfile(data_path):
+        # Load data file and append data to it
+        with open(data_path, 'a') as f:
+            last_measurement.to_csv(f, header=False)
+    else:
+        # create data file and add headers
+        with open(data_path, 'a') as f:
+            last_measurement.to_csv(f, header=True)
+
+
+"""
+Main loop
+"""
+for g in range(0, pardict.get("nbr_meas")):  # for time-lapse monitoring
+    current_measurement = run_measurement(pardict.get("stack"), pardict.get("injection_duration"), 
+                                          OHMPI_CONFIG['R_shunt'], OHMPI_CONFIG['coef_p2'], OHMPI_CONFIG['coef_p3'])
+    append_and_save(pardict.get("export_path"), current_measurement)
+    msg = f'Resitivity: {current_measurement.iloc[-1]["R [ohm]"]:.2f} ohm'
+    msg_logger.info(msg)
+    mqtt_client.publish(measurement_topic, msg)
+    time.sleep(pardict.get("sequence_delay"))  # waiting next measurement (time-lapse)
diff --git a/Proposition MQTT interface.pdf b/Proposition MQTT interface.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..96a92bca0e11dc1fe46c40cf61f8818744b6ba1f
Binary files /dev/null and b/Proposition MQTT interface.pdf differ
diff --git a/basic_mqtt_ohmpi_console.ipynb b/basic_mqtt_ohmpi_console.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..482796e85b96f5028dae24025174e72020a4094a
--- /dev/null
+++ b/basic_mqtt_ohmpi_console.ipynb
@@ -0,0 +1,194 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "606c11c0-3a80-4138-ac50-1da0bd01bef8",
+   "metadata": {},
+   "source": [
+    "# A small code to test MQTT interface for ohmpi"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "daf2041b-1df9-42de-a385-f450a826c96f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import paho.mqtt.client as mqtt\n",
+    "import time"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "14c42035",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client_id = 'ohmpi_console_sn_0001'\n",
+    "measurements_topic = 'measurements_ohmpi_sn_0001'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "391c6373-f7db-485e-b3dd-b1e04a37473a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "broker_address=\"mg3d-dev.umons.ac.be\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "8fc857ba-bbcf-4f99-a30f-84fd14ddb2d0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client = mqtt.Client(client_id, protocol=4) #create new instance"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "24926751-62c6-4833-8d68-99279192d4e0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def on_message(client, userdata, message):\n",
+    "    m = str(message.payload.decode(\"utf-8\"))\n",
+    "    print(f'message received {m}')\n",
+    "    print(f'topic: {message.topic}')\n",
+    "    print(f'qos: {message.qos}')\n",
+    "    print(f'retain flag: {message.retain}')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "06e424ff-cd1d-4756-bf53-cfbca4628e73",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.connect(broker_address) #connect to broker"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "f0b06a71-b0bf-4551-a044-94b1100a3a5d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client.on_message = on_message\n",
+    "client.loop_start()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "8e168d2d-25fa-49ac-9d03-dd0da5e61841",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Subscribing to topic measurements_ohmpi_sn_0001\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(0, 1)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "print(\"Subscribing to topic\", measurements_topic)\n",
+    "client.subscribe(measurements_topic)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "eaa7d034-5383-4ece-a824-f763ce214760",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "message received Resitivity: 215.22 ohm\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "message received Resitivity: 214.94 ohm\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n"
+     ]
+    }
+   ],
+   "source": [
+    "time.sleep(60)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "9bd768aa-c4d3-429e-b667-6e981bd28353",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client.loop_stop()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f9a0333a-c1ec-42a8-bd24-3dc466c51bb4",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.10"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/basic_mqtt_ohmpi_controller.ipynb b/basic_mqtt_ohmpi_controller.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..b9c425cf4fde2a0683f25c72298a5cacd8cb36c9
--- /dev/null
+++ b/basic_mqtt_ohmpi_controller.ipynb
@@ -0,0 +1,728 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "9ec039c2-8dc0-42ab-ad96-356e54a6c228",
+   "metadata": {},
+   "source": [
+    "# A small code to test MQTT ohmpi controller"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "daf2041b-1df9-42de-a385-f450a826c96f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import paho.mqtt.client as mqtt\n",
+    "import pandas as pd\n",
+    "import time"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "013806a6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sequence = './ABMN.txt'\n",
+    "broker_address = \"mg3d-dev.umons.ac.be\"\n",
+    "client_id = \"ohmpi-controller_01\"\n",
+    "control_topic = 'cmd_ohmpi_sn_0001'\n",
+    "measurements_topic = 'measurements_ohmpi_sn_0001'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "c07183bf",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>array</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>1 4 2 3</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>2 5 3 4</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>3 6 4 5</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>4 7 5 6</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>5 8 6 7</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>150</th>\n",
+       "      <td>3 30 12 21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>151</th>\n",
+       "      <td>4 31 13 22</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>152</th>\n",
+       "      <td>5 32 14 23</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>153</th>\n",
+       "      <td>1 31 11 21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>154</th>\n",
+       "      <td>2 32 12 22</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>155 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "          array\n",
+       "0       1 4 2 3\n",
+       "1       2 5 3 4\n",
+       "2       3 6 4 5\n",
+       "3       4 7 5 6\n",
+       "4       5 8 6 7\n",
+       "..          ...\n",
+       "150  3 30 12 21\n",
+       "151  4 31 13 22\n",
+       "152  5 32 14 23\n",
+       "153  1 31 11 21\n",
+       "154  2 32 12 22\n",
+       "\n",
+       "[155 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "df = pd.read_csv(sequence, header=None, names=['array'])\n",
+    "df"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "8fc857ba-bbcf-4f99-a30f-84fd14ddb2d0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client = mqtt.Client(client_id, protocol=4) #create new instance"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "c27d85eb",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def on_message(client, userdata, message):\n",
+    "    m = str(message.payload.decode(\"utf-8\"))\n",
+    "    print(f'message received {m}')\n",
+    "    print(f'topic: {message.topic}')\n",
+    "    print(f'qos: {message.qos}')\n",
+    "    print(f'retain flag: {message.retain}')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "06e424ff-cd1d-4756-bf53-cfbca4628e73",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.connect(broker_address) #connect to broker"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "819fb8f9",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(0, 1)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.on_message = on_message\n",
+    "client.loop_start()\n",
+    "client.subscribe(measurements_topic)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "519791a6",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "publishing 21:55:13 : measure resistivity 0 with array 1 4 2 3\n",
+      "(0, 2)\n",
+      "publishing 21:55:14 : measure resistivity 1 with array 2 5 3 4\n",
+      "(0, 3)\n",
+      "publishing 21:55:15 : measure resistivity 2 with array 3 6 4 5\n",
+      "(0, 4)\n",
+      "publishing 21:55:16 : measure resistivity 3 with array 4 7 5 6\n",
+      "(0, 5)\n",
+      "publishing 21:55:17 : measure resistivity 4 with array 5 8 6 7\n",
+      "(0, 6)\n",
+      "publishing 21:55:18 : measure resistivity 5 with array 6 9 7 8\n",
+      "(0, 7)\n",
+      "publishing 21:55:19 : measure resistivity 6 with array 7 10 8 9\n",
+      "(0, 8)\n",
+      "publishing 21:55:20 : measure resistivity 7 with array 8 11 9 10\n",
+      "(0, 9)\n",
+      "publishing 21:55:21 : measure resistivity 8 with array 9 12 10 11\n",
+      "(0, 10)\n",
+      "publishing 21:55:22 : measure resistivity 9 with array 10 13 11 12\n",
+      "(0, 11)\n",
+      "publishing 21:55:23 : measure resistivity 10 with array 11 14 12 13\n",
+      "(0, 12)\n",
+      "publishing 21:55:24 : measure resistivity 11 with array 12 15 13 14\n",
+      "(0, 13)\n",
+      "publishing 21:55:25 : measure resistivity 12 with array 13 16 14 15\n",
+      "(0, 14)\n",
+      "publishing 21:55:26 : measure resistivity 13 with array 14 17 15 16\n",
+      "(0, 15)\n",
+      "publishing 21:55:27 : measure resistivity 14 with array 15 18 16 17\n",
+      "(0, 16)\n",
+      "publishing 21:55:28 : measure resistivity 15 with array 16 19 17 18\n",
+      "(0, 17)\n",
+      "publishing 21:55:29 : measure resistivity 16 with array 17 20 18 19\n",
+      "(0, 18)\n",
+      "publishing 21:55:30 : measure resistivity 17 with array 18 21 19 20\n",
+      "(0, 19)\n",
+      "publishing 21:55:31 : measure resistivity 18 with array 19 22 20 21\n",
+      "(0, 20)\n",
+      "publishing 21:55:32 : measure resistivity 19 with array 20 23 21 22\n",
+      "(0, 21)\n",
+      "publishing 21:55:33 : measure resistivity 20 with array 21 24 22 23\n",
+      "(0, 22)\n",
+      "publishing 21:55:34 : measure resistivity 21 with array 22 25 23 24\n",
+      "(0, 23)\n",
+      "publishing 21:55:35 : measure resistivity 22 with array 23 26 24 25\n",
+      "(0, 24)\n",
+      "publishing 21:55:36 : measure resistivity 23 with array 24 27 25 26\n",
+      "(0, 25)\n",
+      "publishing 21:55:37 : measure resistivity 24 with array 25 28 26 27\n",
+      "(0, 26)\n",
+      "publishing 21:55:38 : measure resistivity 25 with array 26 29 27 28\n",
+      "(0, 27)\n",
+      "publishing 21:55:39 : measure resistivity 26 with array 27 30 28 29\n",
+      "(0, 28)\n",
+      "publishing 21:55:40 : measure resistivity 27 with array 28 31 29 30\n",
+      "(0, 29)\n",
+      "publishing 21:55:41 : measure resistivity 28 with array 29 32 30 31\n",
+      "(0, 30)\n",
+      "publishing 21:55:42 : measure resistivity 29 with array 1 7 3 5\n",
+      "(0, 31)\n",
+      "publishing 21:55:43 : measure resistivity 30 with array 2 8 4 6\n",
+      "(0, 32)\n",
+      "publishing 21:55:44 : measure resistivity 31 with array 3 9 5 7\n",
+      "(0, 33)\n",
+      "publishing 21:55:45 : measure resistivity 32 with array 4 10 6 8\n",
+      "(0, 34)\n",
+      "publishing 21:55:46 : measure resistivity 33 with array 5 11 7 9\n",
+      "(0, 35)\n",
+      "publishing 21:55:47 : measure resistivity 34 with array 6 12 8 10\n",
+      "(0, 36)\n",
+      "message received TEST 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:48 : measure resistivity 35 with array 7 13 9 11\n",
+      "(0, 37)\n",
+      "message received 21:55:48 : measure resistivity 35 with array 7 13 9 11 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:49 : measure resistivity 36 with array 8 14 10 12\n",
+      "(0, 38)\n",
+      "message received 21:55:49 : measure resistivity 36 with array 8 14 10 12 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:50 : measure resistivity 37 with array 9 15 11 13\n",
+      "(0, 39)\n",
+      "message received 21:55:50 : measure resistivity 37 with array 9 15 11 13 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:51 : measure resistivity 38 with array 10 16 12 14\n",
+      "(0, 40)\n",
+      "message received 21:55:51 : measure resistivity 38 with array 10 16 12 14 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:52 : measure resistivity 39 with array 11 17 13 15\n",
+      "(0, 41)\n",
+      "message received 21:55:52 : measure resistivity 39 with array 11 17 13 15 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:53 : measure resistivity 40 with array 12 18 14 16\n",
+      "(0, 42)\n",
+      "message received 21:55:53 : measure resistivity 40 with array 12 18 14 16 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:54 : measure resistivity 41 with array 13 19 15 17\n",
+      "(0, 43)\n",
+      "message received 21:55:54 : measure resistivity 41 with array 13 19 15 17 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:55 : measure resistivity 42 with array 14 20 16 18\n",
+      "(0, 44)\n",
+      "message received 21:55:55 : measure resistivity 42 with array 14 20 16 18 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:56 : measure resistivity 43 with array 15 21 17 19\n",
+      "(0, 45)\n",
+      "message received 21:55:56 : measure resistivity 43 with array 15 21 17 19 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:57 : measure resistivity 44 with array 16 22 18 20\n",
+      "(0, 46)\n",
+      "message received 21:55:57 : measure resistivity 44 with array 16 22 18 20 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:58 : measure resistivity 45 with array 17 23 19 21\n",
+      "(0, 47)\n",
+      "message received 21:55:58 : measure resistivity 45 with array 17 23 19 21 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:55:59 : measure resistivity 46 with array 18 24 20 22\n",
+      "(0, 48)\n",
+      "message received 21:55:59 : measure resistivity 46 with array 18 24 20 22 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:00 : measure resistivity 47 with array 19 25 21 23\n",
+      "(0, 49)\n",
+      "message received 21:56:00 : measure resistivity 47 with array 19 25 21 23 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:01 : measure resistivity 48 with array 20 26 22 24\n",
+      "(0, 50)\n",
+      "message received 21:56:01 : measure resistivity 48 with array 20 26 22 24 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:02 : measure resistivity 49 with array 21 27 23 25\n",
+      "(0, 51)\n",
+      "message received 21:56:02 : measure resistivity 49 with array 21 27 23 25 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:03 : measure resistivity 50 with array 22 28 24 26\n",
+      "(0, 52)\n",
+      "message received 21:56:03 : measure resistivity 50 with array 22 28 24 26 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:04 : measure resistivity 51 with array 23 29 25 27\n",
+      "(0, 53)\n",
+      "message received 21:56:04 : measure resistivity 51 with array 23 29 25 27 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:05 : measure resistivity 52 with array 24 30 26 28\n",
+      "(0, 54)\n",
+      "message received 21:56:05 : measure resistivity 52 with array 24 30 26 28 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:06 : measure resistivity 53 with array 25 31 27 29\n",
+      "(0, 55)\n",
+      "message received 21:56:06 : measure resistivity 53 with array 25 31 27 29 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:07 : measure resistivity 54 with array 26 32 28 30\n",
+      "(0, 56)\n",
+      "message received 21:56:07 : measure resistivity 54 with array 26 32 28 30 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:08 : measure resistivity 55 with array 1 10 4 7\n",
+      "(0, 57)\n",
+      "message received 21:56:08 : measure resistivity 55 with array 1 10 4 7 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:09 : measure resistivity 56 with array 2 11 5 8\n",
+      "(0, 58)\n",
+      "message received 21:56:09 : measure resistivity 56 with array 2 11 5 8 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:10 : measure resistivity 57 with array 3 12 6 9\n",
+      "(0, 59)\n",
+      "message received 21:56:10 : measure resistivity 57 with array 3 12 6 9 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:11 : measure resistivity 58 with array 4 13 7 10\n",
+      "(0, 60)\n",
+      "message received 21:56:11 : measure resistivity 58 with array 4 13 7 10 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:12 : measure resistivity 59 with array 5 14 8 11\n",
+      "(0, 61)\n",
+      "message received 21:56:12 : measure resistivity 59 with array 5 14 8 11 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:13 : measure resistivity 60 with array 6 15 9 12\n",
+      "(0, 62)\n",
+      "message received 21:56:13 : measure resistivity 60 with array 6 15 9 12 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:14 : measure resistivity 61 with array 7 16 10 13\n",
+      "(0, 63)\n",
+      "message received 21:56:14 : measure resistivity 61 with array 7 16 10 13 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:15 : measure resistivity 62 with array 8 17 11 14\n",
+      "(0, 64)\n",
+      "message received 21:56:15 : measure resistivity 62 with array 8 17 11 14 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:16 : measure resistivity 63 with array 9 18 12 15\n",
+      "(0, 65)\n",
+      "message received 21:56:16 : measure resistivity 63 with array 9 18 12 15 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:17 : measure resistivity 64 with array 10 19 13 16\n",
+      "(0, 66)\n",
+      "message received 21:56:17 : measure resistivity 64 with array 10 19 13 16 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:18 : measure resistivity 65 with array 11 20 14 17\n",
+      "(0, 67)\n",
+      "message received 21:56:18 : measure resistivity 65 with array 11 20 14 17 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:19 : measure resistivity 66 with array 12 21 15 18\n",
+      "(0, 68)\n",
+      "message received 21:56:19 : measure resistivity 66 with array 12 21 15 18 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:20 : measure resistivity 67 with array 13 22 16 19\n",
+      "(0, 69)\n",
+      "message received 21:56:20 : measure resistivity 67 with array 13 22 16 19 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:22 : measure resistivity 68 with array 14 23 17 20\n",
+      "(0, 70)\n",
+      "message received 21:56:22 : measure resistivity 68 with array 14 23 17 20 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:23 : measure resistivity 69 with array 15 24 18 21\n",
+      "(0, 71)\n",
+      "message received 21:56:23 : measure resistivity 69 with array 15 24 18 21 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:24 : measure resistivity 70 with array 16 25 19 22\n",
+      "(0, 72)\n",
+      "message received 21:56:24 : measure resistivity 70 with array 16 25 19 22 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:25 : measure resistivity 71 with array 17 26 20 23\n",
+      "(0, 73)\n",
+      "message received 21:56:25 : measure resistivity 71 with array 17 26 20 23 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:26 : measure resistivity 72 with array 18 27 21 24\n",
+      "(0, 74)\n",
+      "message received 21:56:26 : measure resistivity 72 with array 18 27 21 24 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:27 : measure resistivity 73 with array 19 28 22 25\n",
+      "(0, 75)\n",
+      "message received 21:56:27 : measure resistivity 73 with array 19 28 22 25 45 ohm.m\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "publishing 21:56:28 : measure resistivity 74 with array 20 29 23 26\n",
+      "(0, 76)\n",
+      "publishing 21:56:29 : measure resistivity 75 with array 21 30 24 27\n",
+      "(0, 77)\n",
+      "publishing 21:56:30 : measure resistivity 76 with array 22 31 25 28\n",
+      "(0, 78)\n",
+      "publishing 21:56:31 : measure resistivity 77 with array 23 32 26 29\n",
+      "(0, 79)\n",
+      "publishing 21:56:32 : measure resistivity 78 with array 1 13 5 9\n",
+      "(0, 80)\n",
+      "publishing 21:56:33 : measure resistivity 79 with array 2 14 6 10\n",
+      "(0, 81)\n",
+      "publishing 21:56:34 : measure resistivity 80 with array 3 15 7 11\n",
+      "(0, 82)\n",
+      "publishing 21:56:35 : measure resistivity 81 with array 4 16 8 12\n",
+      "(0, 83)\n",
+      "publishing 21:56:36 : measure resistivity 82 with array 5 17 9 13\n",
+      "(0, 84)\n",
+      "publishing 21:56:37 : measure resistivity 83 with array 6 18 10 14\n",
+      "(0, 85)\n",
+      "publishing 21:56:38 : measure resistivity 84 with array 7 19 11 15\n",
+      "(0, 86)\n",
+      "publishing 21:56:39 : measure resistivity 85 with array 8 20 12 16\n",
+      "(0, 87)\n",
+      "publishing 21:56:40 : measure resistivity 86 with array 9 21 13 17\n",
+      "(0, 88)\n",
+      "publishing 21:56:41 : measure resistivity 87 with array 10 22 14 18\n",
+      "(0, 89)\n",
+      "publishing 21:56:42 : measure resistivity 88 with array 11 23 15 19\n",
+      "(0, 90)\n",
+      "publishing 21:56:43 : measure resistivity 89 with array 12 24 16 20\n",
+      "(0, 91)\n",
+      "publishing 21:56:44 : measure resistivity 90 with array 13 25 17 21\n",
+      "(0, 92)\n",
+      "publishing 21:56:45 : measure resistivity 91 with array 14 26 18 22\n",
+      "(0, 93)\n",
+      "publishing 21:56:46 : measure resistivity 92 with array 15 27 19 23\n",
+      "(0, 94)\n",
+      "publishing 21:56:47 : measure resistivity 93 with array 16 28 20 24\n",
+      "(0, 95)\n",
+      "publishing 21:56:48 : measure resistivity 94 with array 17 29 21 25\n",
+      "(0, 96)\n",
+      "publishing 21:56:49 : measure resistivity 95 with array 18 30 22 26\n",
+      "(0, 97)\n",
+      "publishing 21:56:50 : measure resistivity 96 with array 19 31 23 27\n",
+      "(0, 98)\n",
+      "publishing 21:56:51 : measure resistivity 97 with array 20 32 24 28\n",
+      "(0, 99)\n",
+      "publishing 21:56:52 : measure resistivity 98 with array 1 16 6 11\n",
+      "(0, 100)\n",
+      "publishing 21:56:53 : measure resistivity 99 with array 2 17 7 12\n",
+      "(0, 101)\n",
+      "publishing 21:56:54 : measure resistivity 100 with array 3 18 8 13\n",
+      "(0, 102)\n",
+      "publishing 21:56:55 : measure resistivity 101 with array 4 19 9 14\n",
+      "(0, 103)\n",
+      "publishing 21:56:56 : measure resistivity 102 with array 5 20 10 15\n",
+      "(0, 104)\n",
+      "publishing 21:56:57 : measure resistivity 103 with array 6 21 11 16\n",
+      "(0, 105)\n",
+      "publishing 21:56:58 : measure resistivity 104 with array 7 22 12 17\n",
+      "(0, 106)\n",
+      "publishing 21:56:59 : measure resistivity 105 with array 8 23 13 18\n",
+      "(0, 107)\n",
+      "publishing 21:57:00 : measure resistivity 106 with array 9 24 14 19\n",
+      "(0, 108)\n",
+      "publishing 21:57:01 : measure resistivity 107 with array 10 25 15 20\n",
+      "(0, 109)\n",
+      "publishing 21:57:02 : measure resistivity 108 with array 11 26 16 21\n",
+      "(0, 110)\n",
+      "publishing 21:57:03 : measure resistivity 109 with array 12 27 17 22\n",
+      "(0, 111)\n",
+      "publishing 21:57:04 : measure resistivity 110 with array 13 28 18 23\n",
+      "(0, 112)\n",
+      "publishing 21:57:05 : measure resistivity 111 with array 14 29 19 24\n",
+      "(0, 113)\n",
+      "publishing 21:57:06 : measure resistivity 112 with array 15 30 20 25\n",
+      "(0, 114)\n",
+      "publishing 21:57:07 : measure resistivity 113 with array 16 31 21 26\n",
+      "(0, 115)\n",
+      "publishing 21:57:08 : measure resistivity 114 with array 17 32 22 27\n",
+      "(0, 116)\n",
+      "publishing 21:57:09 : measure resistivity 115 with array 1 19 7 13\n",
+      "(0, 117)\n",
+      "publishing 21:57:10 : measure resistivity 116 with array 2 20 8 14\n",
+      "(0, 118)\n",
+      "publishing 21:57:11 : measure resistivity 117 with array 3 21 9 15\n",
+      "(0, 119)\n",
+      "publishing 21:57:12 : measure resistivity 118 with array 4 22 10 16\n",
+      "(0, 120)\n",
+      "publishing 21:57:13 : measure resistivity 119 with array 5 23 11 17\n",
+      "(0, 121)\n",
+      "publishing 21:57:14 : measure resistivity 120 with array 6 24 12 18\n",
+      "(0, 122)\n",
+      "publishing 21:57:15 : measure resistivity 121 with array 7 25 13 19\n",
+      "(0, 123)\n",
+      "publishing 21:57:16 : measure resistivity 122 with array 8 26 14 20\n",
+      "(0, 124)\n",
+      "publishing 21:57:17 : measure resistivity 123 with array 9 27 15 21\n",
+      "(0, 125)\n",
+      "publishing 21:57:18 : measure resistivity 124 with array 10 28 16 22\n",
+      "(0, 126)\n",
+      "publishing 21:57:19 : measure resistivity 125 with array 11 29 17 23\n",
+      "(0, 127)\n"
+     ]
+    },
+    {
+     "ename": "KeyboardInterrupt",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
+      "\u001b[0;32m/tmp/ipykernel_156611/4011469085.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mpub\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublish\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcontrol_topic\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcommand\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpub\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m     \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
+     ]
+    }
+   ],
+   "source": [
+    "for idx, row in df.iterrows():\n",
+    "    t = time.strftime(\"%H:%M:%S\", time.localtime())\n",
+    "    command = f'{t} : measure resistivity {idx} with array {row[\"array\"]}'\n",
+    "    print(f'publishing {command}')\n",
+    "    pub = client.publish(control_topic, command)\n",
+    "    print(pub)\n",
+    "    time.sleep(1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b6ae4967",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "client.loop_stop()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1517fe4d-b9b3-43b5-a72c-ed691f8f71e2",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "message received Resitivity: 215.17 ohm\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "message received Resitivity: 214.98 ohm\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n",
+      "message received Resitivity: 215.12 ohm\n",
+      "topic: measurements_ohmpi_sn_0001\n",
+      "qos: 0\n",
+      "retain flag: 0\n"
+     ]
+    }
+   ],
+   "source": [
+    "client.reinitialise()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cf1f18b7-c712-43f6-957e-aae872881915",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.10"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/compressed_sized_timed_rotating_logger.py b/compressed_sized_timed_rotating_logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..cf8ca6cdc62e5837ac624306b2615141f74d63b3
--- /dev/null
+++ b/compressed_sized_timed_rotating_logger.py
@@ -0,0 +1,58 @@
+import time
+import os
+import logging.handlers as handlers
+import zipfile
+
+
+class CompressedSizedTimedRotatingFileHandler(handlers.TimedRotatingFileHandler):
+    """
+    Handler for logging to a set of files, which switches from one file
+    to the next when the current file reaches a certain size, or at certain
+    timed intervals
+    """
+    def __init__(self, filename, max_bytes=0, backup_count=0, encoding=None,
+                 delay=0, when='h', interval=1, utc=False, zip_mode=zipfile.ZIP_DEFLATED):
+        handlers.TimedRotatingFileHandler.__init__(self, filename=filename, when=when, interval=interval, utc=utc,
+                                                   backupCount=backup_count, encoding=encoding, delay=delay)
+        self.maxBytes = max_bytes
+        self.zip_mode = zip_mode
+
+    def shouldRollover(self, record):
+        """
+        Determine if rollover should occur.
+        Basically, see if the supplied record would cause the file to exceed
+        the size limit we have.
+        """
+        if self.stream is None:                 # delay was set...
+            self.stream = self._open()
+        if self.maxBytes > 0:                   # are we rolling over?
+            msg = "%s\n" % self.format(record)
+            self.stream.seek(0, 2)              # due to non-posix-compliant Windows feature
+            if self.stream.tell() + len(msg) >= self.maxBytes:
+                return True
+        t = int(time.time())
+        if t >= self.rolloverAt:
+            return True
+        return False
+
+    def find_last_rotated_file(self):
+        dir_name, base_name = os.path.split(self.baseFilename)
+        file_names = os.listdir(dir_name)
+        result = []
+        prefix = f'{base_name}.2'  # we want to find a rotated file with eg filename.2017-12-12... name
+        for file_name in file_names:
+            if file_name.startswith(prefix) and not file_name.endswith('.zip'):
+                result.append(file_name)
+        result.sort()
+        return os.path.join(dir_name, result[0])
+
+    def doRollover(self):
+        super(CompressedSizedTimedRotatingFileHandler, self).doRollover()
+
+        dfn = self.find_last_rotated_file()
+        dfn_zipped = f'{dfn}.zip'
+        if os.path.exists(dfn_zipped):
+            os.remove(dfn_zipped)
+        with zipfile.ZipFile(dfn_zipped, 'w', self.zip_mode) as f:
+            f.write(dfn)
+        os.remove(dfn)
\ No newline at end of file
diff --git a/logging_setup.py b/logging_setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..08b0d617e4db9cdccd5ed9f38c943b5f57a0c6df
--- /dev/null
+++ b/logging_setup.py
@@ -0,0 +1,83 @@
+from settings import LOGGING_CONFIG, DATA_LOGGING_CONFIG
+from os import path, mkdir, statvfs
+from time import gmtime
+import logging
+from compressed_sized_timed_rotating_logger import CompressedSizedTimedRotatingFileHandler
+
+
+def setup_loggers():
+    # Message logging setup
+    log_path = path.join(path.dirname(__file__), 'logs')
+    if not path.isdir(log_path):
+        mkdir(log_path)
+    msg_log_filename = path.join(log_path, 'msg_log')
+    msg_logger = logging.getLogger('msg_logger')
+
+    # Data logging setup
+    base_path = path.dirname(__file__)
+    data_path = path.join(base_path, 'data')
+    if not path.isdir(data_path):
+        mkdir(data_path)
+    data_log_filename = path.join(data_path, 'data_log')
+    data_logger = logging.getLogger('data_logger')
+
+    # Debug and logging
+    debug = LOGGING_CONFIG['debug_mode']
+    if debug:
+        logging_level = logging.DEBUG
+    else:
+        logging_level = logging.INFO
+
+    # Set message logging format and level
+    log_format = '%(asctime)-15s | %(process)d | %(levelname)s: %(message)s'
+    logging_to_console = LOGGING_CONFIG['logging_to_console']
+    msg_handler = CompressedSizedTimedRotatingFileHandler(msg_log_filename, max_bytes=LOGGING_CONFIG['max_bytes'],
+                                                          backup_count=LOGGING_CONFIG['backup_count'],
+                                                          when=LOGGING_CONFIG['when'],
+                                                          interval=LOGGING_CONFIG['interval'])
+    msg_formatter = logging.Formatter(log_format)
+    msg_formatter.converter = gmtime
+    msg_formatter.datefmt = '%Y/%m/%d %H:%M:%S UTC'
+    msg_handler.setFormatter(msg_formatter)
+    msg_logger.addHandler(msg_handler)
+    msg_logger.setLevel(logging_level)
+
+    if logging_to_console:
+        msg_logger.addHandler(logging.StreamHandler())
+
+    # Set data logging level and handler
+    data_logger.setLevel(logging.INFO)
+    data_handler = CompressedSizedTimedRotatingFileHandler(data_log_filename,
+                                                           max_bytes=DATA_LOGGING_CONFIG['max_bytes'],
+                                                           backup_count=DATA_LOGGING_CONFIG['backup_count'],
+                                                           when=DATA_LOGGING_CONFIG['when'],
+                                                           interval=DATA_LOGGING_CONFIG['interval'])
+    data_logger.addHandler(data_handler)
+
+    if not init_logging(msg_logger, logging_level, log_path, data_log_filename):
+        print('ERROR: Could not initialize logging!')
+    return msg_logger, msg_log_filename, data_logger, data_log_filename, logging_level
+
+
+def init_logging(msg_logger, logging_level, log_path, data_log_filename):
+    """ This is the init sequence for the logging system """
+
+    init_logging_status = True
+    msg_logger.info('')
+    msg_logger.info('****************************')
+    msg_logger.info('*** NEW SESSION STARTING ***')
+    msg_logger.info('****************************')
+    msg_logger.info('')
+    msg_logger.info('Logging level: %s' % logging_level)
+    try:
+        st = statvfs('.')
+        available_space = st.f_bavail * st.f_frsize / 1024 / 1024
+        msg_logger.info(f'Remaining disk space : {available_space:.1f} MB')
+    except Exception as e:
+        msg_logger.debug('Unable to get remaining disk space: {e}')
+    msg_logger.info('Saving data log to ' + data_log_filename)
+    msg_logger.info('OhmPi settings:')
+    # TODO Add OhmPi settings
+    msg_logger.info('')
+    msg_logger.info(f'init_logging_status: {init_logging_status}')
+    return init_logging_status
diff --git a/ohmpi_param.json b/ohmpi_param.json
index 018dd93fd39403377d7074565d5356ef36a73ce6..cda9a16697b658b4f57a287040ec967811961927 100644
--- a/ohmpi_param.json
+++ b/ohmpi_param.json
@@ -1,8 +1,8 @@
 {
     "nb_electrodes": 64,
-    "injection_duration":0.2,
+    "injection_duration": 4,
     "nbr_meas": 100,
     "sequence_delay": 1,
     "stack": 1,
-    "export_path": "/home/pi/Documents/OhmPi/measurement.csv" 
+    "export_path": "./measurement.csv"
 }
diff --git a/settings.py b/settings.py
new file mode 100644
index 0000000000000000000000000000000000000000..02737c1d68de756eb4fa76eea3efab5a184070db
--- /dev/null
+++ b/settings.py
@@ -0,0 +1,40 @@
+# OhmPi configuration
+OHMPI_CONFIG = {
+    'id': '0001',  # Unique identifier of the OhmPi board (string)
+    'R_shunt': 2,  # Shunt resistance in Ohms
+    'Imax': 4800/50/2,  # Maximum current
+    'coef_p2': 2.50,  # slope for current conversion for ADS.P2, measurement in V/V
+    'coef_p3': 2.50,  # slope for current conversion for ADS.P3, measurement in V/V
+    'offset_p2': 0,
+    'offset_p3': 0,
+    'integer': 2,  # Max value 10 WHAT IS THIS?
+    'version': 2
+}
+
+# local messages logging configuration
+LOGGING_CONFIG = {
+    'debug_mode': False,
+    'logging_to_console': False,
+    'file_name': 'ohmpi_log',
+    'max_bytes': 262144,
+    'backup_count': 30,
+    'when': 'd',
+    'interval': 1
+}
+
+# local data logging configuration
+DATA_LOGGING_CONFIG = {
+    'file_name': 'data_log',
+    'max_bytes': 16777216,
+    'backup_count': 1024,
+    'when': 'd',
+    'interval': 1
+}
+
+# MQTT configuration parameters
+MQTT_CONFIG = {
+    'mqtt_broker': 'mg3d-dev.umons.ac.be',
+    'client_id': f'ohmpi_sn_{OHMPI_CONFIG["id"]}',
+    'control_topic': f'cmd_ohmpi_sn_{OHMPI_CONFIG["id"]}',
+    'measurements_topic': f'measurements_ohmpi_sn_{OHMPI_CONFIG["id"]}'
+}