Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r4fbaa823eb08d369ea24d4ce59e77b6f2ad8e97a -r12ccb89bb747b00db71fff51238a245855c5d913 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 4fbaa823eb08d369ea24d4ce59e77b6f2ad8e97a) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 12ccb89bb747b00db71fff51238a245855c5d913) @@ -27,6 +27,7 @@ #include "Heaters.h" #include "MessageSupport.h" #include "ModeFill.h" +#include "ModeHeatDisinfect.h" #include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" @@ -51,6 +52,7 @@ #define HEATERS_MAX_DUTY_CYCLE 1.00F ///< Heaters max duty cycle (100%). #define HEATERS_MIN_DUTY_CYCLE 0.00F ///< Heaters minimum duty cycle (0.00%). #define HEATERS_DISINFECT_DUTY_CYCLE 0.80F ///< Heaters disinfect cycle. +#define HEATERS_DISINFECT_TRANSFER_DUTY_CYCLE 0.60F ///< Heaters disinfect transfer duty cycle. #define HEATERS_DISINFECT_TEMPERATURE_DRIFT_C 3.0F ///< Heaters disinfect temperature drift in C. #define HEATERS_MIN_EST_GAIN 0.2F ///< Heaters minimum estimation gain. #define HEATERS_MAX_EST_GAIN 5.0F ///< Heaters maximum estimation gain. @@ -618,28 +620,30 @@ F32 currentTemperature = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); F32 targetTemperature = heatersStatus[ heater ].targetTempC; - if ( currentTemperature < targetTemperature ) + if ( TRUE == isHeatDisinfectInTransitionHotWater() ) { + heatersStatus[ DG_TRIMMER_HEATER ].dutyCycle.data = HEATERS_DISINFECT_TRANSFER_DUTY_CYCLE; + heatersStatus[ DG_PRIMARY_HEATER ].dutyCycle.data = HEATERS_DISINFECT_TRANSFER_DUTY_CYCLE; + } + else if ( currentTemperature < targetTemperature ) + { heatersStatus[ DG_TRIMMER_HEATER ].dutyCycle.data = HEATERS_MAX_DUTY_CYCLE; heatersStatus[ DG_PRIMARY_HEATER ].dutyCycle.data = HEATERS_MAX_DUTY_CYCLE; - setHeaterDutyCycle( DG_TRIMMER_HEATER ); - setHeaterDutyCycle( DG_PRIMARY_HEATER ); } else if ( currentTemperature - targetTemperature < HEATERS_DISINFECT_TEMPERATURE_DRIFT_C ) { heatersStatus[ DG_TRIMMER_HEATER ].dutyCycle.data = HEATERS_DISINFECT_DUTY_CYCLE; heatersStatus[ DG_PRIMARY_HEATER ].dutyCycle.data = HEATERS_DISINFECT_DUTY_CYCLE; - setHeaterDutyCycle( DG_TRIMMER_HEATER ); - setHeaterDutyCycle( DG_PRIMARY_HEATER ); } else { heatersStatus[ DG_TRIMMER_HEATER ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ DG_PRIMARY_HEATER ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; - setHeaterDutyCycle( DG_TRIMMER_HEATER ); - setHeaterDutyCycle( DG_PRIMARY_HEATER ); } + setHeaterDutyCycle( DG_TRIMMER_HEATER ); + setHeaterDutyCycle( DG_PRIMARY_HEATER ); + return state; } Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rd0536d759cb33f099357033c3429401ff1637d26 -r12ccb89bb747b00db71fff51238a245855c5d913 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision d0536d759cb33f099357033c3429401ff1637d26) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 12ccb89bb747b00db71fff51238a245855c5d913) @@ -106,6 +106,7 @@ #define HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Heat disinfect getting reference reservoirs value timeout in milliseconds. #define HEAT_DISINFECT_AT_82_C_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time at 82 C in milliseconds. #define HEAT_DISINFECT_AT_77_C_TIME_MS ( 32 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time at 77 C in milliseconds. +#define HEAT_DISINFECT_PREP_FOR_TRANSFER_TIME_MS ( 30 * MS_PER_SECOND ) ///< Heat disinfect prepare for transfer hot water time in milliseconds. // Mix drain R1 and R2 #define RSRVRS_MIX_DRAIN_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 mix drain timeout in ms. @@ -209,6 +210,7 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFlushDrainR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR1ToR2State( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectPrepareForHotWaterTransitionState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillR2WithHotWaterState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR2ToR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownHeatersState( void ); @@ -329,6 +331,28 @@ /*********************************************************************//** * @brief + * The isHeatDisinfectInTransitionHotWater function returns the status of + * heat disinfect that whether it is in transition hot water water mode or + * not + * @details Inputs: heatDisinfectState + * @details Outputs: none + * @return TRUE if the mode is transfer hot water mode otherwise, FALSE + *************************************************************************/ +BOOL isHeatDisinfectInTransitionHotWater( void ) +{ + BOOL status = FALSE; + + if ( ( DG_HEAT_DISINFECT_STATE_PREPARE_FOR_HOT_WATER_TRANSITION == heatDisinfectState ) || + ( DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER == heatDisinfectState ) ) + { + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The execHeatDisinfectMode function executes the heat disinfect mode * state machine. * @details Inputs: heatDisinfectState @@ -396,6 +420,10 @@ heatDisinfectState = handleHeatDisinfectDisinfectR1ToR2State(); break; + case DG_HEAT_DISINFECT_STATE_PREPARE_FOR_HOT_WATER_TRANSITION: + heatDisinfectState = handleHeatDisinfectPrepareForHotWaterTransitionState(); + break; + case DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER: heatDisinfectState = handleHeatDisinfectFillR2WithHotWaterState(); break; @@ -1124,15 +1152,6 @@ case HEAT_DISINFECT_COMPLETE: requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - // Set the valves to transfer hot water from R1 to R2 and fill up R2. - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VRD2, VALVE_STATE_CLOSED ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - setDrainPumpTargetOutletFlowLPM( HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM ); - // Turn off trimmer heater for transition - stopHeater( DG_TRIMMER_HEATER ); // Although there is fluid in both reservoirs, but they are set to empty // to begin the transition of hot water from R1 to R2. @@ -1142,7 +1161,7 @@ rsrvr1RefVolML = 0.0F; rsrvr2RefVolML = 0.0F; tempGradOutOfRangeTimer = 0; - state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + state = DG_HEAT_DISINFECT_STATE_PREPARE_FOR_HOT_WATER_TRANSITION; timeStatus[ RSRVR_AT_77_C ].startTimeMS = 0; timeStatus[ RSRVR_AT_82_C ].startTimeMS = 0; break; @@ -1158,6 +1177,39 @@ /*********************************************************************//** * @brief + * The handleHeatDisinfectPrepareForHotWaterTransitionState function handles + * the heat disinfect prepare for hot water state. In this state, the fluid is + * run a certain period of time with the heaters are at a much lower duty cycle + * and then the actuators are set to transition the hot water to reservoir 2. + * @details Inputs: stateTimer + * @details Outputs: stateTimer + * @return next state of the heat disinfect state machine + *************************************************************************/ +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectPrepareForHotWaterTransitionState( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_PREPARE_FOR_HOT_WATER_TRANSITION; + + if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_PREP_FOR_TRANSFER_TIME_MS ) ) + { + // Set the valves to transfer hot water from R1 to R2 and fill up R2. + setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + setDrainPumpTargetOutletFlowLPM( HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM ); + // Turn off trimmer heater for transition + stopHeater( DG_TRIMMER_HEATER ); + + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleHeatDisinfectFillR2WithHotWaterState function handles fill R2 * with water state. The state transfers hot water from reservoir 1 to * reservoir 2 until hot water overflows from reservoir 2 to reservoir 1. Index: firmware/App/Modes/ModeHeatDisinfect.h =================================================================== diff -u -r56ba1b163b0cbf6953638065b2108f745b17ec8f -r12ccb89bb747b00db71fff51238a245855c5d913 --- firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision 56ba1b163b0cbf6953638065b2108f745b17ec8f) +++ firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision 12ccb89bb747b00db71fff51238a245855c5d913) @@ -45,6 +45,7 @@ void initHeatDisinfectMode( void ); // Initialize this module U32 transitionToHeatDisinfectMode( void ); // Prepares for transition to heat disinfect mode +BOOL isHeatDisinfectInTransitionHotWater( void ); U32 execHeatDisinfectMode( void ); // Execute the heat disinfect mode state machine (call from OperationModes) DG_HEAT_DISINFECT_STATE_T getCurrentHeatDisinfectState( void ); // get the current state of the heat disinfect mode