Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rd28280f1054fc9ddf9304a11373dc9ee963425e3 -r69ed3f91919e50b68ea448a70db81456fb4946a0 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d28280f1054fc9ddf9304a11373dc9ee963425e3) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 69ed3f91919e50b68ea448a70db81456fb4946a0) @@ -66,7 +66,7 @@ #define DIP_MAX_FLOW_RATE 1320.0F ///< Maximum measured BP flow rate allowed. #define DIP_MIN_FLOW_RATE -1320.0F ///< Minimum measured BP flow rate allowed. -#define DIP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0F ///< Maximum difference between measured motor speed and speed implied by measured flow. +#define DIP_MAX_FLOW_VS_SPEED_DIFF_RPM 350.0F ///< Maximum difference between measured motor speed and speed implied by measured flow. #define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. #define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define DIP_MAX_MOTOR_SPEED_ERROR_RPM 300.0F ///< Maximum difference in speed between measured and commanded RPM. @@ -107,9 +107,8 @@ #define DIP_PWM_ZERO_OFFSET 0.1F ///< 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)*(rate)) * 0.000001 ) + ( (rate) * 0.0005 ) + 0.126 + DIP_PWM_ZERO_OFFSET ) -//#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. +#define DIP_PWM_FROM_ML_PER_MIN(rate) ( ( ( (rate) - 49.121F ) / 684.73F ) + DIP_PWM_ZERO_OFFSET ) +/// Conversion from PWM duty cycle % to commanded pump motor speed. PWM range is 10% to 90%. RPM range is 0 to 3200. 3200 / 0.8 = 4000. #define DIP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DIP_PWM_ZERO_OFFSET) * 4000.0F ) // Macro converts PWM to estimate flow rate needed to achieve it. #define DIP_ML_PER_MIN_FROM_PWM(pwm) ( (( pwm - DIP_PWM_ZERO_OFFSET) * 684.73 ) + 49.121 ) @@ -119,6 +118,9 @@ #define SIZE_OF_ROLLING_AVG 10 #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. +#define DIP_MIN_DIR_CHECK_SPEED_RPM 10.0F ///< Minimum motor speed before we check pump direction. +#define DIP_COMMUTATION_ERROR_MAX_CNT 3 ///< Maximum number of commutation errors within time window before alarm triggered. +#define DIP_COMMUTATION_ERROR_TIME_WIN_MS (15 * MS_PER_SECOND) ///< Time window for DPi commutation error. #define DATA_PUBLISH_COUNTER_START_COUNT 30 ///< Data publish counter start count. @@ -251,6 +253,7 @@ // Initialize persistent alarm for flow sensor signal strength too low initPersistentAlarm( ALARM_ID_HD_DIAL_IN_FLOW_OUT_OF_RANGE, 0, DIP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); + initTimeWindowedCount( TIME_WINDOWED_COUNT_DIP_COMMUTATION_ERROR, DIP_COMMUTATION_ERROR_MAX_CNT, DIP_COMMUTATION_ERROR_TIME_WIN_MS ); } /*********************************************************************//** @@ -502,6 +505,10 @@ // Check for home position, zero/low speed checkDialInPumpRotor(); } + else + { + lastDialInPumpDirectionCount = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; + } // Publish dialIn flow data on interval publishDialInFlowData(); @@ -1029,24 +1036,27 @@ { MOTOR_DIR_T dipMCDir, dipDir; U08 dirErrorCnt = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; + F32 measMCSpeed = getMeasuredDialInPumpMCSpeed(); + BOOL minDirSpeed = ( measMCSpeed >= DIP_MIN_DIR_CHECK_SPEED_RPM ? TRUE : FALSE ); + BOOL isHallSensorFailed = ( TRUE == minDirSpeed && lastDialInPumpDirectionCount != dirErrorCnt ? TRUE : FALSE ); // Check pump direction error count - if ( lastDialInPumpDirectionCount != dirErrorCnt ) + if ( ( TRUE == isHallSensorFailed ) && ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_DIP_COMMUTATION_ERROR ) ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_DIRECTION_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif { - lastDialInPumpDirectionCount = dirErrorCnt; SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PUMP_DIRECTION_STATUS_ERROR, (U32)HD_PUMP_DIALYSATE_INLET_PUMP ) } } + lastDialInPumpDirectionCount = dirErrorCnt; dipMCDir = ( getMeasuredDialInPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); dipDir = ( getMeasuredDialInPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); // Check set direction vs. direction from hall sensors - if ( dialInPumpDirectionSet != dipDir ) + if ( ( dialInPumpDirectionSet != dipDir ) && ( TRUE == minDirSpeed ) ) { if ( ++errorDialInPumpDirectionPersistTimerCtr >= DIP_DIRECTION_ERROR_PERSIST ) { @@ -1059,7 +1069,7 @@ } } // Check set direction vs. direction from sign of motor controller speed - else if ( dialInPumpDirectionSet != dipMCDir ) + else if ( ( dialInPumpDirectionSet != dipMCDir ) && ( TRUE == minDirSpeed ) ) { if ( ++errorDialInPumpDirectionPersistTimerCtr >= DIP_DIRECTION_ERROR_PERSIST ) { @@ -1207,9 +1217,9 @@ { F32 flow = (F32)targetDialInFlowRate; F32 speed = getMeasuredDialInPumpSpeed(); - F32 impliedSpeed = DIP_PWM_TO_MOTOR_SPEED_RPM( DIP_PWM_FROM_ML_PER_MIN( flow ) ); + F32 impliedSpeed = ( flow * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO ); F32 delta = fabs( speed - impliedSpeed ); - + if ( delta > DIP_MAX_FLOW_VS_SPEED_DIFF_RPM ) { if ( ++errorDialInFlowVsMotorSpeedPersistTimerCtr >= DIP_FLOW_VS_SPEED_PERSIST ) @@ -1244,50 +1254,53 @@ static void checkDialInPumpMCCurrent( void ) { F32 dipCurr; - - // DialIn pump should be off - if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) + + if ( FALSE == isAlarmActive( ALARM_ID_HD_AC_POWER_LOST ) ) { - dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); - if ( dipCurr > DIP_MAX_CURR_WHEN_STOPPED_MA ) + // DialIn pump should be off + if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) { - dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) - { + dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); + if ( dipCurr > DIP_MAX_CURR_WHEN_STOPPED_MA ) + { + dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) + { #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); + } } } + else + { + dipCurrErrorDurationCtr = 0; + } } + // DialIn pump should be running else { - dipCurrErrorDurationCtr = 0; - } - } - // DialIn pump should be running - else - { - dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); - if ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) - { - dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) - { -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); + dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); + if ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) + { + dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) + { + #ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + #endif + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); + } } } - } - else - { - dipCurrErrorDurationCtr = 0; - } + else + { + dipCurrErrorDurationCtr = 0; + } + } } }