diff --git a/comms_wrapper_new2.py b/comms_wrapper_new2.py
new file mode 100644
index 0000000000000000000000000000000000000000..989794c4a996df5b044bac0ac02458fd2b785fd2
--- /dev/null
+++ b/comms_wrapper_new2.py
@@ -0,0 +1,276 @@
+import serial
+import serial.tools.list_ports
+from threading import Thread
+import time
+from pynput import keyboard
+import copy
+
+########
+### Arduino communication
+########
+
+class Arduino: 
+    def __init__(self, descriptiveDeviceName, portName, baudrate): 
+        # About the device
+        self.descriptiveDeviceName = descriptiveDeviceName
+        self.portName = portName
+        self.baudrate = baudrate
+        
+        # Communication
+        self._rawReceivedMessage = None
+        self.receivedMessages = {}
+        self.messageNames = None
+        self.arduino = None
+        self.handshakeStatus = False
+        self.connectionStatus = False
+        self._echo_python_msg = None
+        self.newMsgRecieved = False
+
+        # Threading
+        self.__thread = None
+
+    # Private methods
+    def _serial_readline(self):
+        while 1:
+            try:
+                self._rawReceivedMessage = self.arduino.readline().decode('utf-8')[:-2]
+            except:
+                pass
+                #time.sleep(0.00001)
+
+    def _startReadingThread(self):
+        self.__thread = Thread(target=self._serial_readline)
+        self.__thread.daemon = True
+        self.__thread.start()
+
+
+    def _serial_write(self, msg):
+        if self.arduino is not None:
+            self.arduino.write(bytes(msg, 'utf-8'))
+
+
+    def _add_new_message_name(self, msgName):
+        if msgName in self.receivedMessages:
+            print("!! Message name ", msgName, " already exists so it cannot be added. !!")
+        else:
+            self.receivedMessages[msgName] = None
+            self.messageNames = list(self.receivedMessages.keys())
+
+
+    def _connect_to_arduino(self):
+        # Connect to the arduino device
+        try: 
+            self.arduino = serial.Serial(port=self.portName, baudrate=self.baudrate)
+
+            # toggle dtr to reset the arduino
+            self.arduino.dtr = True
+            self.arduino.dtr = False
+
+            self.connectionStatus = True
+        
+            print("Successfully connected to " + self.descriptiveDeviceName)
+            return True
+        except:
+            print("!! Cannot connect to " + self.descriptiveDeviceName + " !!")
+            return False
+        
+
+    def _disect_and_save_message(self, msg):
+        receivedMessageTemp = copy.deepcopy(self.receivedMessages)
+
+        if msg[-2] != ":":
+            return False
+
+        msg = msg[1:-2]
+        splitMsg = msg.split(":")
+        for singleMsg in splitMsg:
+            if len(singleMsg.split(";")) == 2:
+                msgName = singleMsg.split(";")[0]
+                msgPayload = singleMsg.split(";")[1]
+
+                if msgName == "e*p":
+                        self._echo_python_msg = msgPayload
+                else:
+                    if msgName not in self.messageNames:
+                        return False
+                    
+                    receivedMessageTemp[msgName] = msgPayload
+
+            else:
+                return False
+        
+        if receivedMessageTemp == self.receivedMessages: 
+            self.newMsgRecieved = False
+        else: 
+            self.newMsgRecieved = True
+        
+        self.receivedMessages = receivedMessageTemp
+        return True
+
+        
+    # Public methods
+    def define_message_names(self, msgNames):
+        if type(msgNames) == list:
+            for msg in msgNames:
+                self._add_new_message_name(msg) 
+        else: 
+            print("Argument should be of type 'list'")
+
+
+    def connect_and_handshake(self): 
+        # Connect to the arduino device
+
+        if self._connect_to_arduino():
+            pass
+        else:
+            return False
+
+        # Start the reading thread
+        self._startReadingThread()
+        
+        # Wait for a bit for the arduino to initialise nicely
+        time.sleep(0.5)
+
+        # Conduct the handshake process
+        timeoutTimer = time.time()
+        handshakeTimeoutSec = 5
+
+        self.arduino.reset_input_buffer()
+        self.arduino.reset_output_buffer()
+
+
+        while time.time() - timeoutTimer < handshakeTimeoutSec:
+            self._serial_write("handshake1\n")
+            time.sleep(0.1)
+
+            if self._rawReceivedMessage == "handshake2":
+                self.handshakeStatus = True
+                break
+
+        if self.handshakeStatus: 
+            # while 1: 
+            #     self.receive_message()
+            #     if self._echo_python_msg == "NO_PYTHON_MESSAGE":
+            #         break
+            print("Successfull handshake with " + self.descriptiveDeviceName)
+            time.sleep(1)
+        else:
+            print("!! Handshake failed with " + self.descriptiveDeviceName + " !!")
+
+        return self.handshakeStatus
+
+
+    def disconnect_arduino(self):
+        self.arduino.close()
+
+
+    def send_message(self, msg):
+        if type(msg) != str:
+            msg = str(msg)
+        self._serial_write( msg + "\n")
+
+
+    def receive_message(self, printOutput = False, verbose = False):
+        if not self.handshakeStatus:
+            print("!! Handshake not completed !!")
+            return False
+        else:
+            isMessageValid = True
+            msg = self._rawReceivedMessage
+            # sanity check 1: check if ends of the message are < and >
+            try:
+                if msg[0] == "<" and msg[-1] == ">":
+                    pass
+                else:
+                    isMessageValid = False
+            except:
+                isMessageValid = False
+            if isMessageValid:
+                isMessageValid = self._disect_and_save_message(msg)
+            else:
+                pass
+            
+            if printOutput: 
+                if verbose: 
+                    print("----------------------")
+                    print("Raw message received on python side: ", self._rawReceivedMessage)
+                    print("Messege received from the arduino: ", self.receivedMessages)
+                    print("Python message stored on", self.descriptiveDeviceName, ": ", self._echo_python_msg, "\n")
+
+                else:
+                    print("Messege received from the arduino: ", self.receivedMessages)
+
+            time.sleep(0.0001)
+            return True
+
+
+    def current_status(self):
+        status = {
+            "Device name" : self.descriptiveDeviceName, 
+            "Baudrate: ": self.baudrate,
+            "Portname: ": self.portName, 
+            "Connection: ": self.connectionStatus, 
+            "Handshake: ": self.handshakeStatus, 
+            "Message names: ": self.messageNames
+            }
+
+        return status
+    
+
+    def debug(self, verbose = False):
+        if verbose:   
+            self.receive_message(printOutput=True, verbose = True)
+
+            print("Current status of this device:")
+            print(self.current_status())
+            
+        else:
+            print("----------------------")
+            self.receive_message(printOutput=True)
+            print("Python message stored on", self.descriptiveDeviceName, ": ", self._echo_python_msg, "\n")
+            
+
+        for key, value in self.receivedMessages.items():
+            if value is None: 
+                print("Check if message names: ", key, " agrees with the arduino side")
+
+
+########
+### Key commands
+########
+
+class Key():
+    def __init__(self):                
+        self.keyPressLatching = None
+        self._keyReleaseLatching = None
+        self.keyPress = None
+        self._start_keyboard_listener()
+
+    def _on_press(self, key):
+        try:
+            self.keyPressLatching = key.char
+            self.keyPress = key.char
+            
+        except AttributeError:
+            self.keyPressLatching = key
+            self.keyPress = key
+            
+
+    def _on_release(self, key):
+        try:
+            self._keyReleaseLatching = key.char
+
+            if self._keyReleaseLatching == self.keyPress: 
+                self.keyPress = None
+
+        except AttributeError:
+            self._keyReleaseLatching = key
+
+            if self._keyReleaseLatching == self.keyPress: 
+                self.keyPress = None
+
+
+    def _start_keyboard_listener(self):  
+        listener = keyboard.Listener(on_press=self._on_press, on_release=self._on_release)
+        listener.start()
+        print("keyboard listener started")
\ No newline at end of file
diff --git a/test_new.py b/test_new.py
new file mode 100644
index 0000000000000000000000000000000000000000..bc4f9cc77fc9ba011f7f0b1eb921b43c02a75cb5
--- /dev/null
+++ b/test_new.py
@@ -0,0 +1,25 @@
+from comms_wrapper_new2 import *
+from time import sleep, time
+
+def main():
+    key = Key()
+
+    ad = Arduino(descriptiveDeviceName="myArduino", portName="COM10", baudrate=115200)
+    ad.define_message_names(["msgA", "msgB"])
+    ad.connect_and_handshake()
+
+    timer = time()
+    while 1: 
+        t = str(round(time() - timer, 5))
+        while 1: 
+            if len(t) < 5:
+                t += "0"
+            elif len(t) > 5: 
+                t = t[:-1]
+            else: 
+                break
+        ad.send_message(t)
+        print(ad._rawReceivedMessage)
+
+if __name__ == '__main__':
+    main()
\ No newline at end of file
diff --git a/test_new/pyCommsLib.cpp b/test_new/pyCommsLib.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cb2d4b3fcbbe446275fbb98fff7998fb9e68be84
--- /dev/null
+++ b/test_new/pyCommsLib.cpp
@@ -0,0 +1,78 @@
+#include "pyCommsLib.h"
+#include "Arduino.h"
+
+
+#define size_of_array(arr) sizeof(arr) / sizeof(*arr)
+
+
+String rawMsgFromPython = "NO_PYTHON_MESSAGE";
+String payload = "";
+
+
+void load_msg_to_python(String* msgName, String* msg, int numOfMsg) {
+  // If we have the same number of data compared to the message
+  payload = "";
+  
+  for (int i = 0; i < numOfMsg; i++) {
+    payload.concat(msgName[i]);
+    payload.concat(";");
+    payload.concat(msg[i]);
+    payload.concat(":");
+  }
+}
+
+
+void receive_msg_from_python() {
+
+  String msg = "";
+
+  while (Serial.available()) {
+    if (Serial.available()) {
+      msg = Serial.readStringUntil('\n');
+    }
+  }
+
+  if (msg != "") {
+    rawMsgFromPython = msg;
+  }
+
+}
+
+
+String latest_received_msg() { 
+  return rawMsgFromPython;
+}
+
+void init_python_communication() {
+
+  while (true) {
+    // if the python side sent a message
+    if (Serial.available() > 0) {
+      String rawMsgFromPython = Serial.readStringUntil('\n');
+      if (rawMsgFromPython == "handshake1") {
+        break;
+      }
+    }
+  }
+
+  long timer = millis();
+  while (millis() - timer < 1000) {
+    Serial.println("handshake2");
+  }
+
+
+  while (Serial.available()) {
+    Serial.read();
+  }
+}
+
+
+void sync() { 
+  receive_msg_from_python();
+  String final_payload = "<echo_python;";
+  final_payload.concat(latest_received_msg());
+  final_payload.concat(":");
+  final_payload.concat(payload); 
+  final_payload.concat(">");
+  Serial.println(final_payload);
+}
diff --git a/test_new/pyCommsLib.h b/test_new/pyCommsLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..75ee2f403b9fcfa83110c91c443760c37797aa1d
--- /dev/null
+++ b/test_new/pyCommsLib.h
@@ -0,0 +1,17 @@
+#ifndef PYCOMMSLIB_H
+#define PYCOMMSLIB_H
+
+#define size_of_array(arr) sizeof(arr) / sizeof(*arr)
+
+
+#include <Arduino.h>
+
+void load_msg_to_python(String* msgName, String* msg, int numOfMsg);
+
+String latest_received_msg();
+
+void init_python_communication();
+
+void sync();
+
+#endif
diff --git a/test_new/test_new.ino b/test_new/test_new.ino
new file mode 100644
index 0000000000000000000000000000000000000000..68b6761eb384b9dcd7bede90570662ad1dd527d0
--- /dev/null
+++ b/test_new/test_new.ino
@@ -0,0 +1,26 @@
+#include "pyCommsLib.h"
+
+String msgName[] = {"msgA", "msgB"};
+
+String dataCarrier[2];
+
+void setup() {
+  // Start the serial communication. The baudrate is arbiturary.
+  Serial.begin(115200);
+
+  // Connect with the Python side
+  init_python_communication();
+}
+
+void loop() {
+  
+  // This is how you access the latest received message from the Python side
+  String received_message = latest_received_msg();
+
+  dataCarrier[0] = "Some very long message that we want to send";
+  dataCarrier[1] = String(analogRead(A0));
+
+  load_msg_to_python(msgName, dataCarrier, size_of_array(msgName));
+  sync();
+
+}
diff --git a/test_original.py b/test_original.py
index 848ac76f266e0022b144c8ab1e13fcbb76fa94d7..f9c38495e6b208afcf0cecb8a0f154e388dfffaa 100644
--- a/test_original.py
+++ b/test_original.py
@@ -5,7 +5,7 @@ def main():
     key = Key()
 
 
-    ad = Arduino(descriptiveDeviceName="myArduino", portName="/dev/ttyACM0", baudrate=115200)
+    ad = Arduino(descriptiveDeviceName="myArduino", portName="COM", baudrate=115200)
 
     #ad.define_message_names(["msgA", "msgB"])
 
diff --git a/test_original/test_original.ino b/test_original/test_original.ino
index b7964ac3f6b45b1fc42fde2c068946339aabbc25..8efbce81ea79e82ac165228d4beb71e9cf809d29 100644
--- a/test_original/test_original.ino
+++ b/test_original/test_original.ino
@@ -27,9 +27,6 @@ void loop() {
 
 
   //load_msg_to_python(msgName, dataCarrier, size_of_array(msgName));
-
-
-
   sync();
 
 
diff --git a/test_windows.py b/test_windows.py
index 54998e77bc7c23431cf8df56d4486eb1be2c9f12..1435ba8c70752eb1bb23f9a0b771e317f1eb96d3 100644
--- a/test_windows.py
+++ b/test_windows.py
@@ -4,7 +4,7 @@ from time import sleep, time
 def main():
     key = Key()
 
-    arduino1 = Arduino(descriptiveDeviceName="myArduino", portName="/dev/ttyACM0", baudrate=115200)
+    arduino1 = Arduino(descriptiveDeviceName="myArduino", portName="COM7", baudrate=115200)
     arduino1.define_number_of_messages(0, 1)
     arduino1.connect_and_handshake()