From ed26dba4711a41e83db09862bee54ee9968694f7 Mon Sep 17 00:00:00 2001 From: Your Name <you@example.com> Date: Fri, 8 May 2020 09:21:19 +0200 Subject: [PATCH] Minimum 8mm valve current 0.53 duty cycle, proportional 0.01, Integrap 4E-4, inhale valve closed during calibration, PID target pressure rise up in steps --- .../hev_prototype_v1/src/BreathingLoop.cpp | 32 +++++++++++++------ arduino/hev_prototype_v1/src/BreathingLoop.h | 6 ++-- .../hev_prototype_v1/src/ValvesController.cpp | 2 +- arduino/hev_prototype_v1/src/common.h | 2 +- raspberry-dataserver/CommsDebug.py | 12 +++---- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/arduino/hev_prototype_v1/src/BreathingLoop.cpp b/arduino/hev_prototype_v1/src/BreathingLoop.cpp index 42fa3e0e..4725cfd5 100644 --- a/arduino/hev_prototype_v1/src/BreathingLoop.cpp +++ b/arduino/hev_prototype_v1/src/BreathingLoop.cpp @@ -35,7 +35,8 @@ BreathingLoop::BreathingLoop() _pid.Ki = 0.000007; // integral factor _pid.Kd = 0; // derivative factor - _pid_integral = 0.; + _pid_integral = 0.; + _pid_set_point = 0.; } BreathingLoop::~BreathingLoop() @@ -96,14 +97,14 @@ void BreathingLoop::updateReadings() float_t _pressure_inhale = adcToMillibarFloat((_readings_sums.pressure_inhale / _readings_N), _calib_avgs.pressure_inhale ); - doPID(10., _pressure_inhale, _valve_inhale_PID_percentage, _airway_pressure, _volume, _flow); + doPID(5, 25., _pressure_inhale, _valve_inhale_PID_percentage, _airway_pressure, _volume, _flow); //_volume = _valve_inhale_PID_percentage; //_valve_inhale_PID_percentage /= 10.; // In the Labview code the output was defined from 0-10V. It is a simple rescale to keep the same parameters //Lazy approach //airway_pressure = Proportional //volume = Integral - //flow = Derivative + _flow = _valve_inhale_PID_percentage; _valves_controller.setPIDoutput(_valve_inhale_PID_percentage); _valves_controller.setValves(VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::PID, VALVE_STATE::CLOSED, VALVE_STATE::CLOSED); @@ -348,7 +349,7 @@ void BreathingLoop::FSM_breathCycle() initCalib(); break; case BL_STATES::CALIBRATION : - _valves_controller.setValves(VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::CALIB_OPEN, VALVE_STATE::CALIB_OPEN, VALVE_STATE::OPEN); + _valves_controller.setValves(VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::CLOSED, VALVE_STATE::CALIB_OPEN, VALVE_STATE::OPEN); calibrate(); _fsm_timeout = _states_durations.calibration; break; @@ -393,7 +394,8 @@ void BreathingLoop::FSM_breathCycle() _fsm_timeout = _states_durations.buff_pre_inhale; } - _pid_integral = 0.;//Resets the integral of the Inhale Valve PID before the inhale cycle starts + _pid_integral = 0.;//Resets the integral of the Inhale Valve PID before the inhale cycle starts + _pid_set_point = 0.;//Resets the integral of the Inhale Valve PID before the inhale cycle starts break; case BL_STATES::INHALE: @@ -559,19 +561,29 @@ float BreathingLoop::getAirwayPressure(){ return _airway_pressure; } -void BreathingLoop::doPID(float target_pressure, float process_pressure, float &output, float &proportional, float &integral, float &derivative){ +void BreathingLoop::doPID(int nsteps, float target_pressure, float process_pressure, float &output, float &proportional, float &integral, float &derivative){ - float error = target_pressure - process_pressure; + // Set PID profile using the set point + // nsteps defines the number of intermediate steps + + float _pid_set_point_step = target_pressure/nsteps; + + _pid_set_point += _pid_set_point_step; + + if(_pid_set_point > target_pressure) _pid_set_point = target_pressure; + + //Calculate the PID error based on the pid set point + float error = _pid_set_point - process_pressure; proportional = _pid.Kp*error; _pid_integral += _pid.Ki*error; integral = _pid_integral; - //TODO integral and derivative + //TODO derivative - float minimum_open_frac = 0.54; //Minimum opening to avoid vibrations on the valve control - float maximum_open_frac = 0.64; //Maximum opening for the PID control + float minimum_open_frac = 0.53; //Minimum opening to avoid vibrations on the valve control + float maximum_open_frac = 0.70; //Maximum opening for the PID control output = proportional + integral + minimum_open_frac; diff --git a/arduino/hev_prototype_v1/src/BreathingLoop.h b/arduino/hev_prototype_v1/src/BreathingLoop.h index 03a0e6a4..bae9ca23 100644 --- a/arduino/hev_prototype_v1/src/BreathingLoop.h +++ b/arduino/hev_prototype_v1/src/BreathingLoop.h @@ -93,7 +93,8 @@ private: // timeouts uint32_t calculateDurationExhale(); - states_durations _states_durations = {10000, 600, 600, 100, 600, 100, 100, 1000, 500, 600, 400}; + //durations = {calibration, buff_purge, buff_flush, buff_prefill, buff_fill, buff_loaded, buff_pre_inhale, inhale, pause, exhale_fill, exhale } + states_durations _states_durations = {10000, 600, 600, 100, 600, 100, 200, 1000, 200, 600, 400}; // readings void resetReadingSums(); @@ -117,7 +118,7 @@ private: float _airway_pressure; float _valve_inhale_PID_percentage;//from 0 to 1. - void doPID(float, float, float&, float&, float&, float&); + void doPID(int, float, float, float&, float&, float&, float&); // safety void safetyCheck(); @@ -126,6 +127,7 @@ private: // PID vars float _pid_integral; + float _pid_set_point; }; diff --git a/arduino/hev_prototype_v1/src/ValvesController.cpp b/arduino/hev_prototype_v1/src/ValvesController.cpp index f12eb5e0..77fae394 100644 --- a/arduino/hev_prototype_v1/src/ValvesController.cpp +++ b/arduino/hev_prototype_v1/src/ValvesController.cpp @@ -30,7 +30,7 @@ ValvesController::ValvesController() _inhale_duty_cycle = 0; _inhale_open_max = MAX_VALVE_FRAC_OPEN; - _inhale_open_min = 0.54; + _inhale_open_min = 0.53; _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; diff --git a/arduino/hev_prototype_v1/src/common.h b/arduino/hev_prototype_v1/src/common.h index 72dfcecd..e2597218 100644 --- a/arduino/hev_prototype_v1/src/common.h +++ b/arduino/hev_prototype_v1/src/common.h @@ -22,7 +22,7 @@ #define HEV_FORMAT_VERSION 0xA5 // -const float MAX_VALVE_FRAC_OPEN = 0.68; +const float MAX_VALVE_FRAC_OPEN = 0.70; const uint8_t MAX_PATIENT_PRESSURE = 40; //mbar // input params enum PAYLOAD_TYPE : uint8_t { diff --git a/raspberry-dataserver/CommsDebug.py b/raspberry-dataserver/CommsDebug.py index 1032b0cc..1ea61dba 100755 --- a/raspberry-dataserver/CommsDebug.py +++ b/raspberry-dataserver/CommsDebug.py @@ -33,8 +33,8 @@ class Dependant(object): def update_llipacket(self, payload): #logging.info(f"payload received: {payload}") if payload.getType() == 1: - # logging.info(f"payload received: {payload}") - logging.info(f"Fsm state: {payload.fsm_state} ") + logging.info(f"payload received: {payload}") + #logging.info(f"Fsm state: {payload.fsm_state} ") if payload.getType() == 7: logging.info(f" PID {payload.kp:3.6f} {payload.ki:3.6f} {payload.kd:3.6f}") #if hasattr(payload, 'ventilation_mode'): @@ -51,10 +51,10 @@ async def commsDebug(): #comms.writePayload(cmd) await asyncio.sleep(1) - cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KP.value, param=0.0033) # to set Kp=0.0002, param=200 i.e., micro_Kp + cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KP.value, param=0.01) # to set Kp=0.0002, param=200 i.e., micro_Kp comms.writePayload(cmd) await asyncio.sleep(1) - cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KI.value, param=0.0022) # to set Kp=0.0002, param=200 i.e., micro_Kp + cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KI.value, param=0.0004)#0002) # to set Kp=0.0002, param=200 i.e., micro_Kp comms.writePayload(cmd) await asyncio.sleep(1) cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KD.value, param=0.0011) # to set Kp=0.0002, param=200 i.e., micro_Kp @@ -66,11 +66,11 @@ async def commsDebug(): print('sent cmd start') toggle = 2 while True: - await asyncio.sleep(30) + await asyncio.sleep(10) #cmd = CommandFormat(cmd_type=CMD_TYPE.SET_PID.value, cmd_code=CMD_SET_PID.KP.value, param=5) # to set Kp=0.2, param=200 i.e., milli_Kp #comms.writePayload(cmd) #print('sent cmd set Kp = 0.2') - await asyncio.sleep(30) + await asyncio.sleep(10) cmd = CommandFormat(cmd_type=CMD_TYPE.GENERAL.value, cmd_code=toggle, param=0) if toggle == 2 : toggle = 1 -- GitLab