Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r8377b4e6ed494cbfc5dfc2bd9ad3c89b85b333cd -r93a439cf9d1b347e23b84d1156417380ee01efaa --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 8377b4e6ed494cbfc5dfc2bd9ad3c89b85b333cd) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 93a439cf9d1b347e23b84d1156417380ee01efaa) @@ -52,11 +52,18 @@ #define DOP_P_COEFFICIENT 0.0050 ///< P term for dialysate outlet pump control. #define DOP_I_COEFFICIENT 0.0001 ///< I term for dialysate outlet pump control. -#define DOP_HOME_RATE 50 ///< target pump speed (in estimate mL/min) for homing. +#define DOP_HOME_RATE 100 ///< target pump speed (in estimate mL/min) for homing. #define DOP_HOME_TIMEOUT_MS 10000 ///< maximum time allowed for homing to complete (in ms). #define DOP_SPEED_CALC_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the dialysate outlet pump speed is calculated. #define DOP_HALL_EDGE_COUNTS_PER_REV 48 ///< number of hall sensor edge counts per motor revolution. +#define DOP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< maximum motor speed (RPM) while motor is commanded off. +#define DOP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< maximum difference in speed between motor and rotor (in rotor RPM). +#define DOP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< maximum difference in speed between measured and commanded RPM. +#define DOP_OFF_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) for motor off error condition. +#define DOP_MOTOR_SPEED_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) motor speed error condition. +#define DOP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) rotor speed error condition. + #define DOP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. #define DOP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running. #define DOP_MAX_CURR_WHEN_RUNNING_MA 1000.0 ///< Motor controller current should not exceed this when pump should be running. @@ -142,6 +149,10 @@ static MOTOR_DIR_T dopMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; ///< pump direction according to hall sensor count static U32 dopMotorSpeedCalcTimerCtr = 0; ///< counter determines interval for calculating dialysate outlet pump motor speed from hall sensor count. +static U32 errorDialOutMotorOffPersistTimerCtr = 0; ///< persistence timer counter for motor off check error condition. +static U32 errorDialOutMotorSpeedPersistTimerCtr = 0; ///< persistence timer counter for motor speed error condition. +static U32 errorDialOutRotorSpeedPersistTimerCtr = 0; ///< persistence timer counter for rotor speed error condition. + static DIAL_OUT_PUMP_SELF_TEST_STATE_T dialOutPumpSelfTestState = DIAL_OUT_PUMP_SELF_TEST_STATE_START; ///< Current state of the dialysate outlet pump self test state machine. static U32 dialOutPumpSelfTestTimerCount = 0; ///< Timer counter for time reference during self test. @@ -166,7 +177,6 @@ static void checkDialOutPumpRotor( void ); static void checkDialOutPumpDirection( void ); static void checkDialOutPumpSpeeds( void ); -static void checkDialOutPumpFlowAgainstSpeed( void ); static void checkDialOutPumpMCCurrent( void ); static DATA_GET_PROTOTYPE( U32, getPublishDialOutDataInterval ); @@ -407,18 +417,17 @@ // calculate dialysate outlet pump motor speed/direction from hall sensor count updateDialOutPumpSpeedAndDirectionFromHallSensors(); - // check pump speeds and flow - checkDialOutPumpSpeeds(); - checkDialOutPumpFlowAgainstSpeed(); - - // check for home position, zero/low speed - checkDialOutPumpRotor(); - // don't start enforcing checks until out of init/POST mode if ( getCurrentOperationMode() != MODE_INIT ) { + // check pump direction checkDialOutPumpDirection(); + // check pump controller current checkDialOutPumpMCCurrent(); + // check pump speeds + checkDialOutPumpSpeeds(); + // check for home position, zero/low speed + checkDialOutPumpRotor(); } publishDialOutFlowData(); @@ -810,19 +819,96 @@ dopMCDir = ( getMeasuredDialOutPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); if ( ( dialOutPumpDirectionSet != dopMCDir ) || ( dialOutPumpDirectionSet != dopMotorDirectionFromHallSensors ) ) { +#ifndef DISABLE_PUMP_DIRECTION_CHECKS SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, (U32)dialOutPumpDirectionSet, (U32)dopMotorDirectionFromHallSensors ) +#endif } } } +/*********************************************************************//** + * @brief + * The checkDialOutPumpSpeeds function checks several aspects of the dialysate \n + * outlet pump speed. \n + * 1. while pump is commanded off, measured motor speed should be < limit. \n + * 2. while pump is controlling, measured motor speed should be within allowed range of measured motor controller speed. \n + * 3. measured motor speed should be within allowed range of measured rotor speed. \n + * All 3 checks have a persistence time that must be met before an alarm is triggered. + * @details + * Inputs : targetDialOutFlowRate, dialOutPumpSpeedRPM, dialOutPumpRotorSpeedRPM + * Outputs : alarm(s) may be triggered + * @return none + *************************************************************************/ static void checkDialOutPumpSpeeds( void ) { + F32 measMotorSpeed = getMeasuredDialOutPumpSpeed(); -} + // check for pump running while commanded off + if ( FALSE == isDialOutPumpOn ) + { + if ( measMotorSpeed > DOP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) + { + if ( ++errorDialOutMotorOffPersistTimerCtr >= DOP_OFF_ERROR_PERSIST ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_OFF_CHECK, measMotorSpeed ); +#endif + } + } + else + { + errorDialOutMotorOffPersistTimerCtr = 0; + } + } + else + { + errorDialOutMotorOffPersistTimerCtr = 0; + } -static void checkDialOutPumpFlowAgainstSpeed( void ) -{ + if ( DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE == dialOutPumpState ) + { + F32 controllerMotorSpeed = getMeasuredDialOutPumpMCSpeed(); + F32 deltaMotorSpeed = FABS( measMotorSpeed - controllerMotorSpeed ); + 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 ( ++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 ); +#endif + } + } + else + { + errorDialOutMotorSpeedPersistTimerCtr = 0; + } + + // check measured rotor speed vs. measured motor speed while controlling to target + if ( deltaRotorSpeed > DOP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) + { + if ( ++errorDialOutRotorSpeedPersistTimerCtr >= DOP_ROTOR_SPEED_ERROR_PERSIST ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK, measRotorSpeed, measMotorSpeed ); +#endif + } + } + else + { + errorDialOutRotorSpeedPersistTimerCtr = 0; + } + + } + else + { + errorDialOutMotorSpeedPersistTimerCtr = 0; + errorDialOutRotorSpeedPersistTimerCtr = 0; + } } /************************************************************************* @@ -847,7 +933,7 @@ dopCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; if ( dopCurrErrorDurationCtr > DOP_MAX_CURR_ERROR_DURATION_MS ) { -#ifndef DISABLE_MOTOR_CURRENT_ERRORS +#ifndef DISABLE_MOTOR_CURRENT_CHECKS SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK, getMeasuredDialOutPumpMCCurrent() ); #endif } @@ -866,7 +952,7 @@ dopCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; if ( dopCurrErrorDurationCtr > DOP_MAX_CURR_ERROR_DURATION_MS ) { -#ifndef DISABLE_MOTOR_CURRENT_ERRORS +#ifndef DISABLE_MOTOR_CURRENT_CHECKS SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK, getMeasuredDialOutPumpMCCurrent() ); #endif }