From b244ab45764b80018ef35ab259bbe2ed1982c357 Mon Sep 17 00:00:00 2001
From: Karol Hennessy <revkarol@gmail.com>
Date: Mon, 27 Apr 2020 19:35:02 +0200
Subject: [PATCH] functions for readback and cycle

---
 .../hev_prototype_v1/src/BreathingLoop.cpp    |  82 ++++++++----
 arduino/hev_prototype_v1/src/BreathingLoop.h  |  26 +++-
 arduino/hev_prototype_v1/src/UILoop.cpp       | 121 ++++++++++++++++-
 arduino/hev_prototype_v1/src/UILoop.h         |  22 +++-
 arduino/hev_prototype_v1/src/common.cpp       |  21 +++
 arduino/hev_prototype_v1/src/common.h         |  17 +--
 arduino/hev_prototype_v1/src/main.cpp         | 124 ++++--------------
 raspberry-dataserver/CommsDebug.py            |   3 +-
 8 files changed, 279 insertions(+), 137 deletions(-)

diff --git a/arduino/hev_prototype_v1/src/BreathingLoop.cpp b/arduino/hev_prototype_v1/src/BreathingLoop.cpp
index 05aa40eb..8e54d070 100644
--- a/arduino/hev_prototype_v1/src/BreathingLoop.cpp
+++ b/arduino/hev_prototype_v1/src/BreathingLoop.cpp
@@ -18,12 +18,21 @@ BreathingLoop::BreathingLoop()
     initCalib();
     resetReadingSums();
 
-    _total_cycle_duration = _states_durations.buff_loaded
+    _total_cycle_duration[0] = _states_durations.buff_loaded
                        +_states_durations.buff_pre_inhale
                        +_states_durations.inhale
                        +_states_durations.pause
                        +_states_durations.exhale_fill
                        +_states_durations.exhale;
+    _total_cycle_duration[2] = _total_cycle_duration[1] = _total_cycle_duration[0];
+
+    _valve_inhale_percent      = 0;   // replaced by a min level and a max level; bias inhale level.  very slightly open at "closed" position
+    _valve_exhale_percent      = 0;
+    _valve_air_in_enable       = 1;
+    _valve_o2_in_enable        = 1;
+    _valve_purge_enable        = 1;
+    _inhale_trigger_enable     = 0;   // params - associated val of peak flow
+    _exhale_trigger_enable     = 0;
 }
 
 BreathingLoop::~BreathingLoop()
@@ -69,30 +78,32 @@ void BreathingLoop::updateReadings()
         resetReadingSums();
     } else if (tnow - _readings_avgs_time > _readings_avgs_timeout) {
         _readings_avgs.timestamp                = static_cast<uint32_t>(_readings_sums.timestamp                / _readings_N);
-        _readings_avgs.pressure_air_supply      = static_cast<uint16_t>(_readings_sums.pressure_air_supply      / _readings_N);
-        _readings_avgs.pressure_air_regulated   = static_cast<uint16_t>(_readings_sums.pressure_air_regulated   / _readings_N);
-        _readings_avgs.pressure_buffer          = static_cast<uint16_t>(_readings_sums.pressure_buffer          / _readings_N);
-        _readings_avgs.pressure_inhale          = static_cast<uint16_t>(_readings_sums.pressure_inhale          / _readings_N);
-        _readings_avgs.pressure_patient         = static_cast<uint16_t>(_readings_sums.pressure_patient         / _readings_N);
-        _readings_avgs.temperature_buffer       = static_cast<uint16_t>(_readings_sums.temperature_buffer       / _readings_N);
+        _readings_avgs.pressure_air_supply      = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_air_supply      / _readings_N));
+        _readings_avgs.pressure_air_regulated   = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_air_regulated   / _readings_N));
+        _readings_avgs.pressure_buffer          = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_buffer          / _readings_N));
+        _readings_avgs.pressure_inhale          = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_inhale          / _readings_N));
+        _readings_avgs.pressure_patient         = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_patient         / _readings_N));
+        _readings_avgs.temperature_buffer       = adcToMillibar(static_cast<uint16_t>(_readings_sums.temperature_buffer       / _readings_N));
 #ifdef HEV_FULL_SYSTEM
