From 5987a42681f878588fe07028360b65f8f70df0f2 Mon Sep 17 00:00:00 2001
From: kjunge <kai.junge@epfl.ch>
Date: Sat, 22 Jan 2022 03:57:30 +0100
Subject: [PATCH] Big changes to improve functionality

---
 comms_wrapper.py             | 42 ++++++++++++++----
 comms_wrapper_example.py     | 48 ---------------------
 comms_wrapper_test_ground.py | 36 ++++++++++++++++
 pyComms/pyComms.ino          | 51 ++++++----------------
 pyComms/pyCommsLib.cpp       | 84 +++++++++++++++++++++++-------------
 pyComms/pyCommsLib.h         |  9 +++-
 6 files changed, 143 insertions(+), 127 deletions(-)
 delete mode 100644 comms_wrapper_example.py
 create mode 100644 comms_wrapper_test_ground.py

diff --git a/comms_wrapper.py b/comms_wrapper.py
index 49ceb6f..b8798d2 100644
--- a/comms_wrapper.py
+++ b/comms_wrapper.py
@@ -1,3 +1,4 @@
+from tabnanny import verbose
 import serial
 import serial.tools.list_ports
 from threading import Thread
@@ -20,6 +21,7 @@ class Arduino:
         self.messageNames = list(self.receivedMessages.keys())
         self.arduino = None
         self.handshakeStatus = False
+        self._echo_python_msg = None
 
 
     # Private methods
@@ -82,10 +84,14 @@ class Arduino:
                 msgName = singleMsg.split(";")[0]
                 msgPayload = singleMsg.split(";")[1]
 
-                if msgName not in self.messageNames:
-                    return False
-                
-                receivedMessageTemp[msgName] = msgPayload
+
+                if msgName == "echo_python":
+                        self._echo_python_msg = msgPayload
+                else:
+                    if msgName not in self.messageNames:
+                        return False
+                    
+                    receivedMessageTemp[msgName] = msgPayload
 
             else:
                 return False
@@ -147,6 +153,10 @@ class Arduino:
 
         if self.handshakeStatus: 
             print("Successfull handshake with " + self.descriptiveDeviceName)
+            while 1: 
+                self.receive_message()
+                if self._echo_python_msg == "NO_PYTHON_MESSAGE":
+                    break
         else:
             print("!! Handshake failed with " + self.descriptiveDeviceName + " !!")
 
@@ -161,7 +171,7 @@ class Arduino:
         self._serial_write( msg + "\n")
 
 
-    def receive_message(self, showOutput = False, verbose = False):
+    def receive_message(self, printOutput = False, verbose = False):
         if not self.handshakeStatus:
             print("!! Handshake not completed !!")
             return False
@@ -181,15 +191,31 @@ class Arduino:
             else:
                 pass
             
-            if showOutput: 
+            if printOutput: 
                 if verbose: 
-                    print("Raw message received: ", self._rawReceivedMessage, " |  Segmented message: ", self.receivedMessages)
+                    print("----------------------")
+                    print("Raw message received on python side: ", self._rawReceivedMessage)
+                    print("What python received from the arduino: ", self.receivedMessages)
+                    print("What the arduino received from python: ", self._echo_python_msg, "\n")
                 else:
-                    print("Received: ", self.receivedMessages)
+                    print("What python received from the arduino: ", self.receivedMessages)
 
             time.sleep(0.000001)
             return True
 
+    def debug(self, verbose = False):
+        if verbose:   
+            self.receive_message(printOutput=True, verbose = True)
+        else:
+            print("----------------------")
+            self.receive_message(printOutput=True)
+            print("What the arduino received from python: ", self._echo_python_msg, "\n")
+            
+
+        for key, value in self.receivedMessages.items():
+            if value is None: 
+                print("Check if message name: ", key, " agrees with the arduino side")
+
 
 ########
 ### Key commands
diff --git a/comms_wrapper_example.py b/comms_wrapper_example.py
deleted file mode 100644
index 564c1a8..0000000
--- a/comms_wrapper_example.py
+++ /dev/null
@@ -1,48 +0,0 @@
-from comms_wrapper import *
-
-def main():
-    # Define keyboard instance to use key commands easily
-    key = Key()
-
-    # Define arduino1 instance
-    arduino1 = Arduino(descriptiveDeviceName="Uno 1", portName="/dev/ttyACM0", baudrate=115200)
-    arduino2 = Arduino(descriptiveDeviceName="Uno 2", portName="/dev/ttyACM1", baudrate=115200)
-    arduinos = [arduino1, arduino2]
-
-    # This defines the messages sent from the arduino1 to the python side
-    # The names must match exactly between the arduino1 and python side
-    for arduino in arduinos:
-        arduino.add_new_message_name("item1")
-        arduino.add_new_message_name("item2")
-        arduino.add_new_message_name("item3")
-
-        # Connects with the arduino1 and does the handshake to start void loop()
-        arduino.connect_and_handshake()
-
-    
-    # Your loop or process to do somthing
-    while 1: 
-
-        # Receive messages from arduino side
-        for arduino in arduinos:
-            if arduino.receive_message():
-                print("For :", arduino.descriptiveDeviceName, " msg: ", arduino.receivedMessages)
-
-        # simple key commands for testing
-        if key.keyPressValue == "t":
-            arduino1.send_message("On")
-
-        if key.keyPressValue == "f":
-            arduino1.send_message("Off")
-
-        if key.keyPressValue == "y":
-            arduino2.send_message("On")
-
-        if key.keyPressValue == "n":
-            arduino2.send_message("Off")
-
-        time.sleep(0.2)
-
-if __name__ == '__main__':
-    main() 
-    
\ No newline at end of file
diff --git a/comms_wrapper_test_ground.py b/comms_wrapper_test_ground.py
new file mode 100644
index 0000000..8a2061e
--- /dev/null
+++ b/comms_wrapper_test_ground.py
@@ -0,0 +1,36 @@
+from re import A
+from tabnanny import verbose
+from comms_wrapper import *
+
+def main():
+    # Define keyboard instance to use key commands easily
+    key = Key()
+
+    # Define arduino1 instance
+    arduino1 = Arduino(descriptiveDeviceName="Uno 1", portName="/dev/ttyACM0", baudrate=115200)
+
+    # This defines the messages sent from the arduino1 to the python side
+    # The names must match exactly between the arduino1 and python side
+    arduino1.define_message_names(["msgA", "msgB", "msgC"])
+
+    # Connects with the arduino1 and does the handshake to start void loop()
+    arduino1.connect_and_handshake()
+
+    
+    # Your loop or process to do somthing
+    while 1: 
+        # Receive messages from arduino side
+        arduino1.debug()
+
+        if key.keyPressValue == "f": 
+            arduino1.send_message("yes")
+
+        if key.keyPressValue == "g":
+            arduino1.send_message("no")
+
+
+        time.sleep(0.2)
+
+if __name__ == '__main__':
+    main() 
+    
\ No newline at end of file
diff --git a/pyComms/pyComms.ino b/pyComms/pyComms.ino
index 7cc0304..d56c95f 100644
--- a/pyComms/pyComms.ino
+++ b/pyComms/pyComms.ino
@@ -1,24 +1,12 @@
 #include "pyCommsLib.h"
 
+
 /*
  * Variables for you need to define for this program to work
  */
+String msgName[] = {"msgA", "msgB", "msgC"};
+String dataCarrier[3];
 
