Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r1e34d32fcfac88792ed72e55953dee721bacd9d5 -r9426334142cbfdea9ee99e3040fc08ff0247da7b --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 1e34d32fcfac88792ed72e55953dee721bacd9d5) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 9426334142cbfdea9ee99e3040fc08ff0247da7b) @@ -61,19 +61,20 @@ #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines -#define FLUSH_DRAIN_WAIT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. -#define MIN_INLET_TEMPERATURE_C 15.0F ///< Minimum water inlet temperature in C. TODO original temperature was 25 C +#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. +#define MIN_INLET_TEMPERATURE_C 24.0F ///< Minimum water inlet temperature in C. #define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0F ///< Maximum water inlet conductivity in us/cm // Flush circulation path state defines #define RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM 0.8F ///< RO pump target flow rate during flush/fill in L/min. #define MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI 130 ///< Maximum RO pump pressure during flush/fill states in psi. -#define FLUSH_CICRCULATION_WAIT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Flush/rinse circulation path wait time in milliseconds. -#define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 50.0F ///< Maximum flush circulation temperature difference tolerance in C. TODO original difference was 3.0 degrees +#define FLUSH_CICRCULATION_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Flush circulation path wait time in milliseconds. +#define FLUSH_CIRCULATION_CONC_PUMPS_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Flush circulation concentrate pumps on time in milliseconds. +#define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 3.0F ///< Maximum flush circulation temperature difference tolerance in C. #define NUM_OF_TEMP_SENSORS_TO_AVG 4.0F ///< Number of temperature sensors to average to check the difference. -#define ACID_PUMP_SPEED_ML_PER_MIN -30.0F ///< Acid concentrate pump speed in mL/min. +#define ACID_PUMP_SPEED_ML_PER_MIN 30.6F ///< Acid concentrate pump speed in mL/min. // The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during heat disinfect -#define BICARB_PUMP_SPEED_ML_PER_MIN 30.6F ///< Bicarb concentrate pump speed in mL/min. +#define BICARB_PUMP_SPEED_ML_PER_MIN -30.0F ///< Bicarb concentrate pump speed in mL/min. // Flush and drain R1 and R2 #define RSRVRS_FULL_VOL_ML 1900.0F ///< Reservoirs 1 & 2 full volume in mL. @@ -283,6 +284,16 @@ *************************************************************************/ U32 execHeatDisinfectMode( void ) { + checkInletWaterPressure(); + + if ( heatDisinfectState != DG_HEAT_DISINFECT_STATE_FLUSH_DRAIN ) + { + // Do not check on the inlet water temperature and conductivity until the inlet filters have been flushed + // The initial states are drain reservoirs but in those states VPi is closed so these alarms are not checked + checkInletWaterTemperature(); + checkInletWaterConductivity(); + } + monitorModeHeatDisinfect(); switch ( heatDisinfectState ) @@ -586,43 +597,12 @@ // Check if flush time has elapsed if ( TRUE == didTimeout( stateTimer, FLUSH_DRAIN_WAIT_TIME_MS ) ) { - BOOL hasConductivityPassed = FALSE; - - // If the inlet temperature and conductivity are in range, move onto the next state - if ( ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) >= MIN_INLET_TEMPERATURE_C ) && - ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) <= MAX_INLET_CONDUCTIVITY_US_PER_CM ) ) - { - hasConductivityPassed = TRUE; - } - -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) - { - hasConductivityPassed = TRUE; - } -#endif - - if ( TRUE == hasConductivityPassed ) - { - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - stateTimer = getMSTimerCount(); - stateTrialCounter = 0; - state = DG_HEAT_DISINFECT_STATE_FLUSH_CIRCULATION; - } - // If the number of failures have not exceeded the limit, try again. - else if ( stateTrialCounter < MAX_ALLOWED_STATE_TRIALS ) - { - stateTrialCounter++; - stateTimer = getMSTimerCount(); - } - // Couldn't get a good water sample after a couple of trials and the disinfect cycle failed - else - { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_INLET_COND_AND_TEMP_OUT; - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; - } + turnOnUVReactor( INLET_UV_REACTOR ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); + stateTimer = getMSTimerCount(); + stateTrialCounter = 0; + state = DG_HEAT_DISINFECT_STATE_FLUSH_CIRCULATION; } return state; @@ -652,19 +632,17 @@ { F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 TD1Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ); F32 TD2Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); - F32 avgTemp = ( ThdTemp + TPoTemp + TD1Temp + TD2Temp ) / NUM_OF_TEMP_SENSORS_TO_AVG; + F32 avgTemp = ( ThdTemp + TPoTemp + TD2Temp ) / NUM_OF_TEMP_SENSORS_TO_AVG; // Check if any of the temperature sensors deviate for more than the defined value from the average of all // of the temperature sensors BOOL isThdOut = ( fabs( ThdTemp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); BOOL isTPoOut = ( fabs( TPoTemp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); - BOOL isTD1Out = ( fabs( TD1Temp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); BOOL isTD2Out = ( fabs( TD2Temp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); // Check if any of the temperature sensors are out of tolerance - if ( ( TRUE == isThdOut ) || ( TRUE == isTPoOut ) || ( TRUE == isTD1Out ) || ( TRUE == isTD2Out ) ) + if ( ( TRUE == isThdOut ) || ( TRUE == isTPoOut ) || ( TRUE == isTD2Out ) ) { // Check if we have exceeded the number of trials. If not, try another time if ( ++stateTrialCounter < MAX_ALLOWED_STATE_TRIALS ) @@ -676,7 +654,7 @@ { alarmDetectedPendingTrigger = ALARM_ID_DG_TEMP_SENSORS_DIFF_OUT_OF_RANGE; prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } } else @@ -696,7 +674,7 @@ // Only start the concentrate pumps if the temperature sensors are in range if ( TRUE == areTempSensorsInRange ) { - if ( TRUE == didTimeout( concentratePumpsPrimeTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) ) + if ( TRUE == didTimeout( concentratePumpsPrimeTimer, FLUSH_CIRCULATION_CONC_PUMPS_WAIT_TIME_MS ) ) { rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; @@ -822,7 +800,7 @@ else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } // First reservoir 2 must be completely full @@ -856,7 +834,7 @@ // Done with filing turn off the RO pump signalROPumpHardStop(); stopHeater( DG_PRIMARY_HEATER ); - + turnOffUVReactor( INLET_UV_REACTOR ); // Set the valves to drain R2 and no fill setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); @@ -916,7 +894,7 @@ else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -956,7 +934,7 @@ setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_OPEN ); - + turnOnUVReactor( INLET_UV_REACTOR ); // Turn on the RO pump setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); @@ -972,7 +950,7 @@ else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -1012,6 +990,7 @@ // Once reservoir 2 is full, set the actuators for recirculation if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { + turnOffUVReactor( INLET_UV_REACTOR ); // Set the valves to drain R2 and no fill setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VBF, VALVE_STATE_OPEN ); @@ -1259,12 +1238,10 @@ setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setROPumpTargetFlowRateLPM( ROF_COOL_DOWN_TARGET_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); ROFCoolingTimer = 0; @@ -1583,7 +1560,13 @@ *************************************************************************/ static void failHeatDisinfect( void ) { - SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevHeatDisinfectState ) + // In the cleaning modes the alarms are triggered but the mode is not transitioned to fault automatically + // so transition to fault mode is done here + if ( alarmDetectedPendingTrigger != ALARM_ID_NO_ALARM ) + { + SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevHeatDisinfectState ) + } + requestNewOperationMode( DG_MODE_FAUL ); } /*********************************************************************//** @@ -1695,10 +1678,10 @@ else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to drain on time. Update the previous heat disinfect state and transition to basic cancellation - prevHeatDisinfectState = heatDisinfectState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - haveDrainParamsBeenInit[ r ] = FALSE; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevHeatDisinfectState = heatDisinfectState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + haveDrainParamsBeenInit[ r ] = FALSE; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -1806,12 +1789,6 @@ heatDisinfectTimer = getMSTimerCount(); isPartialDisinfectInProgress = TRUE; targetDisinfectTime = HEAT_DISINFECT_TIME_MS; - status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; - - // The temperature of the coldest spot is in range to start the disinfect timer - heatDisinfectTimer = getMSTimerCount(); - isPartialDisinfectInProgress = TRUE; - targetDisinfectTime = HEAT_DISINFECT_TIME_MS; status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; // Turn the pumps on in reverse @@ -1906,6 +1883,8 @@ *************************************************************************/ static void monitorModeHeatDisinfect( void ) { + BOOL areInletWaterAlarmsActive = FALSE; + #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -1920,6 +1899,19 @@ alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; } } + + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_LOW ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW ); + + if ( ( TRUE == areInletWaterAlarmsActive ) ) + { + prevHeatDisinfectState = heatDisinfectState; + heatDisinfectState = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } } /*********************************************************************//**