Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -rfc78b1e5af6d7ab8f7656b410c4cacdfd76a49e6 -r039bdf1f70921b1fe6501d8d2ac9b4f69f066f6f --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision fc78b1e5af6d7ab8f7656b410c4cacdfd76a49e6) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 039bdf1f70921b1fe6501d8d2ac9b4f69f066f6f) @@ -76,7 +76,8 @@ /// Initial conversion factor from target flow rate to PWM duty cycle estimate. #define ROP_FLOW_TO_PWM_DC(flow) ( ROP_FLOW_TO_PWM_SLOPE * flow + ROP_FLOW_TO_PWM_INTERCEPT ) -#define MAX_ALLOWED_FLOW_DEVIATION 0.1F ///< Max allowed deviation from target flow. +#define MAX_ALLOWED_FLOW_DEVIATION_PCT 0.1F ///< Max allowed deviation from target flow in percent. +#define MAX_ALLOWED_FLOW_DEVIATION_MLPM 100.0F ///< Max allowed deviation from target flow in mL/min. #define FLOW_OUT_OF_RANGE_TIME_OUT_MS ( 12 * MS_PER_SECOND ) ///< Flow out of range time out in counts. #define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. #define MAX_ALLOWED_PRESSURE_PSI 130 ///< Maximum allowed pressure that the RO pump can go to. @@ -189,7 +190,7 @@ // Initialize the persistent alarm for max allowed pressure out of range initPersistentAlarm( ALARM_ID_DG_RO_PUMP_PRESSURE_OUT_OF_RANGE, MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL, - MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL ); + MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL ); // Initialize the persistent alarm for not turning off the pump initPersistentAlarm( ALARM_ID_DG_RO_PUMP_DUTY_CYCLE_OUT_OF_RANGE, SAFETY_SHUTDOWN_TIMEOUT, SAFETY_SHUTDOWN_TIMEOUT ); @@ -402,24 +403,47 @@ #endif { // To monitor the flow, the control mode must be in closed loop mode and the pump should be control to flow state - // If the pump is controlled to the maximum pressure, the flow might be different from the target flow for more than 10% + // If the pump is controlled to the maximum pressure, the flow might be different from the target flow for more than the target // but the pump is not able to achieve the flow. - // Do not check the flow target in heat disinfect active cool since the flow during cooling might be very different from the target flow - // since the RO pump membrane is hot and the target flow is low so the RO pump's duty cycle is mostly 0% but the flow is still high and - // above the target - if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) && ( RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE == roPumpState ) && - ( getCurrentOperationMode() != DG_MODE_HCOL ) ) + if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) && ( RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE == roPumpState ) ) { - F32 currentFlow = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); - F32 targetFlow = getTargetROPumpFlowRateLPM(); - // The flow cannot be out of range for than 10% of the target flow - BOOL isFlowOutOfRange = ( fabs( 1.0F - ( currentFlow / targetFlow ) ) > MAX_ALLOWED_FLOW_DEVIATION ? TRUE : FALSE ); - // Figure out whether flow is out of range from which side - BOOL isFlowOutOfUpperRange = ( isFlowOutOfRange && ( currentFlow > targetFlow ) ? TRUE : FALSE ); - BOOL isFlowOutOfLowerRange = ( isFlowOutOfRange && ( currentFlow < targetFlow ) ? TRUE : FALSE ); + BOOL isFlowOutOfUpperRange = FALSE; + BOOL isFlowOutOfLowerRange = FALSE; + BOOL isFlowOutOfRange = FALSE; + F32 currentFlowLPM = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); + F32 targetFlowLPM = getTargetROPumpFlowRateLPM(); - checkPersistentAlarm( ALARM_ID_DG_FLOW_RATE_OUT_OF_UPPER_RANGE, isFlowOutOfUpperRange, currentFlow, targetFlow ); - checkPersistentAlarm( ALARM_ID_DG_FLOW_RATE_OUT_OF_LOWER_RANGE, isFlowOutOfLowerRange, currentFlow, targetFlow ); + switch ( getCurrentOperationMode() ) + { + case DG_MODE_GENE: + case DG_MODE_DRAI: + // The flow cannot be out of target by more than +/- 100 mL/min + isFlowOutOfRange = ( ( fabs( currentFlowLPM - targetFlowLPM ) * ML_PER_LITER ) > MAX_ALLOWED_FLOW_DEVIATION_MLPM ); + isFlowOutOfUpperRange = ( isFlowOutOfRange && ( currentFlowLPM > targetFlowLPM ) ? TRUE : FALSE ); + isFlowOutOfLowerRange = ( isFlowOutOfRange && ( currentFlowLPM < targetFlowLPM ) ? TRUE : FALSE ); + break; + + case DG_MODE_FILL: + case DG_MODE_FLUS: + case DG_MODE_HEAT: + case DG_MODE_CHEM: + case DG_MODE_CHFL: + // The flow cannot be out of range for than 10% of the target flow + isFlowOutOfRange = ( fabs( 1.0F - ( currentFlowLPM / targetFlowLPM ) ) > MAX_ALLOWED_FLOW_DEVIATION_PCT ? TRUE : FALSE ); + isFlowOutOfUpperRange = ( isFlowOutOfRange && ( currentFlowLPM > targetFlowLPM ) ? TRUE : FALSE ); + isFlowOutOfLowerRange = ( isFlowOutOfRange && ( currentFlowLPM < targetFlowLPM ) ? TRUE : FALSE ); + break; + + default: + // Do nothing in the rest of the modes. + // Do not check the flow target in heat disinfect active cool since the flow during cooling might be very different from the target flow + // since the RO pump membrane is hot and the target flow is low so the RO pump's duty cycle is mostly 0% but the flow is still high and + // above the target + break; + } + + checkPersistentAlarm( ALARM_ID_DG_FLOW_RATE_OUT_OF_UPPER_RANGE, isFlowOutOfUpperRange, currentFlowLPM, targetFlowLPM ); + checkPersistentAlarm( ALARM_ID_DG_FLOW_RATE_OUT_OF_LOWER_RANGE, isFlowOutOfLowerRange, currentFlowLPM, targetFlowLPM ); } else {