-        _readings_avgs.pressure_o2_supply       = static_cast<uint16_t>(_readings_sums.pressure_o2_supply       / _readings_N);
-        _readings_avgs.pressure_o2_regulated    = static_cast<uint16_t>(_readings_sums.pressure_o2_regulated    / _readings_N);
-        _readings_avgs.pressure_diff_patient    = static_cast<uint16_t>(_readings_sums.pressure_diff_patient    / _readings_N);
+        _readings_avgs.pressure_o2_supply       = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_o2_supply       / _readings_N));
+        _readings_avgs.pressure_o2_regulated    = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_o2_regulated    / _readings_N));
+        _readings_avgs.pressure_diff_patient    = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_diff_patient    / _readings_N));
 #endif
         resetReadingSums();
     }
 }
 
+
 readings<uint16_t> BreathingLoop::getReadingAverages()
 {
     return _readings_avgs;
 
 }
 
-float BreathingLoop::getRespitoryRate(){
+float BreathingLoop::getRespiratoryRate(){
     // 60*1000ms / total time for a full cycle
-    return 60000.0/_total_cycle_duration;
+    float avg = (_total_cycle_duration[0]+_total_cycle_duration[1]+_total_cycle_duration[2])/3.0;
+    return 60000.0/avg;
 }
 
 float BreathingLoop::getFlow(){
@@ -333,12 +344,12 @@ void BreathingLoop::FSM_breathCycle()
             _valves_controller.setValves(VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, 0.9 * VALVE_STATE::OPEN, VALVE_STATE::CLOSED);
             _fsm_timeout = _states_durations.exhale;
             //update total cycle time
-            _total_cycle_duration = _states_durations.buff_loaded
+            updateTotalCycleDuration(_states_durations.buff_loaded
                        +_states_durations.buff_pre_inhale
                        +_states_durations.inhale
                        +_states_durations.pause
                        +_states_durations.exhale_fill
-                       +_states_durations.exhale;
+                       +_states_durations.exhale);
             break;
         case BL_STATES::BUFF_PURGE:
             _valves_controller.setValves(VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, 0.9 * VALVE_STATE::OPEN, VALVE_STATE::OPEN);
@@ -383,8 +394,16 @@ void BreathingLoop::calibrate()
     uint32_t tnow = static_cast<uint32_t>(millis());
     if (tnow - _calib_time > _calib_timeout) {
         _calib_N++;
-        _calib_sum_pressure += static_cast<uint32_t>(analogRead(pin_pressure_air_regulated));
-        _calib_avg_pressure  = static_cast<float   >(_calib_sum_pressure / _calib_N);
+        _calib_sums.pressure_air_regulated += static_cast<uint32_t>(analogRead(pin_pressure_air_regulated));
+        _calib_avgs.pressure_air_regulated  = static_cast<float   >(_calib_sums.pressure_air_regulated/ _calib_N);
+        _calib_sums.pressure_o2_regulated += static_cast<uint32_t>(analogRead(pin_pressure_o2_regulated));
+        _calib_avgs.pressure_o2_regulated  = static_cast<float   >(_calib_sums.pressure_o2_regulated/ _calib_N);
+        _calib_sums.pressure_buffer += static_cast<uint32_t>(analogRead(pin_pressure_buffer));
+        _calib_avgs.pressure_buffer  = static_cast<float   >(_calib_sums.pressure_buffer/ _calib_N);
+        _calib_sums.pressure_inhale += static_cast<uint32_t>(analogRead(pin_pressure_inhale));
+        _calib_avgs.pressure_inhale  = static_cast<float   >(_calib_sums.pressure_inhale/ _calib_N);
+        _calib_sums.pressure_patient += static_cast<uint32_t>(analogRead(pin_pressure_patient));
+        _calib_avgs.pressure_patient = static_cast<float   >(_calib_sums.pressure_patient/ _calib_N);
     }
 }
 
@@ -393,15 +412,19 @@ void BreathingLoop::initCalib()
 {
     _calib_timeout = 10;
     _calib_time = static_cast<uint32_t>(millis());
-    _calib_sum_pressure = 0;
-    _calib_avg_pressure = 0;
+    _calib_sums.pressure_air_regulated = 0;
+    _calib_sums.pressure_o2_regulated  = 0;
+    _calib_sums.pressure_buffer = 0;
+    _calib_sums.pressure_inhale = 0;
+    _calib_sums.pressure_patient = 0;
+    _calib_avgs.pressure_air_regulated = 0;
+    _calib_avgs.pressure_o2_regulated  = 0;
+    _calib_avgs.pressure_buffer = 0;
+    _calib_avgs.pressure_inhale = 0;
+    _calib_avgs.pressure_patient = 0;
     _calib_N = 0;
 }
 
-float BreathingLoop::getCalibrationOffset()
-{
-    return _calib_avg_pressure;
-}
 
 states_durations &BreathingLoop::getDurations() {
     return _states_durations;
@@ -416,3 +439,18 @@ ValvesController* BreathingLoop::getValvesController()
 {
     return &_valves_controller;
 }
+
+uint8_t BreathingLoop::getValveInhalePercent(){return _valve_inhale_percent;}
+uint8_t BreathingLoop::getValveExhalePercent(){return _valve_exhale_percent;}
+uint8_t BreathingLoop::valveAirInEnabled(){return _valve_air_in_enable;}
+uint8_t BreathingLoop::valveO2InEnabled(){return _valve_o2_in_enable;}
+uint8_t BreathingLoop::valvePurgeEnabled(){return _valve_purge_enable;}
+uint8_t BreathingLoop::inhaleTriggerEnabled(){return _inhale_trigger_enable;}
+uint8_t BreathingLoop::exhaleTriggerEnabled(){return _exhale_trigger_enable;}
+
+void BreathingLoop::updateTotalCycleDuration(uint16_t newtotal)
+{
+    _total_cycle_duration[0] = _total_cycle_duration[1];
+    _total_cycle_duration[1] = _total_cycle_duration[2];
+    _total_cycle_duration[2] = newtotal;
+}
\ No newline at end of file
diff --git a/arduino/hev_prototype_v1/src/BreathingLoop.h b/arduino/hev_prototype_v1/src/BreathingLoop.h
index e2f2eb08..aec23130 100644
--- a/arduino/hev_prototype_v1/src/BreathingLoop.h
+++ b/arduino/hev_prototype_v1/src/BreathingLoop.h
@@ -26,11 +26,18 @@ public:
     bool getRunning();
     void updateReadings();
     readings<uint16_t> getReadingAverages();
-    float getRespitoryRate();
+    float getRespiratoryRate();
     float getFlow();
     float getIERatio();
     float getMinuteVolume();
     ValvesController * getValvesController();
+    uint8_t getValveInhalePercent();
+    uint8_t getValveExhalePercent();
+    uint8_t valveAirInEnabled();
+    uint8_t valveO2InEnabled();
+    uint8_t valvePurgeEnabled();
+    uint8_t inhaleTriggerEnabled();
+    uint8_t exhaleTriggerEnabled();
 
     states_durations &getDurations();
 
@@ -74,12 +81,11 @@ private:
     // calibration
     void calibrate();
     void initCalib();
-    float getCalibrationOffset();
     uint32_t _calib_N;
     uint32_t _calib_time;
     uint32_t _calib_timeout;
-    uint32_t _calib_sum_pressure; // 32 bit due to possible analog read overflow
-    float _calib_avg_pressure;
+    readings<uint32_t> _calib_sums;
+    readings<uint16_t> _calib_avgs;
 
     // timeouts
     uint32_t calculateTimeoutExhale();
@@ -95,9 +101,17 @@ private:
     uint32_t _readings_timeout;
     uint32_t _readings_avgs_time;
     uint32_t _readings_avgs_timeout;
-
+ 
+    uint8_t _valve_inhale_percent  ;   // replaced by a min level and a max level; bias inhale level.  very slightly open at "closed" position
+    uint8_t _valve_exhale_percent  ;
+    uint8_t _valve_air_in_enable   ;
+    uint8_t _valve_o2_in_enable    ;
+    uint8_t _valve_purge_enable    ;
+    uint8_t _inhale_trigger_enable ;   // params - associated val of peak flow
+    uint8_t _exhale_trigger_enable ;
     // calculations
-    uint16_t _total_cycle_duration;
+    void updateTotalCycleDuration(uint16_t newtotal);
+    uint16_t _total_cycle_duration[3];
 };
 
 
diff --git a/arduino/hev_prototype_v1/src/UILoop.cpp b/arduino/hev_prototype_v1/src/UILoop.cpp
index 9f0f6cb8..218d9582 100644
--- a/arduino/hev_prototype_v1/src/UILoop.cpp
+++ b/arduino/hev_prototype_v1/src/UILoop.cpp
@@ -1,15 +1,134 @@
 #include "UILoop.h"
 // #include "BreathingLoop.h"
 
-UILoop::UILoop(BreathingLoop *bl, AlarmLoop *al)
+UILoop::UILoop(BreathingLoop *bl, AlarmLoop *al, CommsControl *comms)
 {
     _breathing_loop = bl;
     _alarm_loop     = al;
+    _comms          = comms;
+    uint32_t tnow = static_cast<uint32_t>(millis());
+    _fast_report_time = tnow;
+    _readback_report_time = tnow;
+    _cycle_report_time = tnow;
+
+    _fast_report_timeout = 50;  //ms
+    _readback_report_timeout = 300; 
+    _cycle_report_timeout = 500;  // this should probably be based on fsm state
 }
 
 UILoop::~UILoop()
 {;}
 
+void UILoop::receiveCommands()
+{
+
+    // check any received payload
+    if(_comms->readPayload(_plReceive)) {
+
+      if (_plReceive.getType() == PAYLOAD_TYPE::CMD) {
+          // apply received cmd to ui loop
+          cmd_format cmd;
+          _plReceive.getPayload(reinterpret_cast<void*>(&cmd));
+          doCommand(cmd);
+      }
+
+      // unset received type not to read it again
+      _plReceive.setType(PAYLOAD_TYPE::UNSET);
+    }
+}
+
+void UILoop::reportFastReadings()
+{
+    uint32_t tnow = static_cast<uint32_t>(millis());
+    if (tnow - _fast_report_time > _fast_report_timeout)
+    {
+
+        readings<uint16_t> readings_avgs = _breathing_loop->getReadingAverages();
+        _fast_data.timestamp = static_cast<uint32_t>(readings_avgs.timestamp);
+        _fast_data.fsm_state = _breathing_loop->getFsmState();
+        _fast_data.pressure_air_supply = readings_avgs.pressure_air_supply;
+        _fast_data.pressure_air_regulated = readings_avgs.pressure_air_regulated;
+        _fast_data.pressure_buffer = readings_avgs.pressure_buffer;
+        _fast_data.pressure_inhale = readings_avgs.pressure_inhale;
+        _fast_data.pressure_patient = readings_avgs.pressure_patient;
+        _fast_data.temperature_buffer = readings_avgs.temperature_buffer;
+        _fast_data.pressure_o2_supply = readings_avgs.pressure_o2_supply;
+        _fast_data.pressure_o2_regulated = readings_avgs.pressure_o2_regulated;
+        _fast_data.pressure_diff_patient = readings_avgs.pressure_diff_patient;
+
+        _plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_fast_data), sizeof(_fast_data));
+        _comms->writePayload(_plSend);
+        _fast_report_time = tnow;
+    }
+}
+
+void UILoop::reportReadbackValues()
+{
+
+    uint32_t tnow = static_cast<uint32_t>(millis());
+    if (tnow - _readback_report_time > _readback_report_timeout)
+    {
+        bool vin_air, vin_o2, vpurge;
+        float vinhale, vexhale;
+        ValvesController *valves_controller = _breathing_loop->getValvesController();
+        valves_controller->getValves(vin_air, vin_o2, vinhale, vexhale, vpurge);
+
+        _readback_data.timestamp = static_cast<uint32_t>(tnow);
+        states_durations durations = _breathing_loop->getDurations();
+        _readback_data.duration_calibration = durations.calibration;
+        _readback_data.duration_buff_purge  = durations.buff_purge;
+        _readback_data.duration_buff_flush  = durations.buff_flush;
+        _readback_data.duration_buff_prefill  = durations.buff_prefill;
+        _readback_data.duration_buff_fill  = durations.buff_fill;
+        _readback_data.duration_buff_loaded  = durations.buff_loaded;
+        _readback_data.duration_buff_pre_inhale  = durations.buff_pre_inhale;
+        _readback_data.duration_inhale  = durations.inhale;
+        _readback_data.duration_pause  = durations.pause;
+        _readback_data.duration_exhale_fill  = durations.exhale_fill;
+        _readback_data.duration_exhale  = durations.exhale;
+
+        _readback_data.valve_air_in = vin_air;
+        _readback_data.valve_o2_in = vin_o2;
+        _readback_data.valve_inhale = vinhale;
+        _readback_data.valve_exhale = vexhale;
+        _readback_data.valve_purge = vpurge;
+
+        _readback_data.ventilation_mode = _breathing_loop->getVentilationMode();
+
+        _readback_data.valve_inhale_percent = 0;  //TODO
+        _readback_data.valve_exhale_percent = 0;  //TODO
+        _readback_data.valve_inhale_percent = _breathing_loop->getValveInhalePercent();
+        _readback_data.valve_exhale_percent = _breathing_loop->getValveInhalePercent();
+        _readback_data.valve_air_in_enable  = _breathing_loop->valveAirInEnabled();
+        _readback_data.valve_o2_in_enable  = _breathing_loop->valveO2InEnabled();
+        _readback_data.valve_purge_enable  = _breathing_loop->valvePurgeEnabled();
+        _readback_data.inhale_trigger_enable = _breathing_loop->inhaleTriggerEnabled();
+        _readback_data.exhale_trigger_enable = _breathing_loop->exhaleTriggerEnabled();
+        // _readback_data.peep = _breathing_loop->peep();
+        _readback_data.inhale_exhale_ratio = _breathing_loop->getIERatio();
+
+        _plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_readback_data), sizeof(_readback_data));
+        _comms->writePayload(_plSend);
+        _readback_report_time = tnow;
+    }
+}
+
+void UILoop::reportCycleReadings()
+{
+    uint32_t tnow = static_cast<uint32_t>(millis());
+    if (tnow - _cycle_report_time > _cycle_report_timeout)
+    {
+
+        _cycle_data.timestamp =  tnow;
+
+        _plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_cycle_data), sizeof(_cycle_data));
+        _comms->writePayload(_plSend);
+        _cycle_report_time = tnow;
+    }
+
+}
+
+
 int UILoop::doCommand(cmd_format &cf)
 {
     switch(cf.cmd_type) {
diff --git a/arduino/hev_prototype_v1/src/UILoop.h b/arduino/hev_prototype_v1/src/UILoop.h
index b25fb31f..a0ad9cd0 100644
--- a/arduino/hev_prototype_v1/src/UILoop.h
+++ b/arduino/hev_prototype_v1/src/UILoop.h
@@ -3,6 +3,7 @@
 
 #include <Arduino.h>
 #include "CommsFormat.h"
+#include "CommsControl.h"
 #include "BreathingLoop.h"
 #include "AlarmLoop.h"
 #include "common.h"
@@ -11,9 +12,14 @@ class UILoop
 {
 
 public:
-    UILoop(BreathingLoop *bl, AlarmLoop *al);
+    UILoop(BreathingLoop *bl, AlarmLoop *al, CommsControl *comms);
     ~UILoop();
     int doCommand(cmd_format &cf);
+    void reportFastReadings();
+    void reportReadbackValues();
+    void reportCycleReadings();
+    void receiveCommands();
+
 private:
     void cmdGeneral(cmd_format &cf);
     void cmdSetDuration(cmd_format &cf);
@@ -21,8 +27,22 @@ private:
     void cmdSetThresholdMin(cmd_format &cf);
     void cmdSetThresholdMax(cmd_format &cf);
 
+
     BreathingLoop *_breathing_loop;
     AlarmLoop     *_alarm_loop    ;
+    CommsControl  *_comms         ;
+
+    Payload _plReceive;
+    Payload _plSend;
+    uint32_t _fast_report_time;
+    uint32_t _readback_report_time;
+    uint32_t _cycle_report_time;
+    uint16_t _fast_report_timeout;
+    uint16_t _readback_report_timeout;
+    uint16_t _cycle_report_timeout;
+    fast_data_format _fast_data;
+    readback_data_format _readback_data;
+    cycle_data_format _cycle_data;
 };
 
 #endif
diff --git a/arduino/hev_prototype_v1/src/common.cpp b/arduino/hev_prototype_v1/src/common.cpp
index bd03dc54..3cad8162 100644
--- a/arduino/hev_prototype_v1/src/common.cpp
+++ b/arduino/hev_prototype_v1/src/common.cpp
@@ -122,3 +122,24 @@ void setDuration(CMD_SET_DURATION cmd, states_durations &durations, uint32_t &va
             break;
     }
 }
+
+uint16_t adcToMillibar(uint16_t adc, uint16_t offset = 0)
+{
+    // TODO -  a proper calibration
+    // rough guess - ADP5111 spec sheet -Panasonic ADP5 pressure sensor
+    // range is 0.5 to 4.5V ==  100 kPA range == 1000 mbar ; but - voltage divide by 2 on PCB
+    // 12 bit ADC => range = 0-4095
+    float bits_per_millivolt = 3300/4096.0;
+    float max_p = 1000; //mbar
+    float min_p = 0;
+    float max_adc = 0.5 * 4500 * bits_per_millivolt;
+    float min_adc = 0.5 * 500 * bits_per_millivolt;
+    float m = (max_p - min_p) / (max_adc - min_adc );
+    float c = max_p - m * max_adc;
+    float mbar = m*(adc-offset) + c; 
+
+    //if (mbar < 0) return 0;
+    //else if (mbar > 1000 ) return 1000;
+
+    return static_cast<uint16_t>(mbar);
+} 
\ No newline at end of file
diff --git a/arduino/hev_prototype_v1/src/common.h b/arduino/hev_prototype_v1/src/common.h
index 49aeabfd..d3e82014 100644
--- a/arduino/hev_prototype_v1/src/common.h
+++ b/arduino/hev_prototype_v1/src/common.h
@@ -137,7 +137,7 @@ struct fast_data_format {
     uint8_t  version                = HEV_FORMAT_VERSION;
     uint32_t timestamp              = 0;
     uint8_t  data_type              = DATA_TYPE::FAST;
-    uint8_t  fsm_state              = 0;
+    uint8_t  fsm_state              = 0; //UNKNOWN
     uint16_t pressure_air_supply    = 0;
     uint16_t pressure_air_regulated = 0;
     uint16_t pressure_o2_supply     = 0;
@@ -180,15 +180,15 @@ struct readback_data_format {
     uint8_t  valve_purge              = 0;
     uint8_t  ventilation_mode         = 0;
 
-    uint8_t valve_inhale_percent      = 0;
+    uint8_t valve_inhale_percent      = 0;   // replaced by a min level and a max level; bias inhale level.  very slightly open at "closed" position
     uint8_t valve_exhale_percent      = 0;
     uint8_t valve_air_in_enable       = 0;
     uint8_t valve_o2_in_enable        = 0;
     uint8_t valve_purge_enable        = 0;
-    uint8_t inhale_trigger_enable     = 0;
+    uint8_t inhale_trigger_enable     = 0;   // params - associated val of peak flow
     uint8_t exhale_trigger_enable     = 0;
     uint8_t peep                      = 0;
-    float   inhale_exhate_ratio       = 0.0;
+    float   inhale_exhale_ratio       = 0.0;
 };
 #pragma pack()
 
@@ -212,12 +212,12 @@ struct cycle_data_format {
     float lung_compliance               = 0;
     float static_compliance             = 0;
 
-    uint16_t inhalation_pressure        = 0;
-    uint16_t peak_inspiratory_pressure  = 0;
-    uint16_t plateau_pressure           = 0;
+    uint16_t inhalation_pressure        = 0;  // mean airway pressure
+    uint16_t peak_inspiratory_pressure  = 0;  
+    uint16_t plateau_pressure           = 0;  
     uint16_t mean_airway_pressure       = 0;
 
-    uint8_t  fi02_percent               = 0;
+    uint8_t  fi02_percent               = 0;  // device from Aurelio
 
     uint16_t apnea_index                = 0;
     uint16_t apnea_time                 = 0;
@@ -281,6 +281,7 @@ struct alarm_thresholds {
 
 void setThreshold(ALARM_CODES alarm, alarm_thresholds &thresholds, uint32_t &value);
 void setDuration(CMD_SET_DURATION cmd, states_durations &timeouts, uint32_t &value);
+uint16_t adcToMillibar(uint16_t adc, uint16_t offset = 0);
 
 // used for calculating averages, template due to different size for sums and averages
 template <typename T> struct readings{
diff --git a/arduino/hev_prototype_v1/src/main.cpp b/arduino/hev_prototype_v1/src/main.cpp
index 45e6f63a..d9dd0633 100644
--- a/arduino/hev_prototype_v1/src/main.cpp
+++ b/arduino/hev_prototype_v1/src/main.cpp
@@ -19,49 +19,16 @@ uint8_t prev_state = LOW;
 uint32_t report_timeout = 50; //ms
 uint32_t report_time = 0;
 
-// float working_pressure = 1;             //?
-// float inspiratory_minute_volume = 6000; // ml/min
-// float respiratory_rate = 15;            //  10-40 +-1 ;aka breaths_per_min
-// float inspiratory_pressure = 10;        // 10-80 cmH2O +-1
-// //float tidal_volume = 200; // calc 200-1500ml +- 100
-// float inspiratory_time = 1.0; // 0.4-1.5s +-0.1
-// float pause_time = 1.0;       // range?
-// //float expiratory_time ; // calc
-// float expiratory_minute_volume; // calc?? same as inspiratory_minute_volume?
-// float trigger_sensitivity;
 
 // comms
-fast_data_format data;
-// fast_data_format data2;
+// fast_data_format data;
 CommsControl comms;
-Payload plReceive;
-Payload plSend;
 
 // loops
 BreathingLoop breathing_loop;
 AlarmLoop     alarm_loop;
-UILoop        ui_loop(&breathing_loop, &alarm_loop);
+UILoop        ui_loop(&breathing_loop, &alarm_loop, &comms);
 
-// bool start_fsm = false;
-
-// // calculations
-// float calcTidalVolume()
-// {
-//     return inspiratory_minute_volume / respiratory_rate;
-// }
-
-// float calcExpirationTime()
-// {
-//     float total_respiratory_time = 60.0 / respiratory_rate;
-//     // total = expire + inspire + pause
-//     return (total_respiratory_time - inspiratory_time - pause_time);
-// }
-
-// float calcExpiratoryMinuteVolume()
-// {
-//     // probably need to calculate this from readings
-//     return 0;
-// }
 
 void setup()
 {
@@ -115,79 +82,40 @@ void loop()
     // buzzer
     // tone(pin, freq (Hz), duration);
 
-    // data2.fsm_state              = 2;
-    // data2.dummy                  = 0x0e0e;
-    // data2.timestamp              = 0x01010101;
-    // data2.pressure_air_supply    = 0x0303;
-    // data2.pressure_air_regulated = 0x0404;
-    // data2.pressure_o2_supply     = 0x0505;
-    // data2.pressure_o2_regulated  = 0x0606;
-    // data2.pressure_buffer        = 0x0707;
-    // data2.pressure_inhale        = 0x0808;
-    // data2.pressure_patient       = 0x0909;
-    // data2.temperature_buffer     = 0x0a0a;
-    // data2.pressure_diff_patient  = 0x0b0b;
-    // data2.readback_valve_air_in  = 0xc;
-    // data2.readback_valve_o2_in   =0xd ;
-    // data2.readback_valve_inhale  =0xe ;
-    // data2.readback_valve_exhale  =0xf ;
-    // data2.readback_valve_purge   = 0x10;
-    // data2.ventilation_mode          =0x11;
-
-    bool vin_air, vin_o2, vpurge ;
-    float vinhale, vexhale;
-    ValvesController *valves_controller = breathing_loop.getValvesController();
-    valves_controller->getValves(vin_air, vin_o2, vinhale, vexhale, vpurge);
-    // data.readback_valve_air_in  = vin_air;
-    // data.readback_valve_o2_in   = vin_o2;
-    // data.readback_valve_inhale  = vinhale;
-    // data.readback_valve_exhale  = vexhale;
-    // data.readback_valve_purge   = vpurge;
-
-    readings<uint16_t> readings_avgs = breathing_loop.getReadingAverages();
-    data.timestamp              = static_cast<uint32_t>(readings_avgs.timestamp);
-    data.pressure_air_supply    = readings_avgs.pressure_air_supply;
-    data.pressure_air_regulated = readings_avgs.pressure_air_regulated;
-    data.pressure_buffer        = readings_avgs.pressure_buffer;
-    data.pressure_inhale        = readings_avgs.pressure_inhale;
-    data.pressure_patient       = readings_avgs.pressure_patient;
-    data.temperature_buffer     = readings_avgs.temperature_buffer;
-    data.pressure_o2_supply     = readings_avgs.pressure_o2_supply;
-    data.pressure_o2_regulated  = readings_avgs.pressure_o2_regulated;
-    data.pressure_diff_patient  = readings_avgs.pressure_diff_patient;
-
-    data.fsm_state              = breathing_loop.getFsmState();
+    // bool vin_air, vin_o2, vpurge ;
+    // float vinhale, vexhale;
+    // ValvesController *valves_controller = breathing_loop.getValvesController();
+    // valves_controller->getValves(vin_air, vin_o2, vinhale, vexhale, vpurge);
+
+    // readings<uint16_t> readings_avgs = breathing_loop.getReadingAverages();
+    // data.timestamp              = static_cast<uint32_t>(readings_avgs.timestamp);
+    // data.pressure_air_supply    = readings_avgs.pressure_air_supply;
+    // data.pressure_air_regulated = readings_avgs.pressure_air_regulated;
+    // data.pressure_buffer        = readings_avgs.pressure_buffer;
+    // data.pressure_inhale        = readings_avgs.pressure_inhale;
+    // data.pressure_patient       = readings_avgs.pressure_patient;
+    // data.temperature_buffer     = readings_avgs.temperature_buffer;
+    // data.pressure_o2_supply     = readings_avgs.pressure_o2_supply;
+    // data.pressure_o2_regulated  = readings_avgs.pressure_o2_regulated;
+    // data.pressure_diff_patient  = readings_avgs.pressure_diff_patient;
+
+    // data.fsm_state              = breathing_loop.getFsmState();
     // data.ventilation_mode          = breathing_loop.getVentilationMode();
 
     breathing_loop.FSM_assignment();
     breathing_loop.FSM_breathCycle();
 
-    uint32_t tnow = static_cast<uint32_t>(millis());
-    if(tnow - report_time > report_timeout) {
-        plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&data), sizeof(data));
-        // data2.ventilation_mode = plSend.getSize();
-        comms.writePayload(plSend);
-        report_time = tnow;
-    }
+    ui_loop.reportFastReadings();
+    // ui_loop.reportReadbackValues();
+    // ui_loop.reportCycleReadings();
+
     // per cycle sender
     comms.sender();
     // per cycle receiver
     comms.receiver();
 
-    // check any received payload
-    if(comms.readPayload(plReceive)) {
-
-      if (plReceive.getType() == PAYLOAD_TYPE::CMD) {
-          // apply received cmd to ui loop
-          cmd_format cmd;
-          plReceive.getPayload(reinterpret_cast<void*>(&cmd));
-          ui_loop.doCommand(cmd);
-      }
-
-      // unset received type not to read it again
-      plReceive.setType(PAYLOAD_TYPE::UNSET);
-    }
-
+    // // check any received payload
+    ui_loop.receiveCommands();
     // run value readings
     breathing_loop.updateReadings();
 }
diff --git a/raspberry-dataserver/CommsDebug.py b/raspberry-dataserver/CommsDebug.py
index 3c85f297..1070b46c 100755
--- a/raspberry-dataserver/CommsDebug.py
+++ b/raspberry-dataserver/CommsDebug.py
@@ -16,8 +16,9 @@ class Dependant(object):
         self._lli.bind_to(self.update_llipacket)
 
     def update_llipacket(self, payload):
-        # logging.info(f"payload received: {payload}")
+        #logging.info(f"payload received: {payload}")
         logging.info(f"payload received: {payload.fsm_state}")
+        #logging.info(f"payload received: {payload.timestamp}")
         #logging.info(f"payload received: {payload.readback_valve_o2_in} {payload.readback_valve_inhale} {payload.readback_valve_exhale} {payload.readback_valve_purge} {payload.fsm_state}")
         self._llipacket = payload.getDict() # returns a dict
         # pop from queue - protects against Dependant going down and not receiving packets
-- 
GitLab