Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rc52bfbc3f41fecde11bbec3eb71dc812154fc760 -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision c52bfbc3f41fecde11bbec3eb71dc812154fc760) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -62,7 +62,9 @@ /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. #define BP_SPEED_CALC_BUFFER_LEN ( MS_PER_SECOND / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) #define BP_MAX_ROTOR_SPEED_RPM 100.0 ///< Maximum rotor speed allowed for blood pump. - + +#define BP_MAX_FLOW_RATE 1320.0 ///< Maximum measured BP flow rate allowed. +#define BP_MIN_FLOW_RATE -1320.0 ///< Minimum measured BP flow rate allowed. #define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. #define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). @@ -78,7 +80,9 @@ /// Persist time (task intervals) pump direction error condition. static const U32 BP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) blood pump rotor speed too fast error condition. -static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) blood flow rate out of range error condition. +static const U32 BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); #define BP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped #define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running @@ -97,8 +101,14 @@ #define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( BP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to motor RPM. #define BP_GEAR_RATIO 32.0 ///< Blood pump motor to blood pump gear ratio #define BP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed -/// Conversion factor from mL/min to estimated PWM duty cycle %. -#define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) +/// Conversion macro from mL/min to estimated PWM duty cycle %. +#define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) +/// Conversion from PWM duty cycle % to commanded pump motor speed. +#ifndef V2_0_SYSTEM + #define BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 4000.0 ) +#else + #define BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 3200.0 ) +#endif #define BLOODPUMP_ADC_FULL_SCALE_V 3.0 ///< BP analog signals are 0-3V (while int. ADC ref may be different) #define BLOODPUMP_ADC_ZERO 1998 ///< Blood pump ADC channel zero offset. @@ -269,6 +279,7 @@ initPersistentAlarm( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_FAST_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_SLOW_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, 0, BLOOD_FLOW_COMM_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, 0, BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } /*********************************************************************//** @@ -291,7 +302,7 @@ { #ifndef NO_PUMP_FLOW_LIMITS // Verify flow rate - if ( flowRate <= MAX_BLOOD_FLOW_RATE ) + if ( flowRate <= MAX_SET_BLOOD_FLOW_RATE ) #endif { resetBloodFlowMovingAverage(); @@ -611,7 +622,7 @@ bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePct ); + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); bpControlTimerCounter = 0; result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } @@ -650,7 +661,7 @@ bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePct ); + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); bpControlTimerCounter = 0; result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } @@ -719,7 +730,7 @@ static void stopBloodPump( void ) { isBloodPumpOn = FALSE; - bloodPumpPWMDutyCyclePctSet = 0.0; + bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET; etpwmSetCmpA( etpwmREG1, 0 ); SET_BP_STOP(); } @@ -1131,10 +1142,10 @@ static void checkBloodPumpSpeeds( void ) { F32 measMotorSpeed = fabs( getMeasuredBloodPumpSpeed() ); - S32 cmdRate = targetBloodFlowRate; - - // Check for pump running while commanded off - if ( 0 == cmdRate ) + F32 measMCMotorSpeed = fabs( getMeasuredBloodPumpMCSpeed() ); + + // Check for pump running while commanded off + if ( 0 == targetBloodFlowRate ) { if ( measMotorSpeed > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) { @@ -1154,23 +1165,25 @@ else { errorBloodMotorOffPersistTimerCtr = 0; - } - + } + + // Checks that only occur when pump is running (and beyond ramp). if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) { - F32 cmdMotorSpeed = ( (F32)cmdRate / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; - F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 cmdMotorSpeed = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); + F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); F32 measRotorSpeed = getMeasuredBloodPumpRotorSpeed(); F32 measMotorSpeedInRotorRPM = measMotorSpeed / BP_GEAR_RATIO; F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); // Check measured motor speed vs. commanded motor speed while controlling to target - if ( deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) + if ( ( deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) ) { if ( ++errorBloodMotorSpeedPersistTimerCtr >= BP_MOTOR_SPEED_ERROR_PERSIST ) { #ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, (F32)cmdRate, measMotorSpeed ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); #endif } } @@ -1213,10 +1226,19 @@ *************************************************************************/ static void checkBloodPumpFlowAgainstSpeed( void ) { - // Check only performed while in treatment mode and while we are in control to target state + F32 flow = getMeasuredBloodFlowRate(); + + // Range check on measure BP flow rate. +#ifndef DISABLE_PUMP_FLOW_CHECKS + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, ( flow > BP_MAX_FLOW_RATE ) || ( flow < BP_MIN_FLOW_RATE ) ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, flow ); + } +#endif + + // Flow vs. speed check only performed while in treatment mode and while we are in control to target state if ( ( MODE_TREA == getCurrentOperationMode() ) && ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) ) { - F32 flow = getMeasuredBloodFlowRate(); F32 speed = getMeasuredBloodPumpSpeed(); F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; F32 delta = fabs( speed - impliedSpeed ); Index: firmware/App/Controllers/BloodFlow.h =================================================================== diff -u -r70d33c50c8c3fd987f39eaa1f3b294860d569830 -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision 70d33c50c8c3fd987f39eaa1f3b294860d569830) +++ firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -31,8 +31,8 @@ // ********** public definitions ********** -#define MAX_BLOOD_FLOW_RATE 500 ///< Maximum blood flow rate (in mL/min). -#define MIN_BLOOD_FLOW_RATE 100 ///< Minimum blood flow rate (in mL/min). +#define MAX_SET_BLOOD_FLOW_RATE 500 ///< Maximum blood flow rate (in mL/min). +#define MIN_SET_BLOOD_FLOW_RATE 100 ///< Minimum blood flow rate (in mL/min). #define SALINE_BOLUS_FLOW_RATE 150 ///< Saline bolus flow rate (in mL/min). #define VOLUME_PER_BP_MOTOR_REV_ML 0.2 ///< Theoretical volume (mL) of blood/saline volume per motor revolution. Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rd7a56c36bbc9b5c66585b0ef39e75bb7766d544f -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d7a56c36bbc9b5c66585b0ef39e75bb7766d544f) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -63,6 +63,8 @@ #define DIP_SPEED_CALC_BUFFER_LEN ( 1000 / DIP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) #define DIP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. +#define DIP_MAX_FLOW_RATE 1320.0 ///< Maximum measured BP flow rate allowed. +#define DIP_MIN_FLOW_RATE -1320.0 ///< Minimum measured BP flow rate allowed. #define DIP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured motor speed and speed implied by measured flow. #define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). @@ -78,8 +80,9 @@ static const U32 DIP_ROTOR_SPEED_ERROR_PERSIST = ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) pump direction error condition. static const U32 DIP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) dialysate flow rate out of range error condition. +static const U32 DIP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); - #define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. #define DIP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running. #define DIP_MAX_CURR_ERROR_DURATION_MS 2000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. @@ -100,6 +103,12 @@ #define DIP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. /// Macro converts flow rate to estimate PWM needed to achieve it. #define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) +/// Conversion from PWM duty cycle % to commanded pump motor speed. +#ifndef V2_0_SYSTEM + #define DIP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DIP_PWM_ZERO_OFFSET) * 4000.0 ) +#else + #define DIP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DIP_PWM_ZERO_OFFSET) * 3200.0 ) +#endif #define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 ///< BP analog signals are 0-3V (while int. ADC ref V may be different). #define DIAL_IN_PUMP_ADC_ZERO 1998 ///< Mid-point (zero) for ADC readings. @@ -261,6 +270,7 @@ initPersistentAlarm( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, 0, DIALYSATE_FLOW_FAST_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_DP_FLOW_SLOW_READ_TIMEOUT_ERROR, 0, DIALYSATE_FLOW_SLOW_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_DP_FLOW_SENSOR_ERROR, 0, DIALYSATE_FLOW_COMM_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_HD_DIAL_IN_FLOW_OUT_OF_RANGE, 0, DIP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } /*********************************************************************//** @@ -574,7 +584,7 @@ dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); dialInPumpControlModeSet = dialInPumpControlMode; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePct ); + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); dipControlTimerCounter = 0; result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } @@ -613,7 +623,7 @@ dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); dialInPumpControlModeSet = dialInPumpControlMode; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePct ); + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); dipControlTimerCounter = 0; result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } @@ -682,7 +692,7 @@ static void stopDialInPump( void ) { isDialInPumpOn = FALSE; - dialInPumpPWMDutyCyclePctSet = 0.0; + dialInPumpPWMDutyCyclePctSet = DIP_PWM_ZERO_OFFSET; etpwmSetCmpA( etpwmREG2, 0 ); SET_DIP_STOP(); } @@ -1100,10 +1110,10 @@ static void checkDialInPumpSpeeds( void ) { F32 measMotorSpeed = getMeasuredDialInPumpSpeed(); - S32 cmdRate = targetDialInFlowRate; + F32 measMCMotorSpeed = fabs( getMeasuredDialInPumpMCSpeed() ); // Check for pump running while commanded off - if ( 0 == cmdRate ) + if ( 0 == targetDialInFlowRate ) { if ( measMotorSpeed > DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) { @@ -1125,21 +1135,23 @@ errorDialInMotorOffPersistTimerCtr = 0; } + // Checks that only occur when pump is running (and beyond ramp). if ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) { - F32 cmdMotorSpeed = ( (F32)cmdRate / (F32)ML_PER_LITER ) * DIP_REV_PER_LITER * DIP_GEAR_RATIO; + F32 cmdMotorSpeed = DIP_PWM_TO_MOTOR_SPEED_RPM( dialInPumpPWMDutyCyclePctSet ); F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); F32 measRotorSpeed = getMeasuredDialInPumpRotorSpeed(); F32 measMotorSpeedInRotorRPM = measMotorSpeed / DIP_GEAR_RATIO; F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); // Check measured motor speed vs. commanded motor speed while controlling to target - if ( deltaMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) + if ( ( deltaMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) ) { if ( ++errorDialInMotorSpeedPersistTimerCtr >= DIP_MOTOR_SPEED_ERROR_PERSIST ) { #ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MOTOR_SPEED_CHECK, (F32)cmdRate, measMotorSpeed ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); #endif } } @@ -1183,6 +1195,16 @@ *************************************************************************/ static void checkDialInPumpFlowAgainstSpeed( void ) { + F32 flow = getMeasuredDialInFlowRate(); + + // Range check on measure DPi flow rate. +#ifndef DISABLE_PUMP_FLOW_CHECKS + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DIAL_IN_FLOW_OUT_OF_RANGE, ( flow > DIP_MAX_FLOW_RATE ) || ( flow < DIP_MIN_FLOW_RATE ) ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_DIAL_IN_FLOW_OUT_OF_RANGE, flow ); + } +#endif + // Check only performed while in treatment mode and while we are in control to target state if ( ( MODE_TREA == getCurrentOperationMode() ) && ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) ) { Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r023b561bbcfe0c8e93f375cfcb96f9b801d93ffd -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 023b561bbcfe0c8e93f375cfcb96f9b801d93ffd) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -104,6 +104,12 @@ #define DOP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. /// Macro converts a flow rate to an estimated PWM duty cycle %. #define DOP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DOP_GEAR_RATIO * DOP_MOTOR_RPM_TO_PWM_DC_FACTOR + DOP_PWM_ZERO_OFFSET ) +/// Conversion from PWM duty cycle % to commanded pump motor speed. +#ifndef V2_0_SYSTEM + #define DOP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DOP_PWM_ZERO_OFFSET) * 4000.0 ) +#else + #define DOP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DOP_PWM_ZERO_OFFSET) * 3200.0 ) +#endif #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. @@ -571,7 +577,7 @@ resetPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, (F32)( (S32)lastGivenRate - getTargetDialInFlowRate() ) * UF_PWM_DC_PCT_PER_ML_PER_MIN ); } dialOutPumpControlModeSet = dialOutPumpControlMode; - setDialOutPumpControlSignalPWM( dialOutPumpPWMDutyCyclePct ); + setDialOutPumpControlSignalPWM( dialOutPumpPWMDutyCyclePctSet ); dopControlTimerCounter = 0; result = DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE; } @@ -646,7 +652,7 @@ *************************************************************************/ static void stopDialOutPump( void ) { - dialOutPumpPWMDutyCyclePctSet = 0.0; + dialOutPumpPWMDutyCyclePctSet = DOP_PWM_ZERO_OFFSET; setDialOutPumpControlSignalPWM( 0 ); SET_DOP_STOP(); isDialOutPumpOn = FALSE; @@ -858,9 +864,10 @@ static void checkDialOutPumpSpeeds( void ) { F32 measMotorSpeed = getMeasuredDialOutPumpSpeed(); + F32 measMCMotorSpeed = fabs( getMeasuredDialOutPumpMCSpeed() ); // Check for pump running while commanded off - if ( FALSE == isDialOutPumpOn ) + if ( dialOutPumpPWMDutyCyclePctSet > DOP_PWM_ZERO_OFFSET ) { if ( measMotorSpeed > DOP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) { @@ -884,19 +891,20 @@ if ( DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE == dialOutPumpState ) { - F32 controllerMotorSpeed = getMeasuredDialOutPumpMCSpeed(); - F32 deltaMotorSpeed = fabs( measMotorSpeed - controllerMotorSpeed ); + F32 cmdMotorSpeed = DOP_PWM_TO_MOTOR_SPEED_RPM( dialOutPumpPWMDutyCyclePctSet ); + F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); F32 measRotorSpeed = getMeasuredDialOutPumpRotorSpeed(); F32 measMotorSpeedInRotorRPM = measMotorSpeed / DOP_GEAR_RATIO; F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); // Check measured motor speed vs. commanded motor speed while controlling to target - if ( deltaMotorSpeed > DOP_MAX_MOTOR_SPEED_ERROR_RPM ) + if ( ( deltaMotorSpeed > DOP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > DOP_MAX_MOTOR_SPEED_ERROR_RPM ) ) { if ( ++errorDialOutMotorSpeedPersistTimerCtr >= DOP_MOTOR_SPEED_ERROR_PERSIST ) { #ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_MOTOR_SPEED_CHECK, controllerMotorSpeed, measMotorSpeed ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); #endif } } Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r39dd0b7734331c784b8410f2bbd481e0f792892e -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 39dd0b7734331c784b8410f2bbd481e0f792892e) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -41,18 +41,24 @@ #define VENOUS_PRESSURE_OFFSET ( 1638 ) ///< Offset for 14-bit venous pressure sensor reading. #define VENOUS_PRESSURE_SCALE ( 14745 - VENOUS_PRESSURE_OFFSET ) ///< Scale for venous pressure sensor. -#define VENOUS_PRESSURE_MIN ( -30.0 ) ///< Minimum of scale for venous pressure sensor reading (in PSI). -#define VENOUS_PRESSURE_MAX ( 30.0 ) ///< Maximum of scale for venous pressure sensor reading (in PSI). +#define VENOUS_PRESSURE_MIN_PSI ( -30.0 ) ///< Minimum of scale for venous pressure sensor reading (in PSI). +#define VENOUS_PRESSURE_MAX_PSI ( 30.0 ) ///< Maximum of scale for venous pressure sensor reading (in PSI). #define ARTERIAL_PRESSURE_SELF_TEST_MIN ( -300.0 ) ///< Minimum self-test value for arterial pressure sensor reading (in mmHg). #define ARTERIAL_PRESSURE_SELF_TEST_MAX ( 100.0 ) ///< Maximum self-test value for arterial pressure sensor reading (in mmHg). +#define ARTERIAL_PRESSURE_MAX_MMHG ( 2000.0 ) ///< Maximum arterial pressure reading (in mmHg) for range check. +#define ARTERIAL_PRESSURE_MIN_MMHG ( -1500.0 ) ///< Minimum arterial pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_SELF_TEST_MIN ( -100.0 ) ///< Minimum self-test value for venous pressure sensor reading (in mmHg). #define VENOUS_PRESSURE_SELF_TEST_MAX ( 600.0 ) ///< Maximum self-test value for venous pressure sensor reading (in mmHg). +#define VENOUS_PRESSURE_MAX_MMHG ( 2000.0 ) ///< Maximum venous pressure reading (in mmHg) for range check. +#define VENOUS_PRESSURE_MIN_MMHG ( -1500.0 ) ///< Minimum venous pressure reading (in mmHg) for range check. -#define VENOUS_PRESSURE_MIN_TEMP ( 0.0 ) ///< Minimum venous pressure sensor temperature. TODO - get from Systems -#define VENOUS_PRESSURE_MAX_TEMP ( 80.0 ) ///< Maximum venous pressure sensor temperature. TODO - get from Systems +#define VENOUS_PRESSURE_MIN_TEMP ( 0.0 ) ///< Minimum venous pressure sensor temperature. +#define VENOUS_PRESSURE_MAX_TEMP ( 80.0 ) ///< Maximum venous pressure sensor temperature. +#define MIN_OCCLUSION_COUNTS ( 2000 ) ///< Minimum occlusion sensor reading for range check. + #define PSI_TO_MMHG ( 51.7149 ) ///< Conversion factor for converting PSI to mmHg. #define VENOUS_PRESSURE_NORMAL_OP 0 ///< Venous pressure status bits indicate normal operation. @@ -148,6 +154,11 @@ initPersistentAlarm( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_DPI_OCCLUSION_SENSOR_ERROR, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_DPO_OCCLUSION_SENSOR_ERROR, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_DPI_OCCLUSION_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_DPO_OCCLUSION_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); lastVenousPressureReadCtr = 0; lastBPOcclReadCtr = 0; @@ -347,7 +358,7 @@ // Record venous read counter for next time around lastVenousPressureReadCtr = venReadCtr; // Convert venous pressure to PSI and then mmHg - venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX - VENOUS_PRESSURE_MIN) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN; + venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX_PSI - VENOUS_PRESSURE_MIN_PSI) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN_PSI; // Convert venous pressure from PSI to mmHg if sensor status is normal if ( VENOUS_PRESSURE_NORMAL_OP == venPresStatus ) { @@ -441,13 +452,23 @@ { F32 artPres = getMeasuredArterialPressure(); +#ifndef DISABLE_PRESSURE_CHECKS + // Check arterial pressure is in range + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres > ARTERIAL_PRESSURE_MAX_MMHG ) || + TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres < ARTERIAL_PRESSURE_MIN_MMHG ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres ); + } +#endif + // Check arterial pressure during treatment mode if ( MODE_TREA == getCurrentOperationMode() ) { F32 artLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); F32 artHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); #ifndef DISABLE_PRESSURE_CHECKS + // Check arterial pressure is within user set alarm limits if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres < artLowLimit ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres, artLowLimit ); @@ -483,6 +504,15 @@ { F32 venPres = getMeasuredVenousPressure(); +#ifndef DISABLE_PRESSURE_CHECKS + // Check arterial pressure is in range + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres > VENOUS_PRESSURE_MAX_MMHG ) || + TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres < VENOUS_PRESSURE_MIN_MMHG ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres ); + } +#endif + // Check arterial pressure during treatment mode if ( MODE_TREA == getCurrentOperationMode() ) { @@ -526,13 +556,26 @@ U32 bpOccl = getMeasuredBloodPumpOcclusion(); U32 diOccl = getMeasuredDialInPumpOcclusion(); U32 doOccl = getMeasuredDialOutPumpOcclusion(); - BOOL alarmDetected = FALSE; #ifndef DISABLE_PRESSURE_CHECKS + // Range check occlusion sensors + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl < MIN_OCCLUSION_COUNTS ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DPI_OCCLUSION_OUT_OF_RANGE, diOccl < MIN_OCCLUSION_COUNTS ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DPI_OCCLUSION_OUT_OF_RANGE, diOccl ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DPO_OCCLUSION_OUT_OF_RANGE, doOccl < MIN_OCCLUSION_COUNTS ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DPO_OCCLUSION_OUT_OF_RANGE, doOccl ); + } + // Check for occlusions if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) { - alarmDetected = TRUE; + signalBloodPumpHardStop(); // Stop pump immediately SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) } else if ( bpOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) @@ -541,7 +584,7 @@ } if ( diOccl > ( OCCLUSION_THRESHOLD_OFFSET + dialInPumpOcclusionAfterCartridgeInstall ) ) { - alarmDetected = TRUE; + signalDialInPumpHardStop(); // Stop pump immediately SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_DIAL_IN_PUMP, diOccl ) } else if ( diOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + dialInPumpOcclusionAfterCartridgeInstall ) ) @@ -550,18 +593,13 @@ } if ( doOccl > ( OCCLUSION_THRESHOLD_OFFSET + dialOutPumpOcclusionAfterCartridgeInstall ) ) { - alarmDetected = TRUE; + signalDialOutPumpHardStop(); // Stop pump immediately SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_DIAL_OUT_PUMP, doOccl ) } else if ( doOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + dialOutPumpOcclusionAfterCartridgeInstall ) ) { clearAlarmCondition( ALARM_ID_OCCLUSION_DIAL_OUT_PUMP ); } - - if ( TRUE == alarmDetected ) - { - // TODO - stop pumps immediately, ... - } #endif } Index: firmware/App/HDCommon.h =================================================================== diff -u -r40b37059da0ecd27dc9beb48614f6f3869d18732 -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 40b37059da0ecd27dc9beb48614f6f3869d18732) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -48,12 +48,12 @@ // #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages // #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks - #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks - #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks +// #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks +// #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks #define DISABLE_SYRINGE_PUMP 1 // Disable syringe pump functionality #define ALWAYS_ALLOW_SYRINGE_PUMP_CMDS 1 // Allow syringe pump commands at any time except when pump is busy - #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks +// #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks // #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position #define DISABLE_CAL_CHECK 1 // Disable calibration checks Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rea91805fa5ea8b23cfcaa0ee2493339e57fe7fc7 -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision ea91805fa5ea8b23cfcaa0ee2493339e57fe7fc7) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -1006,7 +1006,7 @@ U32 dialVolume = dialRate * ( (U32)( (F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN ) + 1 ); // In mL // Validate new rates - if ( ( bloodRate >= MIN_BLOOD_FLOW_RATE ) && ( bloodRate <= MAX_BLOOD_FLOW_RATE ) && + if ( ( bloodRate >= MIN_SET_BLOOD_FLOW_RATE ) && ( bloodRate <= MAX_SET_BLOOD_FLOW_RATE ) && ( dialRate >= MIN_DIAL_IN_FLOW_RATE ) && ( dialRate <= MAX_DIAL_IN_FLOW_RATE ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) { @@ -1018,7 +1018,7 @@ } else { - if ( ( bloodRate < MIN_BLOOD_FLOW_RATE ) || ( bloodRate > MAX_BLOOD_FLOW_RATE ) ) + if ( ( bloodRate < MIN_SET_BLOOD_FLOW_RATE ) || ( bloodRate > MAX_SET_BLOOD_FLOW_RATE ) ) { rejectReason = REQUEST_REJECT_REASON_BLOOD_FLOW_OUT_OF_RANGE; } Index: firmware/App/Services/WatchdogMgmt.c =================================================================== diff -u -r8af2673f6c9142c9a16bb676447916ea788ae53d -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 8af2673f6c9142c9a16bb676447916ea788ae53d) +++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -179,19 +179,19 @@ // Verify 24V is down when w.d. expired if ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 2.0, v24 ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 2.0, v24 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } // Verify backup alarm audio is on when w.d. expired else if ( audioCurrent < MIN_BACKUP_ALARM_CURRENT_MA ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 3.0, audioCurrent ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 3.0, audioCurrent ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } } else { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 1 ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 1 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } watchdogSelfTestTimerCount = getMSTimerCount(); @@ -209,13 +209,13 @@ // Verify 24V is down when w.d. recovered if ( v24 < MIN_24V_LEVEL_ON_WATCHDOG_RECOVER ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 4.0, v24 ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 4.0, v24 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } // Verify backup alarm audio is on when w.d. recovered else if ( audioCurrent > MAX_BACKUP_ALARM_CURRENT_MA ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 5.0, audioCurrent ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 5.0, audioCurrent ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } else