From 70bb59fb6a2241da27b5c1d2c8d736bc45621be3 Mon Sep 17 00:00:00 2001
From: Pascal <engelerp@phys.ethz.ch>
Date: Tue, 13 Jun 2023 16:56:05 +0200
Subject: [PATCH] Added supervision checking

---
 .../drivers/communicator/communicator.cpp     | 25 +++++++++++++++++--
 .../drivers/communicator/communicator.hpp     |  7 ++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/firmware/drivers/communicator/communicator.cpp b/firmware/drivers/communicator/communicator.cpp
index 4241c31..7e133ef 100644
--- a/firmware/drivers/communicator/communicator.cpp
+++ b/firmware/drivers/communicator/communicator.cpp
@@ -5,6 +5,7 @@
 #include <pid_controller.hpp>
 #include <cstdlib> //std::strtod
 #include <algorithm> //This is necessary to fix a bug that cost me 4h.
+#include <Arduino.h>
 
 /*
     As I tracked down, a (standard) string library calls std::min() in some functions (like compare).
@@ -14,16 +15,28 @@
     Holy fucking shit.
 */
 
-unsigned long Communicator::timeout_us_ = 20000; //timeout 20ms
+unsigned long Communicator::timeout_us_ = 20000u; //timeout 20ms
 char Communicator::outbuf_[256]; //out buffer
 char Communicator::cmd_ = 'X'; //command received
 std::vector<char> Communicator::arg_ = std::vector<char>(256, '\0'); //arguments received
+unsigned long Communicator::last_transaction_ms_ = 0u; //time of last transaction
+unsigned long Communicator::interval_assume_eow_ms_ = 1800000u; //no transaction for 30 minutes means we shut down
 
 bool Communicator::communicate(){
-    if(!serialCharAvailable_()){
+    if(!serialCharAvailable_()){ //no communication
+        if(msElapsedSinceLastTransaction_() > interval_assume_eow_ms_){
+            //no sign of supervision for 30 minutes, shut down
+            Pid_controller::turn_off();
+        }
+        else{
+            //have supervision, turn PID Controller on
+            Pid_controller::turn_on();
+        }
         return false;
     }
     else{
+        startTransactionTimer_();
+        Pid_controller::turn_on(); //have supervision, make sure PID Controller is enabled
         cmd_ = getSerialChar_();
         if(isSetCommand_()){
             //read argument
@@ -223,3 +236,11 @@ void Communicator::handleInvalidCommand_(){
     sendBuf_();
     return;
 }
+
+void Communicator::startTransactionTimer_(){
+    last_transaction_ms_ = millis();
+}
+
+unsigned long Communicator::msElapsedSinceLastTransaction_(){
+    return static_cast<unsigned long>(millis() - last_transaction_ms_);
+}
\ No newline at end of file
diff --git a/firmware/drivers/communicator/communicator.hpp b/firmware/drivers/communicator/communicator.hpp
index 560722f..bb12823 100644
--- a/firmware/drivers/communicator/communicator.hpp
+++ b/firmware/drivers/communicator/communicator.hpp
@@ -24,6 +24,9 @@ private:
     static void handleSetCommand_();
     static void handleNopCommand_();
     static void handleInvalidCommand_();
+
+    static void startTransactionTimer_();
+    static unsigned long msElapsedSinceLastTransaction_();
     
 
     /*Data Members*/
@@ -31,6 +34,10 @@ private:
     static char outbuf_[256];
     static char cmd_;
     static std::vector<char> arg_;
+
+    //Note: The timer only works for timeouts that last shorter than 50 days
+    static unsigned long last_transaction_ms_;
+    static unsigned long interval_assume_eow_ms_;
 };
 
 #endif
-- 
GitLab