Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r3fa3bf8d5bf51649dd00756484344daa7dbf6e73 -re3a42336d697af9e7a5c980db0456e72bc949c31 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 3fa3bf8d5bf51649dd00756484344daa7dbf6e73) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision e3a42336d697af9e7a5c980db0456e72bc949c31) @@ -107,8 +107,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_MAX_TIME_MS ( 1.5 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down maximum state time 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 ( 4 * 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 @@ -206,15 +206,8 @@ static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ); static void publishHeatDisinfectData( void ); static void monitorModeHeatDisinfect( void ); +static void writeDisinfectDataToNV( void ); -//#define HELPER_FUNCTIONS -#ifdef HELPER_FUNCTIONS -static BOOL checkGradientOutOfRange(HEAT_DISINFECT_STATUS_T *status); -static BOOL checkResrvoirLoss(HEAT_DISINFECT_STATUS_T *tatus); -static BOOL checkHeatDisinfectTimeout(HEAT_DISINFECT_STATUS_T *status); -static BOOL checkHeatDisinfectComplete(HEAT_DISINFECT_STATUS_T *status); -#endif - /*********************************************************************//** * @brief * The initHeatDisinfectMode function initializes the heat disinfect mode @@ -1138,16 +1131,19 @@ // at inlet temperature > 45 C setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); - // Although there is fluid in both reservoirs, but they are set to empty + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( 9.0F ); + // 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(); // Reset the timer for the next disinfect state tempGradOutOfRangeTimer = 0; state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; - break; + break; + case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: default: heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER; @@ -1191,7 +1187,11 @@ // Get the current volumes to be monitored during R2 to R1 heat disinfect state R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI ); + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter // at inlet temperature > 45 C setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); @@ -1353,8 +1353,10 @@ } else if ( ( TRUE == didTimeout( stateTimer, ROF_COOL_DOWN_MAX_TIME_MS ) ) ) { - cancellationMode = CANCELLATION_MODE_NONE; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + prevHeatDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; // TODO - cool down alarm? + cancellationMode = CANCELLATION_MODE_HOT; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -1838,7 +1840,6 @@ return state; } - /*********************************************************************//** * @brief * The handleHeatDisinfectCompleteState function handles the @@ -1991,186 +1992,8 @@ return status; } -#ifdef HELPER_FUNCTIONS /*********************************************************************//** * @brief - * The checkGradientOutOfRange function checks to ensure that the - * temperature gradient between TPo and THd does not exceed the specified - * gradient. If the heat disinfect status is changed, return true and - * update the status parameter. - * @details Inputs: none - * @details Outputs: alarmDetectedPendingTrigger - * @param *HEAT_DISINFECT_STATUS_T status - * @return Return true if status is updated, else false - *************************************************************************/ -static BOOL checkGradientOutOfRange(HEAT_DISINFECT_STATUS_T *status) -{ - BOOL returnVal = FALSE; - - F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); - - // 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 - bool gradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) ? TRUE : FALSE; - if ( !gradientOutOfRange ) - { - tempGradOutOfRangeTimer = 0; - } - else if ( 0 == tempGradOutOfRangeTimer ) - { - tempGradOutOfRangeTimer = getMSTimerCount(); - } - else if ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) - { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; - *status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; - returnVal = TRUE; - } - - return returnVal; - -} - -/*********************************************************************//** - * @brief - * The checkResrvoirLoss function checks to see if any loss of volume has - * occurred in either reservoir. - * @details Inputs: none - * @details Outputs: alarmDetectedPendingTrigger, areRsrvrsLeaking - * @param *HEAT_DISINFECT_STATUS_T status - * @return Return true if status is updated, else false - *************************************************************************/ -static BOOL checkResrvoirLoss(HEAT_DISINFECT_STATUS_T *status) -{ - BOOL returnVal = FALSE; - 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 either reservoir 1 or reservoir 2 are losing volume more than allowed volume - if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) - { - // If the leak is the first time after a while, set the flag and start the timer - if ( FALSE == areRsrvrsLeaking ) - { - areRsrvrsLeaking = TRUE; - rsrvrsVolMonitorTimer = getMSTimerCount(); - } - // If the volume is out of range and it has timed out, exit - else if ( TRUE == didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) ) - { - areRsrvrsLeaking = FALSE; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; - *status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; - returnVal = TRUE; - } - } - // Reservoirs are in range - else - { - areRsrvrsLeaking = FALSE; - } - - return returnVal; - -} - -/*********************************************************************//** - * @brief - * The checkHeatDisinfectTimeout function checks to see if the heat - * disinfect process has timed out. - * @details Inputs: none - * @details Outputs: isPartialDisinfectInProgress, heatDisinfectTimer, - * isPartialDisinfectInProgress, targetDisinfectTime, - * alarmDetectedPendingTrigger - * @param *HEAT_DISINFECT_STATUS_T status - * @return Return true if status is updated, else false - *************************************************************************/ -static BOOL checkHeatDisinfectTimeout(HEAT_DISINFECT_STATUS_T *status) -{ - BOOL returnVal = FALSE; - - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); - - // If the coldest spot which is THd is less than minimum heat disinfect temperature, - // reset the heat disinfect timers and check whether heating up has timed out - if ( ThdTemp < HEAT_DISINFECT_START_TEMPERATURE_C ) - { - // Keep reseting the disinfect timer so the elapsed time is always 0 until disinfect truly starts - heatDisinfectTimer = getMSTimerCount(); - isPartialDisinfectInProgress = FALSE; - targetDisinfectTime = 0; - - if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMOUT_MS ) ) - { - // Heating up to minimum temperature for heat disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; - *status = HEAT_DISINFECT_HEAT_UP_TIMEOUT; - returnVal = TRUE; - } - } - else if ( ( isPartialDisinfectInProgress != TRUE ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) ) - { - // 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; - returnVal = TRUE; - - // In disinfect R1 to R2, concentrate pumps are also run - if ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState ) - { - // Turn the pumps on in reverse - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); - - // During R1 to R2 disinfect, the concentrate pumps turn on - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - } - } - else if ( ( TRUE == isPartialDisinfectInProgress ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) ) - { - *status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; - returnVal = TRUE; - } - - return returnVal; - -} - -/*********************************************************************//** - * @brief - * The checkHeatDisinfectComplete function checks if the heat disinfect - * process is complete. - * @details Inputs: none - * @details Outputs: targetDisinfectTime, isPartialDisinfectInProgress - * @param *HEAT_DISINFECT_STATUS_T status - * @return Return true if status is updated, else false - *************************************************************************/ -static BOOL checkHeatDisinfectComplete(HEAT_DISINFECT_STATUS_T *status) -{ - BOOL returnVal = FALSE; - - // If heat disinfect temperature has been reached, check if this stage of heat disinfect is done - if ( ( TRUE == isPartialDisinfectInProgress ) && ( TRUE == didTimeout( heatDisinfectTimer, HEAT_DISINFECT_TIME_MS ) ) ) - { - // Done with this stage of heat disnfect. Reset the variables - // Target disinfect time is the time that is published to the UI and when there is - // no disinfect count down, this variable is set to 0. When the target time is 0, the UI - // hides the timer on the UI disinfect screen - targetDisinfectTime = 0; - *status = HEAT_DISINFECT_COMPLETE; - isPartialDisinfectInProgress = FALSE; - returnVal = TRUE; - } - - return returnVal; -} -#endif -/*********************************************************************//** - * @brief * The getHeatDisinfectStatus function monitors and returns the current * stage of heat disinfect cycle. If the level of the reservoirs is drifted * consecutively for the define period of time, it sets the reservoir leak @@ -2186,29 +2009,12 @@ { 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 ); 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; -// checkGradientOutOfRange // 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 bool gradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) ? TRUE : FALSE; @@ -2222,10 +2028,9 @@ } else if ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; } -// End checkGradientOutOfRange if ( ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( 0 == tempGradOutOfRangeTimer ) ) { @@ -2234,12 +2039,10 @@ else if ( ( fabs( 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; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; } -// End checkGradientOutOfRange - // checkResrovoirLoss // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { @@ -2262,9 +2065,7 @@ { areRsrvrsLeaking = FALSE; } -// End checkResrvoiLoss -// checkHeatDisinfectTimeout // If the coldest spot which is THd is less than minimum heat disinfect temperature, // reset the heat disinfect timers and check whether heating up has timed out if ( ThdTemp < HEAT_DISINFECT_START_TEMPERATURE_C ) @@ -2305,9 +2106,7 @@ { status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; } -// End checkHeatdisinfecTimeout -// checkHeatDisinfectComplete // If heat disinfect temperature has been reached, check if this stage of heat disinfect is done if ( ( TRUE == isPartialDisinfectInProgress ) && ( TRUE == didTimeout( heatDisinfectTimer, HEAT_DISINFECT_TIME_MS ) ) ) { @@ -2322,8 +2121,6 @@ return status; -// End CheckHeatDisinfectComplete -#endif } /*********************************************************************//**