diff --git a/comms_wrapper.py b/comms_wrapper.py index 5377bf2409056e8af1802c993b6291c1934ebf6b..978bf14e39d7803f2d09d2b484e35311298cf4b0 100644 --- a/comms_wrapper.py +++ b/comms_wrapper.py @@ -66,8 +66,6 @@ class Arduino: self.arduino.dtr = False self.connectionStatus = True - - self.arduino.set_buffer_size(rx_size = 1280000, tx_size = 1280000) print("Successfully connected to " + self.descriptiveDeviceName) return True diff --git a/comms_wrapper_new.py b/comms_wrapper_new.py index 463e158b15a2d8aa2a4f3da9356feef296b75631..afcf9cb351dceb4a9adbc1b19a7ccf4792d9c2b7 100644 --- a/comms_wrapper_new.py +++ b/comms_wrapper_new.py @@ -76,8 +76,6 @@ class Arduino: self.connectionStatus = True - self.arduino.set_buffer_size(rx_size = 1280000, tx_size = 1280000) - print("Successfully connected to " + self.descriptiveDeviceName) return True except: @@ -110,7 +108,7 @@ class Arduino: # Conduct handshake while time.time() - timeoutTimer < handshakeTimeoutSec: self._serial_write("handshake1\n") - time.sleep(0.1) + #time.sleep(0.1) if self._rawReceivedMessage == "handshake2": self.handshakeStatus = True @@ -137,13 +135,11 @@ class Arduino: payload += str(msg) payload += "@" - payload = "#####" + payload[:-1] + "%" + payload = "#####" + payload[:-1] + "\n" if payload != self._prev_payload: self._prev_payload = payload - for i in range(2): - self._serial_write(payload) - time.sleep(0.1) + self._serial_write(payload) def receive_message(self, printOutput = False, verbose = False): if not self.handshakeStatus: diff --git a/comms_wrapper_original.py b/comms_wrapper_original.py new file mode 100644 index 0000000000000000000000000000000000000000..978bf14e39d7803f2d09d2b484e35311298cf4b0 --- /dev/null +++ b/comms_wrapper_original.py @@ -0,0 +1,273 @@ +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: + time.sleep(0.000001) + + 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): + 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_original.py b/test_original.py new file mode 100644 index 0000000000000000000000000000000000000000..848ac76f266e0022b144c8ab1e13fcbb76fa94d7 --- /dev/null +++ b/test_original.py @@ -0,0 +1,40 @@ +from comms_wrapper_original import * +from time import sleep, time + +def main(): + key = Key() + + + ad = Arduino(descriptiveDeviceName="myArduino", portName="/dev/ttyACM0", baudrate=115200) + + #ad.define_message_names(["msgA", "msgB"]) + + ad.connect_and_handshake() + + timer = time() + while 1: + + # ad.receive_message() + # print(ad.receivedMessages) + + if key.keyPress == "f": + ad.send_message("apples") + #arduino2.send_message("oranges") + + if key.keyPress == "g": + ad.send_message("bananas") + #arduino2.send_message("grapes") + 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(str(t)) + + print(ad._rawReceivedMessage) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/test_original/pyCommsLib.cpp b/test_original/pyCommsLib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb2d4b3fcbbe446275fbb98fff7998fb9e68be84 --- /dev/null +++ b/test_original/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_original/pyCommsLib.h b/test_original/pyCommsLib.h new file mode 100644 index 0000000000000000000000000000000000000000..75ee2f403b9fcfa83110c91c443760c37797aa1d --- /dev/null +++ b/test_original/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_original/test_original.ino b/test_original/test_original.ino new file mode 100644 index 0000000000000000000000000000000000000000..b7964ac3f6b45b1fc42fde2c068946339aabbc25 --- /dev/null +++ b/test_original/test_original.ino @@ -0,0 +1,37 @@ +#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 message"; + dataCarrier[1] = String(3); + + + + //load_msg_to_python(msgName, dataCarrier, size_of_array(msgName)); + + + + sync(); + + + //delay(100); +} diff --git a/test_windows.py b/test_windows.py index e44463f350866b4b16b19e02540cddad37ed1089..54998e77bc7c23431cf8df56d4486eb1be2c9f12 100644 --- a/test_windows.py +++ b/test_windows.py @@ -1,30 +1,16 @@ from comms_wrapper_new import * from time import sleep, time -import msvcrt -def getch(): - return msvcrt.getch().decode() - def main(): key = Key() - arduino1 = Arduino(descriptiveDeviceName="myArduino", portName="COM7", baudrate=2000000) - arduino1.define_number_of_messages(2, 2) + arduino1 = Arduino(descriptiveDeviceName="myArduino", portName="/dev/ttyACM0", baudrate=115200) + arduino1.define_number_of_messages(0, 1) arduino1.connect_and_handshake() - prev = "" timer = time() while 1: - arduino1.receive_message() - # if arduino1._rawReceivedMessage != prev: - # print("REC:", arduino1._rawReceivedMessage) - # prev = arduino1._rawReceivedMessage - - if arduino1.newMsgRecieved: - #print(arduino1.receivedMessages) - print(arduino1._rawOrganizedMessages) - #arduino1.send_message([str(round(time() - timer, 2)) ]) t = str(round(time() - timer, 5)) while 1: @@ -34,10 +20,9 @@ def main(): t = t[:-1] else: break - arduino1.send_message([t,"m"]) + arduino1.send_message([t]) - - sleep(0.001) + print(arduino1._rawReceivedMessage, arduino1._rawOrganizedMessages) if __name__ == '__main__': main() \ No newline at end of file diff --git a/test_windows/pyCommsLib.cpp b/test_windows/pyCommsLib.cpp index 03716b110723707746d6259a77250f1d8dcad72c..6a383941199fba40be1df80e247b83f80414ac2e 100644 --- a/test_windows/pyCommsLib.cpp +++ b/test_windows/pyCommsLib.cpp @@ -29,20 +29,22 @@ void receive_msg_from_python() { String msg = ""; - while (Serial.available()>5) { - msg = Serial.readStringUntil('%'); - msg.remove(0,5); - break; + while (Serial.available()) { + msg = Serial.readStringUntil('\n'); + //msg.remove(0,5); + //break; } while (Serial.available()) { Serial.read(); } - + if (msg != "") { rawMsgFromPython = msg; } + +//Serial.println(rawMsgFromPython); } diff --git a/test_windows/test_windows.ino b/test_windows/test_windows.ino index ccab4deb425ebc2386127ad8fe1372106e3f63bc..a010cb5a6a4339cc5bb23085d5f73fbe6cf3b24d 100644 --- a/test_windows/test_windows.ino +++ b/test_windows/test_windows.ino @@ -1,11 +1,11 @@ #include "pyCommsLib.h" -String msgName[] = {"pot", "msg2"}; -String dataCarrier[2]; +String msgName[] = {}; +String dataCarrier[0]; void setup() { // Start the serial communication. The baudrate is arbiturary. - Serial.begin(2000000); + Serial.begin(115200); // Connect with the Python side init_python_communication(); @@ -16,9 +16,10 @@ void loop() { int pot = analogRead(A0); //Serial.println(pot); - - dataCarrier[0] = String(pot); - dataCarrier[1] = "ddddd"; + //dataCarrier[0] = String(pot); + //dataCarrier[1] = "ddddd"; + +//receive_msg_from_python(); send_msg_to_python(msgName, dataCarrier, size_of_array(msgName)); }