Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -re056d7264626adbe83149a51dcca723d8feb98bf -r1c4e4a00190abdfa7da30e184ba00e1a92009a71 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision e056d7264626adbe83149a51dcca723d8feb98bf) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 1c4e4a00190abdfa7da30e184ba00e1a92009a71) @@ -159,7 +159,6 @@ static BOOL areTempSensorsInRange = FALSE; ///< Heat disinfect temperature sensors in/out range flag. static U32 concentratePumpsPrimeTimer = 0; ///< Concentrate pumps prime timer. /// Boolean flag to check whether draining R1 and R2 is at the end of the heat disinfect cycle or in the beginning. So the drain states can be reused. -static BOOL isThisLastDrain = FALSE; static DG_RESERVOIR_STATUS_T rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 1 status. static DG_RESERVOIR_STATUS_T rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 2 status. static F32 R1HeatDisinfectVol = 0.0; ///< Reservoir 1 full volume during heat disinfect. @@ -198,11 +197,6 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR2State( void ); -#if 0 //wjb -static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR1ToR2State( void ); -static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR2ToR1AndDrainR1State( void ); -static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseCirculationState( void ); -#endif static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeBasicPathState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPathState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCompleteState( void ); @@ -220,7 +214,7 @@ * The initHeatDisinfectMode function initializes the heat disinfect mode * module. * @details Inputs: none - * @details Outputs: heatDisinfectState, stateTimer, isThisLastDrain, + * @details Outputs: heatDisinfectState, stateTimer, * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, * R1HeatDisinfectVol, R2HeatDisinfectVol, overallHeatDisinfectTimer, * cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState @@ -236,7 +230,6 @@ 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; @@ -359,20 +352,7 @@ heatDisinfectState = handleHeatDisinfectMixDrainR2State(); break; -#if 0 //wjb - case DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2: - heatDisinfectState = handleHeatDisinfectRinseR1ToR2State(); - 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; -#endif - case DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH: + case DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH: heatDisinfectState = handleHeatDisinfectCancelModeBasicPathState(); break; @@ -498,7 +478,7 @@ * drain R1 state. The state drains reservoir 1. If the transition is * finished within the time, it transitions to the next state, otherwise, * it transitions to basic cancellation path. - * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status, isThisLastDrain + * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status * @return next state of the heat disinfect state machine *************************************************************************/ @@ -512,43 +492,19 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { - if ( TRUE == isThisLastDrain ) - { - // Done with draining - signalDrainPumpHardStop(); + tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); - // Set the valves to flush the recirculation line - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + // Assume reservoir 2 is full and drain it + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - // TODO turn on the concentrate pumps + // Done with draining R1, close it + setValveState( VRD1, VALVE_STATE_CLOSED ); + // Set the actuators to drain R2. + // NOTE: Drain pump is already on and VDr is already on drain state + setValveState( VRD2, VALVE_STATE_OPEN ); + state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; - // Set the RO pump to run at full pressure - setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - - // Done with final draining - isThisLastDrain = FALSE; - state = DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION; - } - else - { - tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); - tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); - - // Assume reservoir 2 is full and drain it - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - - // Done with draining R1, close it - setValveState( VRD1, VALVE_STATE_CLOSED ); - // Set the actuators to drain R2. - // NOTE: Drain pump is already on and VDr is already on drain state - setValveState( VRD2, VALVE_STATE_OPEN ); - state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; - } - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); // Start the timer @@ -569,7 +525,7 @@ * drain R2 state. The state drains reservoir 2. If the transition is * finished within the time, it transitions to the next state, otherwise, * it transitions to basic cancellation path. - * @details Inputs: stateTimer, rsrvr2Status, isThisLastDrain, + * @details Inputs: stateTimer, rsrvr2Status * stateTrialCounter * @details Outputs: stateTimer, rsrvr2Status, stateTrialCounter * @return next state of the heat disinfect state machine @@ -584,27 +540,18 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { - if ( TRUE == isThisLastDrain ) - { - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VRD2, VALVE_STATE_CLOSED ); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - state = DG_HEAT_DISINFECT_STATE_DRAIN_R1; - } - else - { - tareLoadCell( LOAD_CELL_RESERVOIR_2_PRIMARY ); - tareLoadCell( LOAD_CELL_RESERVOIR_2_BACKUP ); + tareLoadCell( LOAD_CELL_RESERVOIR_2_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_2_BACKUP ); - signalDrainPumpHardStop(); + signalDrainPumpHardStop(); - // Done with draining R2, close it - setValveState( VRD2, VALVE_STATE_CLOSED ); - setValveState( VPI, VALVE_STATE_OPEN ); - stateTrialCounter = 0; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_FLUSH_DRAIN; - } + // Done with draining R2, close it + setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VPI, VALVE_STATE_OPEN ); + stateTrialCounter = 0; + 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 ) @@ -1446,29 +1393,6 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { -#if 0 //wjb - // Done with draining the reservoirs - signalDrainPumpHardStop(); - - // Set the valves to fill up R1 and overflow to R2 - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - // Done with draining reservoir 2 - setValveState( VRD2, VALVE_STATE_CLOSED ); - 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 ); - setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2; -#endif state = DG_HEAT_DISINFECT_STATE_COMPLETE; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) @@ -1480,206 +1404,8 @@ return state; } -#if 0 //wjb /*********************************************************************//** * @brief - * The handleHeatDisinfectRinseR1ToR2State function handles the heat - * disinfect rinse R1 to R2 state. The state rinses reservoir 1 to reservoir - * 2. If the rinse process times out, it transitions to water cancellation - * state, otherwise, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status - * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status - * @return next state of the heat disinfect state machine - *************************************************************************/ -static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR1ToR2State( void ) -{ - DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2; - - if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) - { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - - // Keep monitoring the status of reservoir 2 at the same time - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); - // Reservoir 2 cannot be filled before reservoir 1 is filled and is overflowing to reservoir 2. If reservoir 2 has already - // reached to target volume, it means reservoir 1's load cell might be reading incorrect values. This situation might continue - // until reservoir 2 is filled up and the tubing might expand or leak. - if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) - { - prevHeatDisinfectState = state; - alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); - - if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) - { - // Set the valves to rinse R2 to R1 and drain R1 - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1; - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) - { - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - - return state; -} -#endif - -#if 0 //wjb -/*********************************************************************//** - * @brief - * The handleHeatDisinfectRinseR2ToR1AndDrainR1State function handles the - * heat disinfect rinse R2 to R1 and drain R1 state. The state rinses - * reservoir 2 and drains reservoir 1 at the same time. If the drain - * process times out, it transitions to basic cancellation state, and - * if the rinse times out, it transitions to water cancellation state. - * If the drain and rinse are completed within the define time, it - * transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status, isThisLastDrain - * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, 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 ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) - { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ); - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - // Done with draining R1 - signalDrainPumpHardStop(); - setValveState( VRD1, VALVE_STATE_CLOSED ); - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; - } - - // First reservoir 2 must be completely full - if ( DG_RESERVOIR_BELOW_TARGET == rsrvr2Status ) - { - // Keep monitoring the status of reservoir 1 as the same time - F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - - U32 drainPumpRPM = getDrainPumpTargetRPM(); - - // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already - // reached to target volume, it means reservoir 2's load cell might be reading incorrect values. This situation might continue - // 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 ) ) - { - prevHeatDisinfectState = state; - alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - // Once reservoir 2 is completely full, monitor reservoir 1 - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) - { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); - - if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - // Done with filling, turn off the RO pump - signalROPumpHardStop(); - - // 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( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRD2, VALVE_STATE_OPEN ); - 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 ); - - // Turn the pumps on in reverse - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, ACID_PUMP_SPEED_ML_PER_MIN ); - - // Turn on the concentrate pumps - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - - // This is the last drain of heat disinfect cycle - isThisLastDrain = TRUE; - stateTimer = getMSTimerCount(); - // Set the reservoir status - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - state = DG_HEAT_DISINFECT_STATE_DRAIN_R2; - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) - { - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - } - - return state; -} -#endif - -#if 0 //wjb -/*********************************************************************//** - * @brief - * The handleHeatDisinfectRinseCirculationState function handles the - * heat disinfect rinse RO circulation and concentrate pumps state. Once - * the defined flush circulation time has elapsed, it transitions to the next - * 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 ( TRUE == didTimeout( stateTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) ) - { - state = DG_HEAT_DISINFECT_STATE_COMPLETE; - } - - return state; -} -#endif - -/*********************************************************************//** - * @brief * The handleHeatDisinfectCancelModeBasicPathState function handles the * heat disinfect cancel mode basic path state. The state sets the state * to complete and raises an alarm. @@ -2069,10 +1795,6 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); } } -//wjb else if ( ( TRUE == isPartialDisinfectInProgress ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) ) -//wjb { -//wjb status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; -//wjb } // 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 ) ) )