Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rf91baac9704a90ab0fea1dd05e11833ffc5a5a4e -r9c8b132dfff7ad0ef4973698e14d673b9d72a92b --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision f91baac9704a90ab0fea1dd05e11833ffc5a5a4e) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 9c8b132dfff7ad0ef4973698e14d673b9d72a92b) @@ -7,8 +7,8 @@ * * @file ModeHeatDisinfect.c * -* @author (last) Dara Navaei -* @date (last) 23-May-2022 +* @author (last) Bill Bracken +* @date (last) 22-Aug-2022 * * @author (original) Sean * @date (original) 20-Apr-2020 @@ -38,6 +38,7 @@ #include "Timers.h" #include "UVReactors.h" #include "Valves.h" +#include "CPLD.h" /** * @addtogroup DGHeatDisinfectMode @@ -161,14 +162,14 @@ static BOOL areRsrvrsLeaking = FALSE; ///< Reservoir 1 & 2 leak check flag during heat disinfect. static U32 dataPublishCounter = 0; ///< Heat Disinfect data publish counter. static CANCELLATION_MODE_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. -static U32 rsrvrFillStableTimeCounter = 0; ///< Reservoirs fill stable time counter. +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. -static BOOL haveDrainParamsBeenInit; ///< Boolean flag to indicate whether the drain parameters have been reset or not. +static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< 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 ********** @@ -221,29 +222,30 @@ *************************************************************************/ void initHeatDisinfectMode( void ) { - heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; - stateTimer = 0; - isThisLastDrain = FALSE; - stateTrialCounter = 0; - areTempSensorsInRange = FALSE; - rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; - rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - R1HeatDisinfectVol = 0.0; - R2HeatDisinfectVol = 0.0; - overallHeatDisinfectTimer = 0; - cancellationMode = CANCELLATION_MODE_NONE; - rsrvrFillStableTimeCounter = 0; - isPartialDisinfectInProgress = FALSE; - isDrainPumpInMixDrainOn = FALSE; - ROFCirculationTimer = 0; - ROFCoolingTimer = 0; - hasROFCirculationBeenStarted = FALSE; - concentratePumpsPrimeTimer = 0; - targetDisinfectTime = 0; - haveDrainParamsBeenInit = FALSE; - tempGradOutOfRangeTimer = 0; + heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; + stateTimer = 0; + isThisLastDrain = FALSE; + stateTrialCounter = 0; + areTempSensorsInRange = FALSE; + rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; + rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; + R1HeatDisinfectVol = 0.0; + R2HeatDisinfectVol = 0.0; + overallHeatDisinfectTimer = 0; + cancellationMode = CANCELLATION_MODE_NONE; + rsrvrFillStableTimeCounter = 0; + isPartialDisinfectInProgress = FALSE; + isDrainPumpInMixDrainOn = FALSE; + ROFCirculationTimer = 0; + ROFCoolingTimer = 0; + hasROFCirculationBeenStarted = FALSE; + concentratePumpsPrimeTimer = 0; + targetDisinfectTime = 0; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; + tempGradOutOfRangeTimer = 0; } /*********************************************************************//** @@ -260,6 +262,8 @@ initHeatDisinfectMode(); + setCPLDCleanLEDColor( CPLD_CLEAN_LED_ORANGE ); + return heatDisinfectState; } @@ -447,9 +451,9 @@ // Set all the actuators to reset and de-energized state deenergizeActuators(); - // If the inlet pressure is less than the threshold and TDi and TRo difference is greater than 3 C, the cycle + // If the inlet pressure is less than or equal to the threshold or TDi and TRo difference is greater than 3 C, the cycle // should be canceled - if ( ( ppiPressure < MIN_INLET_PRESSURE_PSI ) && ( fabs( TDiTemp - TRoTemp ) > MAX_START_STATE_TEMP_SENSORS_DIFF_C ) ) + if ( ( ppiPressure <= MIN_INLET_PRESSURE_PSI ) || ( fabs( TDiTemp - TRoTemp ) > MAX_START_STATE_TEMP_SENSORS_DIFF_C ) ) { prevHeatDisinfectState = state; alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_INLET_PRES_AND_TEMP_SNSRS_OUT; @@ -462,6 +466,7 @@ // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); // Set the actuators to drain R1 setValveState( VRD1, VALVE_STATE_OPEN ); @@ -505,7 +510,6 @@ setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); @@ -534,6 +538,8 @@ state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; } + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); + // Start the timer stateTimer = getMSTimerCount(); } @@ -588,6 +594,7 @@ stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_FLUSH_DRAIN; } + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { @@ -863,7 +870,7 @@ // until reservoir 1 is filled up and the tubing might expand or leak. // Before checking whether reservoir 1 is filled pre-maturely, we have to make sure reservoir 1 is drained completely to make // sure the extra volume that is read is not because of previous water that is being drained currently and it is above 500 mL - if ( ( volume > RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) + if ( ( volume >= RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) { prevHeatDisinfectState = state; alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; @@ -1224,7 +1231,7 @@ // Set the disinfect flags setDisinfectStatus( TRUE ); - setLastDisinfectDate( getRTCTimestamp() ); + setLastDisinfectDate( USAGE_INFO_HEAT_DISINFECT, getRTCTimestamp() ); break; case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: @@ -1561,7 +1568,7 @@ // until reservoir 1 is filled up and the tubing might expand or leak. // Before checking whether reservoir 1 is filled pre-maturely, we have to make sure reservoir 1 is drained completely to make // sure the extra volume that is read is not because of previous water that is being drained currently and it is above 500 mL - if ( ( volume > RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) + if ( ( volume >= RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) { prevHeatDisinfectState = state; alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; @@ -1581,7 +1588,7 @@ // De-energize all the valves and set the VDr to drain R2 setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD2, VALVE_STATE_OPEN ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); @@ -1846,18 +1853,18 @@ { if ( ++rsrvrFillStableTimeCounter >= RSRVRS_FULL_STABLE_TIME_COUNT ) { - status = DG_RESERVOIR_REACHED_TARGET; + status = DG_RESERVOIR_REACHED_TARGET; rsrvrFillStableTimeCounter = 0; // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); + stateTimer = getMSTimerCount(); } } else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to fill ontime. Update the previous heat disinfect state and transition to basic cancellation - prevHeatDisinfectState = heatDisinfectState; + prevHeatDisinfectState = heatDisinfectState; alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -1882,28 +1889,28 @@ DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; // If the drain parameters of the reservoir is not initialized, initialize them - if ( FALSE == haveDrainParamsBeenInit ) + if ( FALSE == haveDrainParamsBeenInit[ r ] ) { initDrainParameters( r ); - haveDrainParamsBeenInit = TRUE; + haveDrainParamsBeenInit[ r ] = TRUE; } BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); if ( TRUE == isDrainComplete ) { // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); - haveDrainParamsBeenInit = FALSE; - status = DG_RESERVOIR_REACHED_TARGET; + stateTimer = getMSTimerCount(); + haveDrainParamsBeenInit[ r ] = FALSE; + status = DG_RESERVOIR_REACHED_TARGET; } else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to drain on time. Update the previous heat disinfect state and transition to basic cancellation - prevHeatDisinfectState = heatDisinfectState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - haveDrainParamsBeenInit = FALSE; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevHeatDisinfectState = heatDisinfectState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + haveDrainParamsBeenInit[ r ] = FALSE; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -2034,7 +2041,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;