diff --git a/arduino/hev_prototype_v1/src/BreathingLoop.cpp b/arduino/hev_prototype_v1/src/BreathingLoop.cpp index 9172cea1e811872f71812aed0934ec1336a0dabb..3076f758e8025b2e62ef2411a7fd22160bcdd07d 100644 --- a/arduino/hev_prototype_v1/src/BreathingLoop.cpp +++ b/arduino/hev_prototype_v1/src/BreathingLoop.cpp @@ -77,29 +77,58 @@ void BreathingLoop::updateReadings() if (_readings_reset) { 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 = 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 = 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)); + _readings_avgs.timestamp = static_cast<uint32_t>(_readings_sums.timestamp); + _readings_avgs.pressure_air_supply = adcToMillibar((_readings_sums.pressure_air_supply / _readings_N), _calib_avgs.pressure_air_supply ); + _readings_avgs.pressure_air_regulated = adcToMillibar((_readings_sums.pressure_air_regulated / _readings_N), _calib_avgs.pressure_air_regulated); + _readings_avgs.pressure_buffer = adcToMillibar((_readings_sums.pressure_buffer / _readings_N), _calib_avgs.pressure_buffer ); + _readings_avgs.pressure_inhale = adcToMillibar((_readings_sums.pressure_inhale / _readings_N), _calib_avgs.pressure_inhale ); + _readings_avgs.pressure_patient = adcToMillibar((_readings_sums.pressure_patient / _readings_N), _calib_avgs.pressure_patient ); + _readings_avgs.temperature_buffer = adcToMillibar((_readings_sums.temperature_buffer / _readings_N), _calib_avgs.temperature_buffer ); +#ifdef HEV_FULL_SYSTEM + _readings_avgs.pressure_o2_supply = adcToMillibar((_readings_sums.pressure_o2_supply / _readings_N), _calib_avgs.pressure_o2_supply ); + _readings_avgs.pressure_o2_regulated = adcToMillibar((_readings_sums.pressure_o2_regulated / _readings_N), _calib_avgs.pressure_o2_regulated ); + _readings_avgs.pressure_diff_patient = adcToMillibar((_readings_sums.pressure_diff_patient / _readings_N), _calib_avgs.pressure_diff_patient ); #endif resetReadingSums(); } } +void BreathingLoop::updateRawReadings() +{ + // calc pressure every 1ms + // create averages every 10ms + uint32_t tnow = static_cast<uint32_t>(millis()); + + // to make sure the readings correspond only to the same fsm mode + if (tnow - _readings_avgs_time > _readings_avgs_timeout) { + _readings_raw.timestamp = static_cast<uint32_t>(_readings_sums.timestamp); + _readings_raw.pressure_air_supply =analogRead(pin_pressure_air_supply) ; + _readings_raw.pressure_air_regulated =analogRead(pin_pressure_air_regulated) ; + _readings_raw.pressure_buffer =analogRead(pin_pressure_buffer) ; + _readings_raw.pressure_inhale =analogRead(pin_pressure_inhale) ; + _readings_raw.pressure_patient =analogRead(pin_pressure_patient) ; + _readings_raw.temperature_buffer =analogRead(pin_temperature_buffer) ; +#ifdef HEV_FULL_SYSTEM + _readings_raw.pressure_o2_supply =analogRead(pin_pressure_o2_supply) ; + _readings_raw.pressure_o2_regulated =analogRead(pin_pressure_o2_regulated) ; + _readings_raw.pressure_diff_patient =analogRead(pin_pressure_diff_patient) ; +#endif + } +} -readings<uint16_t> BreathingLoop::getReadingAverages() + +readings<int16_t> BreathingLoop::getReadingAverages() { return _readings_avgs; } +readings<int16_t> BreathingLoop::getRawReadings() +{ + return _readings_raw; + +} + float BreathingLoop::getRespiratoryRate(){ // 60*1000ms / total time for a full cycle float avg = (_total_cycle_duration[0]+_total_cycle_duration[1]+_total_cycle_duration[2])/3.0; @@ -184,7 +213,7 @@ void BreathingLoop::FSM_assignment( ) { case BL_STATES::IDLE: if (_running == true) { // FSM_time = millis(); - next_state = BL_STATES::BUFF_PREFILL; + next_state = BL_STATES::CALIBRATION; } else { next_state = BL_STATES::IDLE; } @@ -397,9 +426,9 @@ bool BreathingLoop::getRunning() void BreathingLoop::calibrate() { - // get pressure_air_regulated over 10s calc mean + // get pressure_air_regulated over last sec of 10s calc mean uint32_t tnow = static_cast<uint32_t>(millis()); - if (tnow - _calib_time > _calib_timeout) { + if (tnow - _calib_time > _calib_timeout ) { _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); @@ -411,13 +440,18 @@ void BreathingLoop::calibrate() _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); + + _calib_time = tnow; + _calib_timeout = 10; } } void BreathingLoop::initCalib() -{ - _calib_timeout = 10; +{ // do calibration in last sec of calibration step (normally 10s) or default to 10ms + _calib_timeout = 10; + if (_states_durations.calibration - 1000 > 10) + _calib_timeout = _states_durations.calibration - 1000; _calib_time = static_cast<uint32_t>(millis()); _calib_sums.pressure_air_regulated = 0; _calib_sums.pressure_o2_regulated = 0; @@ -464,4 +498,4 @@ 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 c97cbbdbb4bd1dd9351cca57bbbf639fd1cd2f96..416869be760f71a49acbac1e59a2d31129203d33 100644 --- a/arduino/hev_prototype_v1/src/BreathingLoop.h +++ b/arduino/hev_prototype_v1/src/BreathingLoop.h @@ -25,7 +25,9 @@ public: void doReset(); bool getRunning(); void updateReadings(); - readings<uint16_t> getReadingAverages(); + void updateRawReadings(); + readings<int16_t> getReadingAverages(); + readings<int16_t> getRawReadings(); float getRespiratoryRate(); float getFlow(); float getIERatio(); @@ -84,8 +86,8 @@ private: uint32_t _calib_N; uint32_t _calib_time; uint32_t _calib_timeout; - readings<uint32_t> _calib_sums; - readings<uint16_t> _calib_avgs; + readings<int32_t> _calib_sums; + readings<int16_t> _calib_avgs; // timeouts uint32_t calculateDurationExhale(); @@ -93,8 +95,9 @@ private: // readings void resetReadingSums(); - readings<uint32_t> _readings_sums; // 32 bit due to possible analog read overflow - readings<uint16_t> _readings_avgs; + readings<int32_t> _readings_sums; // 32 bit due to possible analog read overflow + readings<int16_t> _readings_avgs; + readings<int16_t> _readings_raw; bool _readings_reset; uint32_t _readings_N; uint32_t _readings_time; diff --git a/arduino/hev_prototype_v1/src/UILoop.cpp b/arduino/hev_prototype_v1/src/UILoop.cpp index 218d9582dc7e11b0c4870d798b57a2b15d57fc14..6ff12f2120b8f91889b81be7af00f62410400f4a 100644 --- a/arduino/hev_prototype_v1/src/UILoop.cpp +++ b/arduino/hev_prototype_v1/src/UILoop.cpp @@ -43,18 +43,22 @@ void UILoop::reportFastReadings() 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); + // TO SWITCH BETWEEN RAW AND MILLIBAR DATA UNCOMMENT BELOW + readings<int16_t> readings = _breathing_loop->getReadingAverages(); + //readings<int16_t> readings = _breathing_loop->getRawReadings(); + + _fast_data.timestamp = static_cast<uint32_t>(readings.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; + + _fast_data.pressure_air_supply = readings.pressure_air_supply; + _fast_data.pressure_air_regulated = readings.pressure_air_regulated; + _fast_data.pressure_buffer = readings.pressure_buffer; + _fast_data.pressure_inhale = readings.pressure_inhale; + _fast_data.pressure_patient = readings.pressure_patient; + _fast_data.temperature_buffer = readings.temperature_buffer; + _fast_data.pressure_o2_supply = readings.pressure_o2_supply; + _fast_data.pressure_o2_regulated = readings.pressure_o2_regulated; + _fast_data.pressure_diff_patient = readings.pressure_diff_patient; _plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_fast_data), sizeof(_fast_data)); _comms->writePayload(_plSend); diff --git a/arduino/hev_prototype_v1/src/common.cpp b/arduino/hev_prototype_v1/src/common.cpp index 43180c397f7069f19020ad01c0903f5a6792c902..4fb15eae17307a7c1fd4ebcfc82207ac7fbaf972 100644 --- a/arduino/hev_prototype_v1/src/common.cpp +++ b/arduino/hev_prototype_v1/src/common.cpp @@ -123,25 +123,21 @@ void setDuration(CMD_SET_DURATION cmd, states_durations &durations, uint32_t &va } } -uint16_t adcToMillibar(uint16_t adc, uint16_t offset = 0) +int16_t adcToMillibar(int16_t adc, int16_t offset = 0) { // TODO - a proper calibration - // rough guess - ADP5111 spec sheet -Panasonic ADP5 pressure sensor + // rough guess - ADP51A11 spec sheet -Panasonic ADP5 pressure sensor // range is 0.5 to 4.5V == 40 kPA range == 400 mbar ; but - voltage divide by 2 on PCB // 12 bit ADC => range = 0-4095 float bits_per_millivolt = 3300/4096.0; float max_p = 400; //mbar float min_p = 0; - float max_adc = 0.5 * 4500 * bits_per_millivolt; - float min_adc = 0.5 * 500 * bits_per_millivolt; + float max_adc = 0.5 * 4500 / bits_per_millivolt; + float min_adc = 0; //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 ) mbar = 0; // hack FIXME - //if (mbar < 0) return 0; - //else if (mbar > 1000 ) return 1000; - - return static_cast<uint16_t>(mbar); - //return static_cast<uint16_t>(adc); -} \ No newline at end of file + return static_cast<int16_t>(mbar); + //return static_cast<int16_t>(adc); +} diff --git a/arduino/hev_prototype_v1/src/common.h b/arduino/hev_prototype_v1/src/common.h index a533973527339f43f4bb66927bed17ade2b854f6..37022d6f189094b89819db228fdf908b51e6a1b2 100644 --- a/arduino/hev_prototype_v1/src/common.h +++ b/arduino/hev_prototype_v1/src/common.h @@ -138,17 +138,17 @@ struct fast_data_format { uint32_t timestamp = 0; uint8_t data_type = DATA_TYPE::FAST; uint8_t fsm_state = 0; //UNKNOWN - uint16_t pressure_air_supply = 0; - uint16_t pressure_air_regulated = 0; - uint16_t pressure_o2_supply = 0; - uint16_t pressure_o2_regulated = 0; - uint16_t pressure_buffer = 0; - uint16_t pressure_inhale = 0; - uint16_t pressure_patient = 0; - uint16_t temperature_buffer = 0; - uint16_t pressure_diff_patient = 0; - uint16_t ambient_pressure = 0; - uint16_t ambient_temperature = 0; + int16_t pressure_air_supply = 0; + int16_t pressure_air_regulated = 0; + int16_t pressure_o2_supply = 0; + int16_t pressure_o2_regulated = 0; + int16_t pressure_buffer = 0; + int16_t pressure_inhale = 0; + int16_t pressure_patient = 0; + int16_t temperature_buffer = 0; + int16_t pressure_diff_patient = 0; + int16_t ambient_pressure = 0; + int16_t ambient_temperature = 0; float airway_pressure = 0; float flow = 0; float volume = 0; @@ -281,7 +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); +int16_t adcToMillibar(int16_t adc, int16_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 ed9112d8ac1ff0462a128f00037861dd88acbd7e..dd3ecafdf92c7ad3c407bf52c90ca08e27945063 100644 --- a/arduino/hev_prototype_v1/src/main.cpp +++ b/arduino/hev_prototype_v1/src/main.cpp @@ -37,6 +37,8 @@ void setup() btStop(); ledcSetup(pwm_chan_inhale, pwm_frequency, pwm_resolution); ledcSetup(pwm_chan_exhale, pwm_frequency, pwm_resolution); + ledcSetup(3, 2000, pwm_resolution); + ledcAttachPin(pin_buzzer, 3); ledcAttachPin(pin_valve_inhale , pwm_chan_inhale); ledcAttachPin(pin_valve_exhale , pwm_chan_exhale); pin_to_chan[pin_valve_inhale] = pwm_chan_inhale; @@ -73,41 +75,18 @@ void setup() pinMode(pin_buzzer, OUTPUT); pinMode(pin_button_0, INPUT); -// while (!Serial) ; comms.beginSerial(); } void loop() { - // buzzer - // tone(pin, freq (Hz), duration); - - // 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(); ui_loop.reportFastReadings(); - ui_loop.reportReadbackValues(); - ui_loop.reportCycleReadings(); +// ui_loop.reportReadbackValues(); +// ui_loop.reportCycleReadings(); // per cycle sender comms.sender(); @@ -118,4 +97,6 @@ void loop() ui_loop.receiveCommands(); // run value readings breathing_loop.updateReadings(); + breathing_loop.updateRawReadings(); + } diff --git a/raspberry-dataserver/CommsCommon.py b/raspberry-dataserver/CommsCommon.py index 05e8b82066163cbcf4eb41f7ca63d73187376744..3c10da74e84ffeca9481844ed8b6bdb409f37db3 100644 --- a/raspberry-dataserver/CommsCommon.py +++ b/raspberry-dataserver/CommsCommon.py @@ -189,7 +189,7 @@ class BaseFormat(): @dataclass class DataFormat(BaseFormat): # subclass dataformat - _dataStruct = Struct("<BIBBHHHHHHHHHHHfff") + _dataStruct = Struct("<BIBBhhhhhhhhhhhfff") _type = PAYLOAD_TYPE.DATA # subclass member variables diff --git a/raspberry-dataserver/CommsDebug.py b/raspberry-dataserver/CommsDebug.py index 790481023a53e2f2ef2b5e1a4eb004d2632b973c..89c31230fdc6da0b8141dced2884e03833efbd97 100755 --- a/raspberry-dataserver/CommsDebug.py +++ b/raspberry-dataserver/CommsDebug.py @@ -3,10 +3,23 @@ from CommsControl import CommsControl from CommsCommon import * import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +from serial.tools import list_ports import sys import time -comms = CommsControl(port = sys.argv[1]) +port_device = "" +for port in list_ports.comports(): + vidpid = "" + if port.pid != None and port.vid != None: + vidpid = f"{ port.vid:04x}:{port.pid:04x}".upper() + print(vidpid) + if port.manufacturer and "ARDUINO" in port.manufacturer.upper(): + port_device = port.device + elif vidpid == "10C4:EA60" : + port_device = port.device + elif len(sys.argv) > 1: + port_device = sys.argv[1] +comms = CommsControl(port = port_device) class Dependant(object):