Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -r5126b79e4970ffe2ed9db4cccea18a1216c78570 -rf6022e86136c821709ce24b61e11e8e2bdf0b11e --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 5126b79e4970ffe2ed9db4cccea18a1216c78570) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision f6022e86136c821709ce24b61e11e8e2bdf0b11e) @@ -41,7 +41,8 @@ // ********** private definitions ********** #define DIALYSATE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump data is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. -#define DP_CONTROL_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. +#define DP_CONTROL_INTERVAL_MS 1000 ///< Dialysate pump control interval in ms +#define DP_CONTROL_INTERVAL ( DP_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. #define DIALYSATE_PUMP_CONTROL_RUN 0x01 ///< Dialysate pump control run pump. #define DIALYSATE_PUMP_CONTROL_STOP 0x00 ///< Dialysate pump control stop pump. #define DIALYSATE_PUMP_FORWARD_DIR 1 ///< Dialysate pump forward direction. reverse direction is not allowed. @@ -59,20 +60,21 @@ #define MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< FPGA dialysate pump direction fault window #define MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_FAILURES 10 ///< FPGA dialysate pump direction fault failures per MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_WINDOW_MS -#define FRESH_DIALYSATE_TARGET_PRESSURE_PSI 25.0F ///< Fresh dialysate pump recommended pressure(D18) in psi. -#define FRESH_DIALYSATE_MAX_PRESSURE_PSI 26.0F ///< Fresh dialysate pump maximum allowed (D18) pressure in psi. -#define SPENT_DIALYSATE_TARGET_PRESSURE_PSI 29.0F ///< Spent dialysate pump recommended pressure(PDs) in psi. -#define SPENT_DIALYSATE_MAX_PRESSURE_PSI 30.0F ///< Spent dialysate pump maximum allowed (PDs) pressure in psi. +#define DEFAULT_FRESH_DIALYSATE_TARGET_PRESSURE_PSI -12.79F ///< Default degas pump(D18) target pressure (at zero sea level)in psi. +#define DEFAULT_SPENT_DIALYSATE_TARGET_PRESSURE_PSI 30.0F ///< Default spent dialysate pump target pressure(D48) in psi. #define FRESH_DIAL_OPEN_LOOP_SPEED_RPM 2000.0F ///< fresh dialysate pump open loop speed to meet target pressure. #define SPENT_DIAL_OPEN_LOOP_SPEED_RPM 2500.0F ///< spent dialysate pump open loop speed to meet target pressure. #define DIALYSATE_PUMP_SPEED_ZERO_RPM 0 ///< Dialysate pump zero RPM speed. #define SPEED_COUNT_ZERO 0 ///< Measured speed count zero check. #define SPEED_CONV_FACTOR 1500000 ///< Measured speed count conversion to RPM -#define D12_PUMP_P_COEFFICIENT 20.0F ///< P term for fresh dialysate pump delta pressure control. -#define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control. -#define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control. -#define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control. +#define D12_PUMP_P_COEFFICIENT 20.0F ///< P term for fresh dialysate pump delta pressure control. +#define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control. +#define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control. +#define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control. +#define DIAL_PUMP_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control +#define DEGAS_PUMP_SLOPE_FACTOR -0.0156F ///< Dialysate pump target pressure multiply factor ( m factor in 'y = mx + b' equation) +#define DEGAS_PUMP_INTERCEPT_FACTOR 0.1153F ///< Dialysate pump target pressure addition factor ( b factor in 'y = mx + b' equation) #define MAX_ALLOWED_RPM_OUT_OF_RANGE 300 ///< Maximum allowed RPM out of range from target RPM in open loop. #define PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD 20.0F ///< Speed change that alters the state to ramp during control state. @@ -116,6 +118,7 @@ U32 pumpID; ///< Pump ID Fresh(DGP) : 0, Spent ( SDP) : 1 U32 startStop; ///< Stop : 0, Start : 1 U32 rpm; ///< Speed range from 300 to 4500 RPM range + U32 pumpControl; ///< 1 : Open Loop control, 0 : Closed loop control } DIAL_PUMP_START_STOP_CMD_PAYLOAD_T; // ********** private data ********** @@ -132,6 +135,7 @@ static OVERRIDE_F32_T dialysatePumpMeasuredCurrentA[ NUM_OF_DIALYSATE_PUMPS ]; ///< Measured dialysate pump current feedback. static OVERRIDE_U32_T measuredDirection[ NUM_OF_DIALYSATE_PUMPS ]; ///< Measured dialysate pump direction. static OVERRIDE_F32_T pumpTargetPressure[ NUM_OF_DIALYSATE_PUMPS ]; ///< Target dialysate pumps' pressure (PSI). +static BOOL isDialPumpOpenLoopEnabled[ NUM_OF_DIALYSATE_PUMPS ]; ///< Flag to run in open loop control mode. static BOOL dialPumpsReadyToControl; ///< Flag use to indicate the minimum control interval is met for pump control //For testing @@ -149,6 +153,7 @@ static DIALYSATE_PUMP_STATE_T handleDialysatePumpRampToTargetState( DIALYSATE_PUMPS_T pumpId ); static DIALYSATE_PUMP_STATE_T handleDialysatePumpOffState( DIALYSATE_PUMPS_T pumpId ); static void monitorPumpDirectionErrorCount( DIALYSATE_PUMPS_T pumpId ); +static void calculateDegasPumpTargetPressure( void ); /*********************************************************************//** * @brief @@ -193,27 +198,28 @@ dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; dialysatePumps[ pumpId ].directionErrorCount = 0; dialysatePumps[ pumpId ].lastDirectionErrorCount = 0; + isDialPumpOpenLoopEnabled[ pumpId ] = FALSE; dialPumpsReadyToControl = FALSE; signalDialysatePumpHardStop( pumpId ); } - pumpTargetPressure[D12_PUMP].data = FRESH_DIALYSATE_TARGET_PRESSURE_PSI; - pumpTargetPressure[D12_PUMP].ovInitData = FRESH_DIALYSATE_TARGET_PRESSURE_PSI; + pumpTargetPressure[D12_PUMP].data = DEFAULT_FRESH_DIALYSATE_TARGET_PRESSURE_PSI; + pumpTargetPressure[D12_PUMP].ovInitData = DEFAULT_FRESH_DIALYSATE_TARGET_PRESSURE_PSI; pumpTargetPressure[D12_PUMP].ovData = 0.0F; pumpTargetPressure[D12_PUMP].override = OVERRIDE_RESET; - pumpTargetPressure[D48_PUMP].data = SPENT_DIALYSATE_TARGET_PRESSURE_PSI; - pumpTargetPressure[D48_PUMP].ovInitData = SPENT_DIALYSATE_TARGET_PRESSURE_PSI; + pumpTargetPressure[D48_PUMP].data = DEFAULT_SPENT_DIALYSATE_TARGET_PRESSURE_PSI; + pumpTargetPressure[D48_PUMP].ovInitData = DEFAULT_SPENT_DIALYSATE_TARGET_PRESSURE_PSI; pumpTargetPressure[D48_PUMP].ovData = 0.0F; pumpTargetPressure[D48_PUMP].override = OVERRIDE_RESET; // Initialize the fresh dialysate pump PI controller initializePIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, D12_PUMP_P_COEFFICIENT, D12_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM ); + MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); // Initialize spent dialysate pump PI controller initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, D48_PUMP_P_COEFFICIENT, D48_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM ); + MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM,FALSE, DIAL_PUMP_NO_FEED_FORWARD ); // Init the dialysate pump with valid PWM while motor is disabled. // when enable triggers, we dont want invlid RPM set that triggers alarm in motor controller. @@ -246,16 +252,34 @@ /*********************************************************************//** * @brief + * The calculateDegasPumpTargetPressure function gets the barometric pressure + * sensor reading to calcualte degassing pump(D12) target control pressure for closed + * loop control. + * @details \b Inputs: none + * @details \b Outputs: pumpTargetSpeed. + * @return none + *************************************************************************/ +static void calculateDegasPumpTargetPressure( void ) +{ + F32 pressureInmmHg = getFilteredPressure( BARO_PRES ); + + //Get the degassing target pressure + pumpTargetPressure[D12_PUMP].data = ( ( DEGAS_PUMP_SLOPE_FACTOR * pressureInmmHg ) + DEGAS_PUMP_INTERCEPT_FACTOR ) + DEGAS_PUMP_TARGET_PRES_ADJ_THRESHOLD; +} + +/*********************************************************************//** + * @brief * The setDialysatePumpTargetSpeed function sets a new target RPM for the * dialysate pump. * @details \b Inputs: none * @details \b Outputs: pumpTargetSpeed. * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump id supplied. * @param pumpId pump id to set the new speed. * @param rpm new dialysate pump target RPM + * @param isOpenLoopControlEnabled dialysate pump control method * @return TRUE if new target RPM is set, FALSE if not *************************************************************************/ -BOOL setDialysatePumpTargetRPM( DIALYSATE_PUMPS_T pumpId, U32 rpm ) +BOOL setDialysatePumpTargetRPM( DIALYSATE_PUMPS_T pumpId, U32 rpm, BOOL isOpenLoopControlEnabled ) { BOOL result = FALSE; @@ -275,6 +299,13 @@ pumpTargetSpeed[ pumpId ].data = MAX_DIALYSATE_PUMP_RPM; } + // Assign Open loop or close loop control + isDialPumpOpenLoopEnabled[ pumpId ] = isOpenLoopControlEnabled; + +#ifdef __BARO_PRES_SENSOR__ + //Update Degas pump target speed + calculateDegasPumpTargetPressure(); +#endif //handle target speed update when pump is running if ( DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE == dialysatePumps[ pumpId ].dialysatePumpState ) { @@ -329,15 +360,16 @@ dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; dialysatePumps[ pumpId ].controlTimerCounter = 0; dialysatePumps[ pumpId ].isDialPumpOn = FALSE; + isDialPumpOpenLoopEnabled[ pumpId ] = FALSE; //Reset PI Controller if ( D12_PUMP == pumpId ) { - resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } else { - resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } } @@ -666,11 +698,11 @@ { if ( D12_PUMP == pumpId ) { - resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } else { - resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } state = DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE; } @@ -750,8 +782,8 @@ DIALYSATE_PUMP_STATE_T state = DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE; // control at set minimum interval or interval is expired and balance chamber fill is complete - if ( ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) || - ( TRUE == dialPumpsReadyToControl ) ) + if ( ( ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) || + ( TRUE == dialPumpsReadyToControl ) ) && ( TRUE != isDialPumpOpenLoopEnabled[ pumpId ] ) ) { dialysatePumps[ pumpId ].controlTimerCounter = 0; dialPumpsReadyToControl = TRUE; @@ -1129,7 +1161,7 @@ if ( ( TRUE == payload.startStop ) && ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= MAX_DIALYSATE_PUMP_RPM ) ) ) { - setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm ); + setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm, (BOOL)payload.pumpControl ); result = TRUE; }