diff --git a/LICENSE b/LICENSE
index d9e38d6696ea9771bf927a9221f7a9fa842cb58d..02598a246c57ccb039b4898807de1425056aea8f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-                    GNU GENERAL PUBLIC LICENSE
+LICENSE                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
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/mqtt_setup.py b/mqtt_setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..9067c5251e7dd58fbf45987701a1a37b84304a8f
--- /dev/null
+++ b/mqtt_setup.py
@@ -0,0 +1,18 @@
+from settings import MQTT_CONFIG
+import paho.mqtt.client as mqtt
+
+
+def on_message(client, userdata, message):
+    m = str(message.payload.decode("utf-8"))
+    print(f'message received {m}')
+    print(f'topic: {message.topic}')
+    print(f'qos: {message.qos}')
+    print(f'retain flag: {message.retain}')
+    client.publish(MQTT_CONFIG['measurements_topic'], f'{m} 45 ohm.m')
+
+
+def mqtt_client_setup():
+    client = mqtt.Client(MQTT_CONFIG['client_id'], protocol=5)  # create new client instance
+    client.connect(MQTT_CONFIG['mqtt_broker'])
+    client.on_message = on_message
+    return client, MQTT_CONFIG['measurements_topic']
diff --git a/Ohmpi.py b/ohmpi.py
similarity index 97%
rename from Ohmpi.py
rename to ohmpi.py
index 81d1e296525d96ce105181811fea572de38d92aa..ae8ef7b3a146fcbbcb2aca29c2156f0d52961f2f 100644
--- a/Ohmpi.py
+++ b/ohmpi.py
@@ -16,6 +16,8 @@ import time
 from datetime import datetime
 from termcolor import colored
 import threading
+from logging_setup import setup_loggers
+# from mqtt_setup import mqtt_client_setup
 
 # finish import (done only when class is instantiated as some libs are
 # only available on arm64 platform)
@@ -31,11 +33,13 @@ try:
     from digitalio import Direction
     from gpiozero import CPUTemperature
     arm64_imports = True
-except Exception as e:
+except ImportError as e:
     print(f'Warning: {e}')
     arm64_imports = False
 
-
+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}')
 VERSION = '2.0.1'
 
 print('\033[1m'+'\033[31m'+' ________________________________')
@@ -53,13 +57,6 @@ current_time = datetime.now()
 print(current_time.strftime("%Y-%m-%d %H:%M:%S"))
 
 
-# from logging_setup import setup_loggers
-# from mqtt_setup import mqtt_client_setup
-# 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}')
-
-
 class OhmPi(object):
     """Create the main OhmPi object.
 
@@ -70,8 +67,6 @@ class OhmPi(object):
     sequence : str, optional
         Path to the .txt where the sequence is read. By default, a 1 quadrupole
         sequence: 1, 2, 3, 4 is used.
-    on_pi : bool, optional
-        True if running on the RaspberryPi. False for testing (random data generated).
     output : str, optional
         Either 'print' for a console output or 'mqtt' for publication onto
         MQTT broker.
@@ -87,8 +82,7 @@ class OhmPi(object):
 
         if not arm64_imports:
             self.dump(f'Warning: {e}\n Some libraries only available on arm64 platform could not be imported.\n'
-                  f'The Ohmpi class will fake operations for testing purposes.', 'warning')
-
+                      f'The Ohmpi class will fake operations for testing purposes.', 'warning')
 
         # read in hardware parameters (settings.py)
         self._read_hardware_parameters()
@@ -114,14 +108,6 @@ class OhmPi(object):
         else:
             self.read_quad(sequence)
 
-        # address of the multiplexer board
-        self.board_address = {
-            'A': 0x76,
-            'B': 0x71,
-            'M': 0x74,
-            'N': 0x70
-        }
-
         # connect to components on the OhmPi board
         if self.on_pi:
             # activation of I2C protocol
@@ -198,6 +184,7 @@ class OhmPi(object):
         self.nb_samples = OHMPI_CONFIG['integer']  # number of samples measured for each stack
         self.version = OHMPI_CONFIG['version']  # hardware version
         self.max_elec = OHMPI_CONFIG['max_elec']  # maximum number of electrodes
+        self.board_address = OHMPI_CONFIG['board_address']
         self.dump('OHMPI_CONFIG = ' + str(OHMPI_CONFIG), level='debug')
 
     @staticmethod
diff --git a/requirements.txt b/requirements.txt
index 76ed151b75175e25781bdeccfb6f2f02a0a376e5..ef9dd3ef00dd254ea4754d5544a2b4f00bc445f6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
 RPi.GPIO
 adafruit-blinka
 numpy
-pandas
+paho-mqtt
 adafruit-circuitpython-ads1x15
 adafruit-circuitpython-tca9548a
 adafruit-circuitpython-mcp230xx
diff --git a/settings.py b/settings.py
index d57801920eeae972dd231ced847190b7de227c81..23f3544a9268dd4571a8996a1c9ac9dd1116060a 100644
--- a/settings.py
+++ b/settings.py
@@ -10,6 +10,7 @@ OHMPI_CONFIG = {
     'integer': 2,  # Max value 10 WHAT IS THIS?
     'version': 2,
     'max_elec': 64,
+    'board_address': {'A': 0x76, 'B': 0x71, 'M': 0x74, 'N': 0x70}  # def. {'A': 0x76, 'B': 0x71, 'M': 0x74, 'N': 0x70}
 }
 
 # local messages logging configuration