Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r4b7029ae5b0a163d7c54f26d57ad8f186b96c76f -r76105aa3acd8870d705ed4af84954b697477d6ef --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 4b7029ae5b0a163d7c54f26d57ad8f186b96c76f) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 76105aa3acd8870d705ed4af84954b697477d6ef) @@ -56,7 +56,7 @@ // Flush circulation path state defines #define RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM 0.8 ///< 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 circulation path wait time in milliseconds. +#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 3.0 ///< Maximum flush circulation temperature difference tolerance in C. // Flush and drain R1 and R2 @@ -79,6 +79,9 @@ #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 100.0 ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 1 * 60 * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. +// Rinse R1 to R2 +#define ROF_MIN_LOW_PRESSURE_TEMPERATURE_C 45.0 ///< RO filter minimum temperature that the pressure must be no more than 30psi in C. + /// Name of reservoirs typedef enum rsrvrs { @@ -99,6 +102,7 @@ // ********** private data ********** static DG_HEAT_DISINFECT_STATE_T heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Currently active heat disinfect state. +static U32 overallHeatDisinfectTimer = 0; ///< Heat disinfect cycle total timer. static U32 stateTimer = 0; ///< Heat disinfect state timer to be used in different states. static U32 stateTrialCounter = 0; ///< Heat disinfect state trial counter to be used for retries in different states. static BOOL areTempSensorsInRange = FALSE; ///< Heat disinfect temperature sensors in/out range flag. @@ -131,6 +135,9 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR2ToR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR2State( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR1ToR2( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR2ToR1AndDrainR1State( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseCirculationState( void ); static void resetActuators( void ); static void setModeToFailed( DG_HEAT_DISINFECT_STATE_T state ); @@ -244,18 +251,23 @@ break; case DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R2: + heatDisinfectState = handleHeatDisinfectMixDrainR2State(); break; case DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2: + heatDisinfectState = handleHeatDisinfectRinseR1ToR2(); break; case DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1: + heatDisinfectState = handleHeatDisinfectRinseR2ToR1AndDrainR1State(); break; case DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION: + heatDisinfectState = handleHeatDisinfectRinseCirculationState(); break; case DG_HEAT_DISINFECT_STATE_COMPLETE: + // Done with heat disinfect cycle, complete or not break; default: @@ -339,7 +351,7 @@ * @brief * The handleHeatDisinfectDrainR1State function handles the heat disinfect * drain R1 state. - * @details Inputs: stateTimer, isR1Full + * @details Inputs: stateTimer, isR1Full, isThisLastDrain * @details Outputs: stateTimer, isR1Full * @return next state of the heat disinfect state machine *************************************************************************/ @@ -351,11 +363,29 @@ { isR1Full = FALSE; - // Set the actuators to drain R2. - // NOTE: Drain pump is already on and VDr is already on drain state - setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; + if ( isThisLastDrain ) + { + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); + + //TODO turn on the concentrate pumps + + // TODO discuss the cooling process for proper flow rate and pressure set + setROPumpTargetFlowRate( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); + + // Done with final rinsing + isThisLastDrain = FALSE; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION; + } + else + { + // Set the actuators to drain R2. + // NOTE: Drain pump is already on and VDr is already on drain state + setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; + } } return state; @@ -365,7 +395,7 @@ * @brief * The handleHeatDisinfectDrainR2State function handles the heat disinfect * drain R2 state. - * @details Inputs: stateTimer, isR2Full + * @details Inputs: stateTimer, isR2Full, isThisLastDrain * @details Outputs: stateTimer, isR2Full * @return next state of the heat disinfect state machine *************************************************************************/ @@ -379,8 +409,8 @@ if ( isThisLastDrain ) { - //TODO set the rest of the actuators - state = DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION; + setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); + state = DG_HEAT_DISINFECT_STATE_DRAIN_R1; } else { @@ -832,6 +862,8 @@ if ( isRsrvrEmpty( R1, RSRVRS_DRAIN_TIMEOUT_MS, state ) ) { + isR1Full = FALSE; + // Set the drain valve to reservoir 2 setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); @@ -845,7 +877,7 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectMixDrainR2State function handles the heat - * disinfect mix drain R1 state. + * disinfect mix drain R2 state. * @details Inputs: stateTimer * @details Outputs: stateTimer * @return next state of the heat disinfect state machine @@ -856,9 +888,22 @@ if ( isRsrvrEmpty( R2, RSRVRS_DRAIN_TIMEOUT_MS, state ) ) { - // Set the drain valve to reservoir 2 - setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); + isR2Full = FALSE; + // Done with draining the reservoirs + signalDrainPumpHardStop(); + + // Set the valves to fill up R1 and overflow to R2 + // The RO pump is still running at low pressure until the coldest + // spot temperature is less than 45 C. + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); + stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2; } @@ -868,6 +913,127 @@ /*********************************************************************//** * @brief + * The handleHeatDisinfectRinseR1ToR2 function handles the heat + * disinfect rinse R1 to R2 state. + * @details Inputs: stateTimer, isR1Full, isR2Full + * @details Outputs: stateTimer, isR1Full, isR2Full + * @return next state of the heat disinfect state machine + *************************************************************************/ +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR1ToR2( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2; + + if ( FALSE == isR1Full ) + { + // Since reservoir 1 is being filled up at a lower flow rate, the timeout is twice as long as a normal fill up + isR1Full = isRsrvrFull( R1, RSRVRS_FULL_VOL_ML, 2 * RSRVRS_FILL_UP_TIMEOUT_MS, state ); + } + else + { + // Since reservoir 2 is being filled up at a lower flow rate, the timeout is longer than a normal fill up + isR2Full = isRsrvrFull( R2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, state ); + + if ( isR2Full ) + { + // Set the valves to rinses R2 to R1 and drain R1 + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleHeatDisinfectRinseR2ToR1AndDrainR1State function handles the + * heat disinfect rinse R2 to R1 and drain R1 state. + * @details Inputs: stateTimer, isR1Full, isR2Full, isThisLastDrain + * @details Outputs: stateTimer, isR1Full, isR2Full, isThisLastDrain + * @return next state of the heat disinfect state machine + *************************************************************************/ +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR2ToR1AndDrainR1State( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1; + + if ( isR1Full ) + { + // Since reservoir 1 is being filled up at a lower flow rate, the timeout is twice as long as a normal fill up + isR1Full = isRsrvrEmpty( R1, RSRVRS_DRAIN_TIMEOUT_MS, state ); + + // Done with draining R1 + signalDrainPumpHardStop(); + } + else if ( FALSE == isR1Full ) + { + if ( FALSE == isR2Full ) + { + isR2Full = isRsrvrFull( R2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, state ); + } + else + { + isR1Full = isRsrvrFull( R1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS, state ); + + if ( isR1Full ) + { + // Done with filling, turn off the RO pump + signalROPumpHardStop(); + + // Deenergize all the valves and set the VDr to drain R2 + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + + // Turn on the drain pump to drain R2 + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + + // This is the last drain of heat disinfect cycle + isThisLastDrain = TRUE; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; + } + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleHeatDisinfectRinseCirculationState function handles the + * heat disinfect rinse RO circulation and conectrate pumps state. + * @details Inputs: none + * @details Outputs: none + * @return next state of the heat disinfect state machine + *************************************************************************/ +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseCirculationState( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION; + + if ( didTimeout( stateTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) ) + { + // Done with heat disinfect cycle + resetActuators(); + + state = DG_HEAT_DISINFECT_STATE_COMPLETE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The resetActuators function sets all the actuators to reset and * deenergized state. * @details Inputs: none