Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r3fae8c2aab5873ccfaf8b7e1e4a2abf78216a7fd -rd8686d68bf29761ee329fc638264d2e60a5191c0 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 3fae8c2aab5873ccfaf8b7e1e4a2abf78216a7fd) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision d8686d68bf29761ee329fc638264d2e60a5191c0) @@ -31,6 +31,7 @@ #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" +#include "PIControllers.h" #include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -51,19 +52,18 @@ #define CHEM_DISINFECT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Mode chem disinfect data publish interval in counts. // Start state defines -#define MIN_INLET_PRESSURE_PSI 30.0F ///< Minimum water inlet pressure in psi. +#define MIN_INLET_PRESSURE_PSI 20.0F ///< Minimum water inlet pressure in psi. TODO: set to 30.0 // Drain R1 & R2 states defines #define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. -#define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines -#define FLUSH_DRAIN_WAIT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. -#define MIN_INLET_TEMPERATURE_C 24.0F ///< Minimum water inlet temperature in C. -#define MIN_INLET_TEMPERATURE_C 35.0F ///< Maximum water inlet temperature in C. +#define FLUSH_DRAIN_WAIT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. +#define MIN_INLET_TEMPERATURE_C 20.0F ///< Minimum water inlet temperature in C. TODO: set to 24.0 +#define MAX_INLET_TEMPERATURE_C 35.0F ///< Maximum water inlet temperature in C. #define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0F ///< Maximum water inlet conductivity in us/cm -#define MIN_INLET_CONDUCTIVITY_US_PER_CM 100.0F ///< Minimum water inlet conductivity in us/cm +#define MIN_INLET_CONDUCTIVITY_US_PER_CM 0.0F ///< Minimum water inlet conductivity in us/cm #define MAX_ALLOWED_FLUSH_DRAIN_PERIODS 2 ///< Number of flush drain periods to wait for inlet water to come into range #define INLET_WATER_CHECK_FAILURE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Timer for inlet water check failures before alarm // Flush circulation path state defines @@ -73,32 +73,47 @@ #define FLUSH_CICRCULATION_ADDITIONAL_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Flush/rinse circulation path additional wait time in milliseconds. #define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 3.0F ///< Maximum flush circulation temperature difference tolerance in C. #define NUM_OF_TEMP_SENSORS_TO_AVG 2.0F ///< Number of temperature sensors to average to check the difference. -#define MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM 100.0F ///< Maximum allowed conductivity in flush circulation state in us/cm +#define MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM 1000.0F ///< Maximum allowed conductivity in flush circulation state in us/cm TODO: set to 100.0 #define MAX_ALLOWED_FLUSH_CIRC_PERIODS 3 ///< Number of flush circulation periods to wait for sensors to come into range // Flush and drain R1 and R2 -#define RSRVRS_FULL_VOL_ML 1850.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 +#define RSRVRS_FULL_VOL_ML 1000.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0F ///< Reservoirs 1 & 2 partial volume in mL. #define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts. -#define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. -#define RSRVRS_500ML_FILL_UP_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. -#define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. +#define RSRVRS_FILL_UP_TIMEOUT_MS ( 6 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. +#define RSRVRS_BOTH_FILL_UP_TIMEOUT_MS ( 12 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. +#define RSRVRS_PARTIAL_FILL_UP_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. +#define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. +#define RSRVRS_DRAIN_TIMEOUT_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. // R1 to R2 & R2 to R1 chemical disinfect circulation #define CHEM_DISINFECT_TARGET_RO_FLOW_LPM 0.5F ///< Chemical disinfect target RO flow rate in L/min. #define CHEM_DISINFECT_MAX_RO_PRESSURE_PSI 130 ///< Chemical disinfect maximum RO pressure in psi. -#define CHEM_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0 ///< Chemical disinfect target drain outlet pressure in psi. -#define CHEM_DISINFECT_TIME_MS ( 36 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect time for each section in milliseconds. TODO original time was 36 minutes -#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. + +#define CHEM_DISINFECT_TIME_MS ( 7 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect time for each section in milliseconds. TODO original time was 36 minutes +#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 6 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. +#define DRAIN_PUMP_VOLUME_CONTROL_RPM 1200 +#define RSRVR_DRAIN_CONTROL_MIN_VOLUME 1600.0F +#define RSRVR_DRAIN_CONTROL_MAX_VOLUME 1750.0F + +#define DRP_VOLUME_CONTROL_TARGET_VOLUME_ML 1000.0F +#define DRP_VOLUME_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define DRP_VOLUME_CONTROL_P_COEFFICIENT -0.5F ///< P term for dialIn pump control. +#define DRP_VOLUME_CONTROL_I_COEFFICIENT 0.0F ///< P term for dialIn pump control. +#define MIN_DRP_VOLUME_CONTROL_RPM 200.0F +#define MAX_DRP_VOLUME_CONTROL_RPM 1500.0F + +// the next 4 not currently used +//#define CHEM_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0 ///< Chemical disinfect target drain outlet pressure in psi. #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5F * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during chemical disinfect. TODO change this to 5 seconds #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 600.0F ///< Reservoirs 1 & 2 maximum allowed volume change when full during chemical disinfect. TODO original value is 100 mL #define POST_CHEM_DISINFECT_WAIT_TIME_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect final wait time before flushing the system in milliseconds. // Prime acid line #define PRIME_ACID_LINE_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Priming acid line timeout in milliseconds. #define DISINFECTANT_PUMP_PRIME_SPEED_ML_PER_MIN 19.0F ///< Disinfectant pump prime speed in ml/min. -#define MIN_PRIME_ACID_CONDUCTIVITY_US_PER_CM 600.0F ///< Minimum conductivity that indicates acid is in the line in uS/cm. -#define PRIME_ACID_STEADY_CONDUCTIVITY_TIME_MS ( ( 10 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Minimum time that a steady conductivity of acid must be read in milliseconds. +#define MIN_PRIME_ACID_CONDUCTIVITY_US_PER_CM 2.0F ///< Minimum conductivity that indicates acid is in the line in uS/cm. TODO: set to 600.0 +#define PRIME_ACID_STEADY_CONDUCTIVITY_TIME_MS ( ( 10 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Minimum time that a steady conductivity of acid must be read in milliseconds. TODO: set to 10 sec #define RO_PUMP_TARGET_PRIME_DISINECTANT_FLOW_RATE_LPM 0.8F ///< ROP flow rate for disinfectant prime #define MAX_RO_PUMP_PRIME_DISINFECTANT_PRESSURE_PSI 130.0F ///< ROP max pressure for disinfectant prime @@ -108,15 +123,16 @@ #define DISINFECTANT_PUMP_FILL_SPEED_ML_PER_MIN 7.5F ///< Disinfectant pump fill speed in ml/min. #define RO_PUMP_TARGET_FILL_DISINECTANT_FLOW_RATE_LPM 0.5F ///< ROP flow rate for disinfectant prime #define MAX_RO_PUMP_FILL_DISINFECTANT_PRESSURE_PSI 130.0F ///< ROP max pressure for disinfectant fill -#define FLUSH_DISINFECTANT_INITIAL_WAIT_TIME ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Initial time to wait for temperature and conductivity to reach target in disinfectant flush state -#define FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME ( 60 * SEC_PER_MIN * MS_PER_SECOND ) ///< Additional time to wait for temperature and conductivity to reach target in disinfectant flush state +#define FLUSH_DISINFECTANT_INITIAL_WAIT_TIME ( 30 * MS_PER_SECOND ) ///< Initial time to wait for temperature and conductivity to reach target in disinfectant flush state +#define FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME ( 60 * MS_PER_SECOND ) ///< Additional time to wait for temperature and conductivity to reach target in disinfectant flush state #define MAX_DISINFECT_FLUSH_CYCLE_PERIODS 2 ///< Number of allowed periods to check conductivity and temperature in disinfectant flush state -#define MIN_DISINFECT_CONDUCTIVITY_US_PER_CM 150.0F ///< Minimum conductivity for mixed disinfect fluid in us/cm -#define MAX_DISINFECT_CONDUCTIVITY_US_PER_CM 650.0F ///< Minimum conductivity for mixed disinfect fluid in us/cm -#define MIN_DISINFECT_TD2_TEMPERATURE_C 35.0F ///< Minimum temperature for mixed disinfect fluid at outlet of heater in dec C -#define MAX_DISINFECT_TD2_TEMPERATURE_C 45.0F ///< Maximum temperature for mixed disinfect fluid at outlet of heater in dec C +#define MIN_DISINFECT_CONDUCTIVITY_US_PER_CM 5.0F ///< Minimum conductivity for mixed disinfect fluid in us/cm TODO: set to 150.0 +#define MAX_DISINFECT_CONDUCTIVITY_US_PER_CM 5000.0F ///< Minimum conductivity for mixed disinfect fluid in us/cm TODO: set to 650.0 +#define MIN_DISINFECT_TD2_TEMPERATURE_C 25.0F ///< Minimum temperature for mixed disinfect fluid at outlet of heater in dec C TODO: set to 35.0 +#define MAX_DISINFECT_TD2_TEMPERATURE_C 45.0F ///< Maximum temperature for mixed disinfect fluid at outlet of heater in dec C TODO: set to 45.0 // Fill heat up -#define CHEM_DISINFECT_TARGET_TEMPERATURE_C 40.0F ///< Chemical disinfect target water temperature in C. // TODO this used to 30.0 +#define CHEM_DISINFECT_TARGET_TEMPERATURE_C 30.0F ///< Chemical disinfect target water temperature in C. // TODO this used to 30.0 +#define CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C 40.0F ///< Chemical disinfect heater control water temperature in C. // TODO this used to 30.0 #define DISINFECT_CYCLE_PERIOD_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time for disinfectant filling and partial draining cycle static const F32 ACID_TO_WATER_MIXING_RATIO = ( 1.0F / 70.0F ); ///< Acid to water mixing ratio for chemical disinfect. @@ -168,8 +184,10 @@ static F32 R1ChemDisinfectVol = 0.0; ///< Reservoir 1 full volume during chemical disinfect. static F32 R2ChemDisinfectVol = 0.0; ///< Reservoir 2 full volume during chemical disinfect. static U32 chemDisinfectTimer = 0; ///< Chemical disinfect timer. +static U32 chemDisinfectWarmupTimer = 0; ///< Chemical disinfect warmup timer. static BOOL isPartialDisinfectInProgress = FALSE; ///< Chemical disinfect partial complete/in progess flag. -static U32 rsrvrsVolMonitorTimer = 0; ///< Reservoir 1 & 2 volume monitor timers during chemical disinfect. +static U32 rsrvrsVolMonitorTimer = 0; +static U32 drpControlTimerCounter = 0; static BOOL areRsrvrsLeaking = FALSE; ///< Reservoir 1 & 2 leak check flag during chemical disinfect. static U32 dataPublishCounter = 0; ///< Chemical Disinfect data publish counter. static CANCELLATION_MODE_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. @@ -194,16 +212,13 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectFillWithDisinfectantState( void ); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectR1DisinfectantFillR2DrainState( void ); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectR2DisinfectantFillR1DrainState( void ); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR1ToR2State( void ); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR1FillR1ToR2State( void ); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR2ToR1State( void ); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR2FillR1ToR2State( void ); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeBasicPathState(void); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeWaterPathState(void); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCompleteState(void); static void failChemicalDisinfect( void ); static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout ); static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ); +static void controlDRPByReservoirVolume( DG_RESERVOIR_ID_T r, BOOL initialize ); static CHEM_DISINFECT_STATUS_T getChemicalDisinfectStatus( void ); static void publishChemicalDisinfectData( void ); static void monitorModeChemicalDisinfect( void ); @@ -236,6 +251,8 @@ R1ChemDisinfectVol = 0.0; R2ChemDisinfectVol = 0.0; overallChemDisinfectTimer = 0; + chemDisinfectWarmupTimer = 0; + chemDisinfectTimer = 0; cancellationMode = CANCELLATION_MODE_NONE; rsrvrFillStableTimeCounter = 0; isPartialDisinfectInProgress = FALSE; @@ -315,26 +332,12 @@ case DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN: chemDisinfectState = handleChemicalDisinfectR2DisinfectantFillR1DrainState(); + break; case DG_CHEM_DISINFECT_STATE_R1_DISINFECTANT_FILL_R2_DRAIN: chemDisinfectState = handleChemicalDisinfectR1DisinfectantFillR2DrainState(); - - case DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2: - chemDisinfectState = handleChemicalDisinfectDisinfectR1ToR2State(); break; - case DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R1_FILL_R1_TO_R2: - chemDisinfectState = handleChemicalDisinfectPartialDrainR1FillR1ToR2State(); - break; - - case DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1: - chemDisinfectState = handleChemicalDisinfectDisinfectR2ToR1State(); - break; - - case DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2: - chemDisinfectState = handleChemicalDisinfectPartialDrainR2FillR1ToR2State(); - break; - case DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH: chemDisinfectState = handleChemicalDisinfectCancelModeBasicPathState(); break; @@ -559,21 +562,21 @@ // Check if flush time has elapsed if ( TRUE == didTimeout( stateTimer, FLUSH_DRAIN_WAIT_TIME_MS ) ) { - if (haveInletWaterChecksPassed) + if ( TRUE == haveInletWaterChecksPassed ) { // set pumps and valves for next state, flush disinfectant line setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - turnOnUVReactor( INLET_UV_REACTOR ); + turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); flushCircWaitTime = FLUSH_CICRCULATION_WAIT_TIME_MS; stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_FLUSH_CIRCULATION; } else - { + { // If the number of failures have not exceeded the limit, try again. ++stateTrialCounter; if ( stateTrialCounter < MAX_ALLOWED_FLUSH_DRAIN_PERIODS ) @@ -587,7 +590,7 @@ prevChemDisinfectState = state; state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; } - } + } } @@ -642,15 +645,15 @@ // determine which alarm it is, temperature or conductivity, one of them has to take precedence { if ( ( TRUE == isTPoOut ) || ( TRUE == isTD2Out ) ) - { + { alarmDetectedPendingTrigger = ALARM_ID_DG_TEMP_SENSORS_DIFF_OUT_OF_RANGE; - } - else - { + } + else + { alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE; //ALARM_ID_DG_NEW_CON; - } - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; + } + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; } } else @@ -660,7 +663,7 @@ // Set the acid dispense pump speed setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, DISINFECTANT_PUMP_PRIME_SPEED_ML_PER_MIN ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - state = DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT; + state = DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT; stateTimer = getMSTimerCount(); @@ -685,7 +688,7 @@ *************************************************************************/ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPrimeDisinfectantState( void ) { - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_PRIME_ACID_LINE; + DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT; F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); // Set the chemical disinfect that is published on the UI @@ -716,12 +719,12 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); // Start heating the water while we are filling up the reservoirs - setHeaterTargetTemperature( DG_PRIMARY_HEATER, CHEM_DISINFECT_TARGET_TEMPERATURE_C ); + setHeaterTargetTemperature( DG_PRIMARY_HEATER, CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C ); startHeater( DG_PRIMARY_HEATER ); flushDisinfectantWaitTime = FLUSH_DISINFECTANT_INITIAL_WAIT_TIME; stateTrialCounter = 0; - state = DG_CHEM_DISINFECT_STATE_FILL_WITH_WATER_AND_DISINFECTANT; + state = DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH; stateTimer = getMSTimerCount(); } } @@ -760,30 +763,32 @@ if ( TRUE == didTimeout( stateTimer, flushDisinfectantWaitTime ) ) { CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - if ( ( CHEM_DISINFECT_HEATER_OUTLET_TEMPERATURE_OUT_OF_RANGE == state ) || - ( CHEM_DISINFECT_DISINFECTANT_CONDUCTIVITY_OUT_OF_RANGE == state ) ) - { + if ( ( CHEM_DISINFECT_HEATER_OUTLET_TEMPERATURE_OUT_OF_RANGE == status ) || + ( CHEM_DISINFECT_DISINFECTANT_CONDUCTIVITY_OUT_OF_RANGE == status ) ) + { // Check if we have exceeded the number of trials. If not, try another time ++stateTrialCounter; if (stateTrialCounter < MAX_ALLOWED_DISINFECTANT_FLUSH_PERIODS ) { stateTimer = getMSTimerCount(); flushDisinfectantWaitTime = FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME; - } - else - { + } + else + { // fail, alarm has already been set - prevChemDisinfectState = state; + prevChemDisinfectState = state; state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; - } + } } else - { + { // No changes in valves and pumps for next state + //setValveState( VRD1, VALVE_STATE_OPEN ); // for testing, may prevent tubing breaks, TODO: remove + //setValveState( VRD2, VALVE_STATE_OPEN ); // for testing, may prevent tubing breaks, TODO: remove rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_FILL_WITH_WATER_AND_DISINFECTANT; + state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; } } @@ -807,58 +812,55 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectFillWithDisinfectantState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; - CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - static BOOL rsvr2TimerStarted = FALSE; - // First reservoir 1 must be full - if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) - { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - } +// if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) +// { +// rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); +// } // Once reservoir 1 is full, check the status of reservoir 2 since the water overflows to reservoir 2 - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - if ( FALSE == rsvr2TimerStarted ) - { - // have to reset timer for reservoir 2 fill - stateTimer = getMSTimerCount(); - rsvr2TimerStarted = TRUE; - } - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); +// else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) +// { + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_BOTH_FILL_UP_TIMEOUT_MS ); - // Once reservoir 2 is full, set the actuators for next state + // If R1 is not full, keep monitoring for R1 level and timeout + // Once R1 is full, keep monitoring for R2 level and timeout + // Once R2 is full, transition to the next state if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { + // Set the actuators to flush R2 and drain R1 state // Set the valves to drain R1 and fill R2 setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_OPEN ); - + // Set both reservoirs status + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; // Set the drain pump to control mode TODO: change to volume control mode - setDrainPumpTargetOutletPressure( CHEM_DISINFECT_TARGET_DRAIN_PRES_PSI ); + //setDrainPumpTargetOutletPressure( CHEM_DISINFECT_TARGET_DRAIN_PRES_PSI ); + controlDRPByReservoirVolume( DG_RESERVOIR_1, TRUE ); //Initialize the PI controller for DRP // Get the current volumes of R1 & R2. These values will be used to make sure the reservoirs' // volume does not change more than a certain amount during the actual chemical disinfect cycle R1ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); R2ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - + chemDisinfectWarmupTimer = getMSTimerCount(); + isPartialDisinfectInProgress = FALSE; stateTimer = getMSTimerCount(); rsrvrsVolMonitorTimer = getMSTimerCount(); - isPartialDisinfectInProgress = TRUE; - chemDisinfectTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } +// } +// else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) +// { +// prevChemDisinfectState = state; +// state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; +// } return state; } @@ -887,29 +889,34 @@ if ( CHEM_DISINFECT_COMPLETE == status) { // turn pumps and valves off - stopHeater( DG_PRIMARY_HEATER ); + stopHeater( DG_PRIMARY_HEATER ); setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); - signalROPumpHardStop(); + signalROPumpHardStop(); signalDrainPumpHardStop(); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); - - state = DG_CHEM_DISINFECT_STATE_COMPLETE; + + state = DG_CHEM_DISINFECT_STATE_COMPLETE; } if ( TRUE == didTimeout( stateTimer, DISINFECT_CYCLE_PERIOD_MS ) ) { // go to the next disinfect configuration cycle setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_OPEN ); stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_R1_DISINFECTANT_FILL_R2_DRAIN; + state = DG_CHEM_DISINFECT_STATE_R1_DISINFECTANT_FILL_R2_DRAIN; } + else + { + controlDRPByReservoirVolume( DG_RESERVOIR_1, FALSE ); + } return state; } @@ -938,224 +945,41 @@ if ( CHEM_DISINFECT_COMPLETE == status) { // turn pumps and valves off - stopHeater( DG_PRIMARY_HEATER ); + stopHeater( DG_PRIMARY_HEATER ); setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD2, VALVE_STATE_CLOSED ); - signalROPumpHardStop(); + signalROPumpHardStop(); signalDrainPumpHardStop(); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); - state = DG_CHEM_DISINFECT_STATE_COMPLETE; + state = DG_CHEM_DISINFECT_STATE_COMPLETE; } - if ( TRUE == didTimeout( stateTimer, DISINFECT_CYCLE_PERIOD_MS ) ) + else if ( TRUE == didTimeout( stateTimer, DISINFECT_CYCLE_PERIOD_MS ) ) { // go to the next disinfect configuration cycle setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_OPEN ); setValveState( VRD2, VALVE_STATE_CLOSED ); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN; + state = DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN; } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleChemicalDisinfectDisinfectR1ToR2State function handles the - * chemical disinfect R1 to R2 state. The state runs reservoir 1 to reservoir 2 - * chemical disinfect. If the reservoirs leak or it cannot reach to temperature - * within a certain period of time, it transitions to water cancellation. - * If chemical disinfect reservoir 1 to reservoir 2 is completed, it - * transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status - * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, - * chemDisinfectUIState - * @return next state of the chemical disinfect state machine - *************************************************************************/ -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR1ToR2State( void ) -{ - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; - CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - - // Set the chemical disinfect that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; - - switch ( status ) + else { - case CHEM_DISINFECT_RSRVRS_LEAK_TIMEOUT: - case CHEM_DISINFECT_HEAT_UP_TIMEOUT: - - break; - - case CHEM_DISINFECT_COMPLETE: - // Turn off the concentrate pumps - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); - - // 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 ); - // Although there is fluid in both reservoirs, but they are set to empty - // to begin the transition of disinfectant water from R1 to R2. - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_FILL_R2_WITH_DISINFECTANT; - break; - - default: - // Do nothing, chemical disinfect is in progress - break; + controlDRPByReservoirVolume( DG_RESERVOIR_2, FALSE ); } return state; } -/*********************************************************************//** - * @brief - * The handleChemicalDisinfectFillR2WithDisinfectantState function - * handles fill R2 with water state. The state transfers disinfectant from - * reservoir 1 to reservoir 2 until disinfectant overflows from reservoir 2 - * to reservoir 1. - * If the fill times out, it transitions to water cancellation state, - * otherwise, it transitions to the next state. - * @details Inputs: rsrvr1Status, rsrvr2Status - * @details Outputs: rsrvr1Status, rsrvr2Status, R1ChemDisinfectVol, - * R2ChemDisinfectVol, prevChemDisinfectState - * @return next state of the chemical disinfect state machine - *************************************************************************/ -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR1FillR1ToR2State( void ) -{ - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_FILL_R2_WITH_DISINFECTANT; - CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - - // First reservoir 1 must be partially full - if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) - { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) - { - // Get the current volumes to be monitored during R2 to R1 chemical disinfect state - R1ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - R2ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - - state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) - { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - - return state; -} - /*********************************************************************//** * @brief - * The handleChemicalDisinfectDisinfectR2ToR1State function handles the - * chemical disinfect R2 to R1 state. If the reservoirs leak or it cannot - * reach to temperature within a certain period of time, it transitions to - * water cancellation state. If heat disinfect reservoir 1 to reservoir 2 is - * completed, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status - * @details Outputs: stateTimer, rsrvr1Status - * @return next state of the heat disinfect state machine - *************************************************************************/ -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR2ToR1State( void ) -{ - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; - CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - - switch ( status ) - { - case CHEM_DISINFECT_RSRVRS_LEAK_TIMEOUT: - case CHEM_DISINFECT_HEAT_UP_TIMEOUT: - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - break; - - case CHEM_DISINFECT_COMPLETE: - // Turn off the heaters - stopHeater( DG_PRIMARY_HEATER ); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_COOL_DOWN_HEATERS; - break; - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleChemicalDisinfectFillR2WithDisinfectantState function - * handles fill R2 with water state. The state transfers disinfectant from - * reservoir 1 to reservoir 2 until disinfectant overflows from reservoir 2 - * to reservoir 1. - * If the fill times out, it transitions to water cancellation state, - * otherwise, it transitions to the next state. - * @details Inputs: rsrvr1Status, rsrvr2Status - * @details Outputs: rsrvr1Status, rsrvr2Status, R1ChemDisinfectVol, - * R2ChemDisinfectVol, prevChemDisinfectState - * @return next state of the chemical disinfect state machine - *************************************************************************/ -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR2FillR1ToR2State( void ) -{ - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_FILL_R2_WITH_DISINFECTANT; - CHEM_DISINFECT_STATUS_T status = getChemicalDisinfectStatus(); - - // First reservoir 1 must be partially full - if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) - { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - - if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) - { - // Get the current volumes to be monitored during R2 to R1 chemical disinfect state - R1ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - R2ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - - state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) - { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - - return state; -} - -/*********************************************************************//** - * @brief * The handleChemicalDisinfectCancelModeBasicPathState function handles the * chemical disinfect cancel mode basic path state. The state sets the state * to complete and raises an alarm. @@ -1383,7 +1207,67 @@ return status; } +static void controlDRPByReservoirVolume( DG_RESERVOIR_ID_T r, BOOL initialize ) +{ + if ( TRUE == initialize ) + { + // Initialize dialysate inlet flow PI controller + initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, MIN_DRP_VOLUME_CONTROL_RPM, + DRP_VOLUME_CONTROL_P_COEFFICIENT, DRP_VOLUME_CONTROL_I_COEFFICIENT, + MIN_DRP_VOLUME_CONTROL_RPM, MAX_DRP_VOLUME_CONTROL_RPM ); + drpControlTimerCounter = getMSTimerCount(); + resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, MIN_DRP_VOLUME_CONTROL_RPM ); + setDrainPumpTargetRPM( MIN_DRP_VOLUME_CONTROL_RPM ); + } + else if ( TRUE == didTimeout( drpControlTimerCounter, DRP_VOLUME_CONTROL_INTERVAL ) ) + { // Control at set interval + F32 tgtVolume = (F32)DRP_VOLUME_CONTROL_TARGET_VOLUME_ML; + F32 actVolume; + U32 newRPM; + if ( DG_RESERVOIR_1 == r ) + { + actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + } + else if ( DG_RESERVOIR_2 == r ) + { + actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + } + else + { + actVolume = tgtVolume + 500.0; + //SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_RESERVOIR_SELECTED, r ) + } + + newRPM = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, tgtVolume, actVolume ); + setDrainPumpTargetRPM( newRPM ); + drpControlTimerCounter = getMSTimerCount(); + } + + + +/* + if ( volume > RSRVR_DRAIN_CONTROL_MAX_VOLUME ) + { + // If volume is above target, turn pump on. + setDrainPumpTargetRPM( DRAIN_PUMP_VOLUME_CONTROL_RPM ); + } + else if ( volume < RSRVR_DRAIN_CONTROL_MIN_VOLUME ) + { + //if volume is below target, turn pump off. + signalDrainPumpHardStop(); + } + // TODO: somehow prevent both reservoirs from being full at the same time + //if ( volume > RSRVR_DRAIN_CONTROL_MAX_VOLUME ) + //{ + // //there is a problem with draining, alarm + // prevChemDisinfectState = chemDisinfectState; + // alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; //TODO: get correct alarm + // failChemicalDisinfect(); //TODO: fail in the correct way + //} +*/ +} + /*********************************************************************//** * @brief * The getChemicalDisinfectStatus function monitors and returns the current @@ -1400,14 +1284,14 @@ CHEM_DISINFECT_STATUS_T status = CHEM_DISINFECT_IN_PROGRESS; // Update the variables - F32 TdiTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + F32 TdiTemp = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); BOOL isR1OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1ChemDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; BOOL isR2OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2ChemDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); F32 TD2Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); BOOL isCD2OutofRange = ( cd2Conductivity < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Conductivity > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); - BOOL isTD2OutofRange = ( TD2Temp < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || TD2Temp > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); - + BOOL isTD2OutofRange = ( TD2Temp < MIN_DISINFECT_TD2_TEMPERATURE_C || TD2Temp > MAX_DISINFECT_TD2_TEMPERATURE_C ); + /* // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { @@ -1431,7 +1315,7 @@ { areRsrvrsLeaking = FALSE; } - + */ // For the following checks, if multiple failures occur at the same time, the last one will take precedence // Check if the acid conductivity and temperature are within range if ( TRUE == isCD2OutofRange ) @@ -1442,28 +1326,28 @@ if ( ( TRUE == isTD2OutofRange ) ) { alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; - status = CHEM_DISINFECT_HEATER_OUTLET_TEMPERATURE_OUT_OF_RANGE; + status = CHEM_DISINFECT_HEATER_OUTLET_TEMPERATURE_OUT_OF_RANGE; } - // If the coldest spot which is THd is less than minimum chemical disinfect temperature, + // If the coldest spot which is TDi is less than minimum chemical disinfect temperature, // reset the chemical disinfect timers and check whether heating up has timed out if ( TdiTemp < CHEM_DISINFECT_TARGET_TEMPERATURE_C ) { - if ( TRUE == didTimeout( stateTimer, CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ) ) + if ( TRUE == didTimeout( chemDisinfectWarmupTimer, CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ) ) { // Heating up to minimum temperature for chemical disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; status = CHEM_DISINFECT_HEAT_UP_TIMEOUT; } - else - { + else + { // Keep reseting the disinfect timer so the elapsed time is always 0 until disinfect truly starts chemDisinfectTimer = getMSTimerCount(); isPartialDisinfectInProgress = FALSE; status = CHEM_DISINFECT_DISINFECT_TEMPERATURE_LOW; - } + } } - else if ( ( isPartialDisinfectInProgress != TRUE ) && ( TdiTemp >= CHEM_DISINFECT_TARGET_TEMPERATURE_C ) ) + else if ( isPartialDisinfectInProgress != TRUE ) { // The temperature of the coldest spot is in range to start the disinfect timer chemDisinfectTimer = getMSTimerCount(); @@ -1473,7 +1357,7 @@ // If chemical disinfect temperature has been reached, check if this stage of chemical disinfect is done if ( ( TRUE == isPartialDisinfectInProgress ) && ( TRUE == didTimeout( chemDisinfectTimer, CHEM_DISINFECT_TIME_MS ) ) ) { - // Done with this stage of chemical disnfect. Reset the variables + // Done with this stage of chemical disinfect. Reset the variables status = CHEM_DISINFECT_COMPLETE; isPartialDisinfectInProgress = FALSE; } @@ -1501,12 +1385,12 @@ data.stateElapsedTime = calcTimeSince( stateTimer ); data.cancellationMode = (U32)cancellationMode; - // If the mode is in the actual chemical disinfect states, publish the elapsed time, otherwise publish 0 to avoid confusion - if ( ( DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 == chemDisinfectState ) || - ( DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1 == chemDisinfectState ) ) + //If the mode is in the actual chemical disinfect states, publish the elapsed time, otherwise publish 0 to avoid confusion + if ( ( DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN == chemDisinfectState ) || + ( DG_CHEM_DISINFECT_STATE_R1_DISINFECTANT_FILL_R2_DRAIN == chemDisinfectState ) ) { uiData.chemDisinfectTargetTime = CHEM_DISINFECT_TIME_MS; - uiData.chemDisinfectCountdownTime = CHEM_DISINFECT_TIME_MS - calcTimeSince( chemDisinfectTimer ); + uiData.chemDisinfectCountdownTime = calcTimeSince( chemDisinfectTimer ); //CHEM_DISINFECT_TIME_MS - calcTimeSince( chemDisinfectTimer ); data.R1FillLevel = R1ChemDisinfectVol; data.R2FillLevel = R2ChemDisinfectVol; } @@ -1563,27 +1447,29 @@ alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; } } + // In all states, check inlet temperature, inlet pressure, and inlet conductivity. haveInletWaterChecksPassed= TRUE; - hasConductivityFailed = ( ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) >= MAX_INLET_CONDUCTIVITY_US_PER_CM ) || - ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) <= MIN_INLET_CONDUCTIVITY_US_PER_CM ) ); + hasConductivityFailed = ( ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) > MAX_INLET_CONDUCTIVITY_US_PER_CM ) || + ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) < MIN_INLET_CONDUCTIVITY_US_PER_CM ) ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) { hasConductivityFailed = FALSE; } #endif if ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) < MIN_INLET_TEMPERATURE_C || + getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) > MAX_INLET_TEMPERATURE_C || hasConductivityFailed || getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ) < MIN_INLET_PRESSURE_PSI) { // Inlet check failed, set timer if not already set if ( 0 == inletWaterChecksFailTimer ) - { - inletWaterChecksFailTimer = getMSTimerCount(); - } - haveInletWaterChecksPassed= FALSE; // set flag for flush drain state + { + inletWaterChecksFailTimer = getMSTimerCount(); + } + haveInletWaterChecksPassed= FALSE; // set flag for flush drain state if ( TRUE == didTimeout( inletWaterChecksFailTimer, INLET_WATER_CHECK_FAILURE_TIMEOUT_MS ) ) { // alarm unless in the start, drain, or flush drain states @@ -1602,16 +1488,14 @@ alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE; //ALARM_ID_NEW_WAT; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; break; - case DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT: - case DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2: - case DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R1_FILL_R2_TO_R1: - case DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1: - case DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2: + case DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT: + case DG_CHEM_DISINFECT_STATE_R2_DISINFECTANT_FILL_R1_DRAIN: + case DG_CHEM_DISINFECT_STATE_R1_DISINFECTANT_FILL_R2_DRAIN: prevChemDisinfectState = chemDisinfectState; alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE; //ALARM_ID_NEW_WAT; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; break; - } + } } } else