Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r35d635b442da3d931c1016ae4d23ead116d214f3 -rdf52e97b57868e3c2e0fb3f3dfa4c155514821be --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 35d635b442da3d931c1016ae4d23ead116d214f3) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision df52e97b57868e3c2e0fb3f3dfa4c155514821be) @@ -91,7 +91,7 @@ // R1 to R2 & R2 to R1 heat disinfect circulation #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F ///< Heat disinfect target RO flow rate in L/min. -#define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. +#define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 40 ///< Heat disinfect maximum RO pressure in psi. #define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0F ///< Heat disinfect target drain outlet pressure in psi. #define HEAT_DISINFECT_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. #define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. @@ -104,7 +104,8 @@ // Cool down RO filter #define THD_REACH_BELOW_45_AFTER_CIRC_TIME_MS ( 5 * MS_PER_SECOND ) ///< Number of circulations that are needed to make the RO filter is below 45 C. #define ROF_COOL_DOWN_TARGET_FLOW_LPM 0.3F ///< RO filter cool down target flow in L/min. -#define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down circulation timer in milliseconds. +#define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down circulation timer in milliseconds. +#define ROF_COOL_DOWN_MAX_TIME_MS ( 1.5 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down maximum state time in milliseconds. #define TARGET_THD_SENSOR_FOR_RINSING_C 44.0F ///< Target THd temperature sensor value before rinsing in C. // Mix drain R1 and R2 @@ -165,7 +166,6 @@ static U32 rsrvrFillStableTimeCounter; ///< Reservoirs fill stable time counter. static ALARM_ID_T alarmDetectedPendingTrigger; ///< Heat disinfect alarm to raise. static BOOL isDrainPumpInMixDrainOn = FALSE; ///< Flag to indicate the drain pump is on during mix drain. -static U32 ROFCirculationTimer = 0; ///< RO filter circulation timer. static U32 ROFCoolingTimer = 0; ///< RO filter cooling timer. static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated. static U32 targetDisinfectTime = 0; ///< Target disinfect time. @@ -220,8 +220,8 @@ * R1HeatDisinfectVol, R2HeatDisinfectVol, overallHeatDisinfectTimer, * cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, - * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime - * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer, + * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime, + * concentratePumpsPrimeTimer, * haveDrainParamsBeenInit, tempGradOutOfRangeTimer * @return none *************************************************************************/ @@ -243,7 +243,6 @@ rsrvrFillStableTimeCounter = 0; isPartialDisinfectInProgress = FALSE; isDrainPumpInMixDrainOn = FALSE; - ROFCirculationTimer = 0; ROFCoolingTimer = 0; hasROFCirculationBeenStarted = FALSE; concentratePumpsPrimeTimer = 0; @@ -1254,7 +1253,7 @@ * disinfect cool down heaters state. The state continues running the fluid * while the heaters are off for a certain period of time. * @details Inputs: stateTimer - * @details Outputs: stateTimer + * @details Outputs: stateTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownHeatersState( void ) @@ -1272,17 +1271,21 @@ // De-energize all the valves that are not in the path anymore // and wait for the RO membrane to be cooled down. - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); - ROFCoolingTimer = getMSTimerCount(); - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + 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; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + } return state; @@ -1293,23 +1296,58 @@ * The handleHeatDisinfectCoolDownROFilterState function handles the heat * disinfect cool down RO filter state. The state monitors the temperature * at THd and if it is less than 45 C, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter - * @details Outputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter + * @details Inputs: stateTimer, ROFCoolingTimer + * @details Outputs: stateTimer, ROFcoolingTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + // THd is the closet sensor to the RO filter and this temperature is monitored + // until it is dropped below 45 C to be able to run fluid through the RO filter + F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; - // THd is the closet sensor to the RO filter and this temperature is monitored - // until it is dropped below 45 C to be able to run fluid through the RO filter - F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + if ( ( 0 == ROFCoolingTimer ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) + { + // Temperature is below target - perform mandatory cool down + ROFCoolingTimer = getMSTimerCount(); + } + else if ( THdTemp >= TARGET_THD_SENSOR_FOR_RINSING_C ) + { + // Temperature is not below target - reset the timer and keep looking + ROFCoolingTimer = 0; + } + if ( ( 0 != ROFCoolingTimer ) && ( TRUE == didTimeout( ROFCoolingTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) + { + // Temperature is below target, transition to next state + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + + signalROPumpHardStop(); + + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; + } + else if ( ( TRUE == didTimeout( stateTimer, ROF_COOL_DOWN_MAX_TIME_MS ) ) ) + { + cancellationMode = CANCELLATION_MODE_NONE; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } + + return state; + +#if 0 // Check if the coldest spot temperature is less than 45 C so the RO filter can safely run if ( ( FALSE == isROPumpRunning() ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) { @@ -1353,8 +1391,8 @@ ROFCoolingTimer = getMSTimerCount(); signalROPumpHardStop(); } - return state; +#endif } /*********************************************************************//** @@ -1775,16 +1813,15 @@ failHeatDisinfect(); } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VRD2, VALVE_STATE_CLOSED ); - signalDrainPumpHardStop(); - - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; - } } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) + { + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + prevHeatDisinfectState = state; + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + } return state; } @@ -1940,7 +1977,8 @@ return status; } -#if 0 +#define HELPER_FUNCTIONS +#ifdef HELPER_FUNCTIONS static BOOL checkGradientOutOfRange(HEAT_DISINFECT_STATUS_T *status) { BOOL returnVal = FALSE; @@ -2095,6 +2133,22 @@ { HEAT_DISINFECT_STATUS_T status = HEAT_DISINFECT_HEAT_UP_IN_PROGRESS; +#ifdef HELPER_FUNCTIONS + + // Each of the check... functions below will return TRUE if their processing + // sets the status value. In essence these checks are in priority order. + // As soon as any function changes the status, no further processing is + // required. + //\// NOTE: Do not change the order of the execution of the functions. + if ( TRUE == checkHeatDisinfectComplete( &status ) ) {} + else if ( TRUE == checkGradientOutOfRange( &status ) ) {} + else if ( TRUE == checkResrvoirLoss( &status ) ) {} + else if ( TRUE == checkHeatDisinfectTimeout( &status ) ) {} + + return status; + +#else + F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); @@ -2207,6 +2261,7 @@ return status; +#endif } /*********************************************************************//** @@ -2219,7 +2274,7 @@ *************************************************************************/ static void publishHeatDisinfectData( void ) { - if ( ++dataPublishCounter > HEAT_DISINFECT_DATA_PUB_INTERVAL ) + if ( ++dataPublishCounter >= HEAT_DISINFECT_DATA_PUB_INTERVAL ) { MODE_HEAT_DISINFECT_DATA_T data; MODE_HEAT_DISINFECT_UI_DATA_T uiData;