-// An array of strings containing the names of the variables 
-// which the Arduino will send to python
-// you will need to define the same name on the python side
-String msgName[] = {"item1", "item2", "item3"};
-
-// An array of strings which will be the payload
-// Each element corresponds to the message defined in msgName
-// Make sure the array length of msgName and Data match
-String dataCarrier[] = {"Null", "Null", "Null"};
-
-// The length of the msgName and Data array
-const int numOfMsg = 3;
-
-// Define the string where the recieved message will be captured
-String rawMsg = "NULL";
 
 
 void setup() {
@@ -32,23 +20,6 @@ void setup() {
 void loop() {
 
 
-  ////////////////////
-  // RECEIVING DATA
-  ////////////////////
-  
-  // Receive messages from python. 
-  // Just copy and paste this 
-  rawMsg = recieve_msg(rawMsg);
-
-  // An example of how you might want to use the message received from python/
-  /*
-   * if(rawMsg == "blah") {
-   *  // do something
-   * }
-   */
-
-
-  
   ////////////////////
   // SENDING DATA
   ////////////////////
@@ -59,13 +30,17 @@ void loop() {
 
   This can be easilly done by doing String(whatever) - see Data[1] = String(20);
   */
-  Data[0] = "a";
-  Data[1] = String(20);
-  Data[2] = rawMsg;
 
-  // The send command. Just copy and paste this. 
-  send_msg(msgName, Data, numOfMsg);
+  dataCarrier[0] = "Some message";
+  dataCarrier[1] = String(3);
+  dataCarrier[2] = received_msg();
 
-  // this delay is not necessary - it's only to show that even with a delay this process works.
+
+  // The send command. Just copy and paste this. 
+  load_msg_to_python(msgName, dataCarrier, size_of_array(msgName));
+  
+  // this delay is not necessary to have here - it's only to show that even with a delay this process works.
   delay(100);
+
+  sync();
 }
diff --git a/pyComms/pyCommsLib.cpp b/pyComms/pyCommsLib.cpp
index d5fd277..fa396a3 100644
--- a/pyComms/pyCommsLib.cpp
+++ b/pyComms/pyCommsLib.cpp
@@ -1,61 +1,83 @@
 #include "pyCommsLib.h"
 #include "Arduino.h"
 
+#define size_of_array(arr) sizeof(arr) / sizeof(*arr)
 
-void send_msg(String* msgName, String* msg, int numOfMsg) {
-  // If we have the same number of data compared to the message
-  String payload = "<";
+String rawMsgFromPython = "NO_PYTHON_MESSAGE";
+String payload = "";
 
-  for(int i = 0; i < numOfMsg; i++) { 
+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(":");
   }
+}
 
-  payload.concat(">");
+void receive_msg_from_python() {
+
+  String msg = "";
+
+  while (Serial.available()) {
+    if (Serial.available()) {
+      msg = Serial.readStringUntil('\n');
+    }
+  }
+
+  if (msg != "") {
+    rawMsgFromPython = msg;
+  }
 
-  Serial.println(payload);
-  
 }
 
-String recieve_msg(String prevMsg) {
-    
-    String msg = "";
 
-   while(Serial.available()) {
-     if(Serial.available()) {
-      msg = Serial.readStringUntil('\n');
-     }
-   }
-
-   if(msg == "") {
-    msg = prevMsg; 
-   }
-   
-   return msg;
+String received_msg() { 
+  return rawMsgFromPython;
 }
 
+void init_python_communication() {
 
-void init_python_communication() { 
-  
-  while(true){ 
+  while (true) {
     // if the python side sent a message
-    if(Serial.available() > 0) {
-      String rawMsg = Serial.readStringUntil('\n');
-      if(rawMsg == "handshake1") { 
+    if (Serial.available() > 0) {
+      String rawMsgFromPython = Serial.readStringUntil('\n');
+      if (rawMsgFromPython == "handshake1") {
         break;
       }
     }
   }
 
   long timer = millis();
-  while(millis() - timer < 1000) { 
+  while (millis() - timer < 1000) {
     Serial.println("handshake2");
   }
 
-     
-   while(Serial.available()) {
+
+  while (Serial.available()) {
     Serial.read();
-   }
+  }
+}
+
+
+void echo_python() {
+  String echo = "<echo_pytyon;";
+  echo.concat(received_msg());
+  echo.concat(":>");
+
+  Serial.println(echo);
+}
+
+
+void sync() { 
+  receive_msg_from_python();
+  String final_payload = "<echo_python;";
+  final_payload.concat(received_msg());
+  final_payload.concat(":");
+  final_payload.concat(payload); 
+  final_payload.concat(">");
+  Serial.println(final_payload);
 }
diff --git a/pyComms/pyCommsLib.h b/pyComms/pyCommsLib.h
index 3a94955..1da9eb6 100644
--- a/pyComms/pyCommsLib.h
+++ b/pyComms/pyCommsLib.h
@@ -1,12 +1,17 @@
 #ifndef PYCOMMSLIB_H
 #define PYCOMMSLIB_H
 
+#define size_of_array(arr) sizeof(arr) / sizeof(*arr)
+
+
 #include <Arduino.h>
 
-void send_msg(String* msgName, String* msg, int numOfMsg);
+void load_msg_to_python(String* msgName, String* msg, int numOfMsg);
 
-String recieve_msg(String prevMsg);
+String received_msg();
 
 void init_python_communication();
 
+void sync();
+
 #endif
-- 
GitLab