Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rb0a5452ec4b9be9be937095b1249079a2fce5ce5 -ra727129f5f547fc7a46f481417f7b926454d3e97 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision b0a5452ec4b9be9be937095b1249079a2fce5ce5) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision a727129f5f547fc7a46f481417f7b926454d3e97) @@ -77,7 +77,7 @@ #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6F ///< Bicarb concentrate pump speed in mL/min. // Flush and drain R1 and R2 -#define RSRVRS_FULL_VOL_ML 1750.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 +#define RSRVRS_FULL_VOL_ML 1850.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0F ///< Reservoirs 1 & 2 partial volume in mL. #define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts. #define RSRVRS_FILL_UP_TIMEOUT_MS ( 8 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. TODO original value was 5 mins @@ -89,14 +89,16 @@ #define HEAT_DISINFECT_START_TEMPERATURE_C 81.0F ///< Heat disinfect minimum acceptable temperature in C. // R1 to R2 & R2 to R1 heat disinfect circulation -#define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F // TODO this was 1.3 ///< Heat disinfect target RO flow rate in L/min. -#define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 // TODO this was 30 ///< Heat disinfect maximum RO pressure in psi. -#define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0F // TODO was 12 ///< Heat disinfect target drain outlet pressure in psi. +#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_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. #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5F * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. TODO change this to 5 seconds #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 150.0F ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. +#define HEAT_DISINFECT_MAX_TEMP_GRADIENT_C 15.0F ///< Heat disinfect maximum allowed temperature gradient in between hottest and coldest sensors. +#define HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ( 0.16 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect temperature gradient out of range timeout in milliseconds. // 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. @@ -132,6 +134,7 @@ HEAT_DISINFECT_DISINFECT_IN_PROGRESS, ///< Heat disinfect disinfect in progress. HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT, ///< Heat disinfect reservoirs leak timeout. HEAT_DISINFECT_HEAT_UP_TIMEOUT, ///< Heat disinfect heat up timeout. + HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE, ///< Heat disinfect temperature gradient out of range. HEAT_DISINFECT_COMPLETE, ///< Heat disinfect complete. NUM_OF_HEAT_DISINFECT_STATUS ///< Number of heat disinfect status. } HEAT_DISINFECT_STATUS_T; @@ -166,6 +169,7 @@ static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated. static U32 targetDisinfectTime = 0; ///< Target disinfect time. static BOOL haveDrainParamsBeenInit; ///< Boolean flag to indicate whether the drain parameters have been reset or not. +static U32 tempGradOutOfRangeTimer; ///< Temperature gradient out of range start timer. // ********** private function prototypes ********** @@ -212,7 +216,7 @@ * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer, - * haveDrainParamsBeenInit + * haveDrainParamsBeenInit, tempGradOutOfRangeTimer * @return none *************************************************************************/ void initHeatDisinfectMode( void ) @@ -239,6 +243,7 @@ concentratePumpsPrimeTimer = 0; targetDisinfectTime = 0; haveDrainParamsBeenInit = FALSE; + tempGradOutOfRangeTimer = 0; } /*********************************************************************//** @@ -1085,7 +1090,7 @@ * If heat disinfect reservoir 1 to reservoir 2 is completed, it transitions * to the next state. * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status - * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status + * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, tempGradOutOfRangeTimer * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR1ToR2State( void ) @@ -1100,6 +1105,10 @@ state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; break; + case HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE: + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + break; + case HEAT_DISINFECT_DISINFECT_IN_PROGRESS: heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_1; break; @@ -1116,11 +1125,12 @@ setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); // Although there is fluid in both reservoirs, but they are set to empty // to begin the transition of hot water from R1 to R2. - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; - stateTimer = getMSTimerCount(); - - state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; + rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; + stateTimer = getMSTimerCount(); + // Reset the timer for the next disinfect state + tempGradOutOfRangeTimer = 0; + state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; break; case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: @@ -1199,7 +1209,7 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; HEAT_DISINFECT_STATUS_T status = getHeatDisinfectStatus(); - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2; switch ( status ) { @@ -1208,6 +1218,10 @@ state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; break; + case HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE: + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + break; + case HEAT_DISINFECT_COMPLETE: // Turn off the heaters stopHeater( DG_PRIMARY_HEATER ); @@ -1925,6 +1939,19 @@ BOOL isR1OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; BOOL isR2OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; + // Check if the temperature gradient in between the coldest and the hottest spot is more than the specified temperature and + // the timer has not started yet, start it + if ( ( TPoTemp - ThdTemp > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( 0 == tempGradOutOfRangeTimer ) ) + { + tempGradOutOfRangeTimer = getMSTimerCount(); + } + else if ( ( TPoTemp - ThdTemp > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && + ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) ) + { + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE; + status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; + } + // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { @@ -1939,7 +1966,7 @@ { areRsrvrsLeaking = FALSE; alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; - status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; + status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; } } // Reservoirs are in range @@ -1961,7 +1988,7 @@ { // Heating up to minimum temperature for heat disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; - status = HEAT_DISINFECT_HEAT_UP_TIMEOUT; + status = HEAT_DISINFECT_HEAT_UP_TIMEOUT; } } else if ( ( isPartialDisinfectInProgress != TRUE ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) )