Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r9051b47d2d0e9f112d4ebc310a5572844b7528f4 -rfb1673d2282822995ed233f3e9ea5dfb0567780d --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 9051b47d2d0e9f112d4ebc310a5572844b7528f4) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision fb1673d2282822995ed233f3e9ea5dfb0567780d) @@ -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,15 +107,17 @@ #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 ) /// Measured dialIn flow is filtered w/ moving average. #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. @@ -248,6 +250,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 ); } /*********************************************************************//** @@ -491,6 +494,10 @@ // Check for home position, zero/low speed checkDialInPumpRotor(); } + else + { + lastDialInPumpDirectionCount = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; + } // Publish dialIn flow data on interval publishDialInFlowData(); @@ -1018,24 +1025,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 ) { @@ -1048,7 +1058,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 ) { @@ -1196,9 +1206,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 ) @@ -1233,50 +1243,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; + } + } } }