Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -refc7f297febee73bf520b4c5646e49c8f53caf41 -r3f19c30ddaa6677778f7e74447cfcdbcfe4cd77e --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision efc7f297febee73bf520b4c5646e49c8f53caf41) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 3f19c30ddaa6677778f7e74447cfcdbcfe4cd77e) @@ -84,7 +84,7 @@ #define RSRVRS_FILL_UP_TIMEOUT_MS ( 8 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. #define RSRVRS_PARTIAL_FILL_UP_TIMEOUT_MS ( 7 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. #define RSRVRS_ALMOST_FULL_FILL_UP_TIMEOUT_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. It is assumed the reservoir is nearly full to begin. -#define RESERVOIR_FULL_VOLUME_CHANGE_LIMIT_ML 5.0F ///< The maximum difference between the short-term and long-term filtered reservoir volumes in ml that determines the tank is full. +#define RESERVOIR_FULL_VOLUME_CHANGE_LIMIT_ML 5.0F ///< The maximum difference between the short-term and long-term filtered reservoir volumes in ml that determines the reservoir is full. #define RESERVOIR_MINIMUM_FULL_VOLUME_ML 1700.0F ///< When filling the reservoir, the volume reading must be at least this value before checking for the volume to level off. #define RSRVRS_FILL_TO_FULL_STABLE_TASK_INT ( ( 2 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in task intervals. @@ -116,8 +116,8 @@ // Initial disinfectant fill of R1 and R2 #define RSRVRS_FULL_VOL_ML 1800.0F ///< Reservoirs 1 & 2 full volume in mL. -#define RSRVRS_LEAK_VOL_TIMEOUT_TASK_INT ( ( 30 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Time delay for declaring that tank is leaking due to volume depletion. -#define RSRVRS_MAX_LEAK_VOL_CHANGE_ML 100.0F; ///< Volume loss that is necessary to declare a tank leak. +#define RSRVRS_LEAK_VOL_TIMEOUT_TASK_INT ( ( 30 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Time delay for declaring that reservoir is leaking due to volume depletion. +#define RSRVRS_MAX_LEAK_VOL_CHANGE_ML 100.0F; ///< Volume loss that is necessary to declare a reservoir leak. // Parameters controlling chemical disinfect #define TARGET_CHEM_DISINFECT_TIME_MS ( 12 * SEC_PER_MIN * MS_PER_SECOND ) ///< Expected chemical disinfect time in ms. @@ -126,12 +126,12 @@ #define CHEM_DISINFECT_MINIMUM_TEMPERATURE_C 35.0F ///< Chemical disinfect target water temperature in C. #define CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C 45.0F ///< Chemical disinfect heater control water temperature in C. #define DISINFECT_CYCLE_PERIOD_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time for each disinfectant filling and partial draining cycle. This is the time that the reservoir is full and the temperature is above the target. -#define REQUIRED_DISINFECT_CYCLES 2 ///< Number of times each tank is to be filled with disinfectant. -#define MAX_DISINFECT_STATE_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Maximum time in each tank disinfect cycle. +#define REQUIRED_DISINFECT_CYCLES 2 ///< Number of times each reservoir is to be filled with disinfectant. +#define MAX_DISINFECT_STATE_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Maximum time in each reservoir disinfect cycle. -// A PI control loop is used control the DRP speed while the tank is filling and draining, to maintain a constant level of disinfectant in the tank +// A PI control loop is used control the DRP speed while the reservoir is filling and draining, to maintain a constant level of disinfectant in the reservoir #define RESERVOIR_VOLUME_BELOW_FULL_ML 150.0F ///< Volume to maintain in reservoir relative to full volume -#define DRP_VOLUME_CONTROL_TARGET_VOLUME_ML 1800.0F ///< Tank level to maintain using DRP volume control, default value +#define DRP_VOLUME_CONTROL_TARGET_VOLUME_ML 1800.0F ///< Reservoir level to maintain using DRP volume control, default value #define DRP_VOLUME_CONTROL_INTERVAL_TASK_INT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Update rate for DRP volume control in ms. #define DRP_VOLUME_CONTROL_P_COEFFICIENT -2.5F ///< P term for DRP volume control. #define DRP_VOLUME_CONTROL_I_COEFFICIENT -0.2F ///< I term for DRP volume control. @@ -176,7 +176,7 @@ static BOOL ischemDisinfectWarmupTargetReached = FALSE; ///< Flag that indicates whether the disinfect warmup target has been reached. static BOOL isChemDisinfectTemperatureAboveTarget = FALSE; ///< Flag that indicates if the disinfect temperature is currently above the target. static U32 DisinfectCycleCounter = 0; ///< Counter for disinfect cycles. -static U32 drpControlTimerCounter = 0; ///< Timer/counter for tank volume control of DRP. +static U32 drpControlTimerCounter = 0; ///< Timer/counter for reservoir volume control of DRP. static U32 dataPublishCounter = 0; ///< Chemical Disinfect data publish timer/counter. static CANCELLATION_MODE_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. static U32 rsrvrFillStableTimeCounter; ///< Reservoirs fill stable time counter. @@ -524,7 +524,8 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - + turnOnUVReactor( INLET_UV_REACTOR ); + stateTrialCounter = 0; stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_FLUSH_DRAIN; @@ -571,7 +572,6 @@ setHeaterTargetTemperature( DG_PRIMARY_HEATER, CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C ); startHeater( DG_PRIMARY_HEATER ); // The UV reactors will be on for the entire disinfect cycle - turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); flushCircWaitTime = FLUSH_CICRCULATION_INITIAL_WAIT_TIME_MS; @@ -627,15 +627,15 @@ // of the temperature sensors BOOL isTPoOut = FALSE; BOOL isTD2Out = FALSE; + BOOL isCD2Out = ( cd2Conductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); + BOOL isCPoOut = ( cpoConductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_TEMPERATURE_SENSORS_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif { isTPoOut = ( fabs( TPoTemp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); isTD2Out = ( fabs( TD2Temp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); } - BOOL isCD2Out = ( cd2Conductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); - BOOL isCPoOut = ( cpoConductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); // Check if any of the temperature sensors are out of tolerance if( ( TRUE == isTPoOut ) || ( TRUE == isTD2Out ) || ( TRUE == isCD2Out ) || ( TRUE == isCPoOut) ) { @@ -765,15 +765,17 @@ F32 cd2Conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); BOOL isCD2OutofRange = ( cd2Conductivity < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Conductivity > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); + BOOL isTPoOutofRange = ( TPoTemp > MAX_DISINFECT_TPO_TEMPERATURE_C ); + #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) { isCD2OutofRange = FALSE; } #endif - BOOL isTPoOutofRange = ( TPoTemp > MAX_DISINFECT_TPO_TEMPERATURE_C ); + if ( ( TRUE == isCD2OutofRange ) || ( TRUE == isTPoOutofRange ) ) - { // The conditions have not been met + { // The conditions have not been met // Check if we have exceeded the number of trials. If not, try another time if (++stateTrialCounter < MAX_ALLOWED_DISINFECTANT_FLUSH_PERIODS ) { @@ -930,7 +932,7 @@ rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R1_FILL_R2_TO_R1; + state = DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R1_FILL_R2_TO_R1; } else { @@ -971,7 +973,7 @@ isRsrvrLeaking = FALSE; chemDisinfectReservoirTime = 0; isChemDisinfectTemperatureAboveTarget = FALSE; - ischemDisinfectWarmupTargetReached = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; @@ -1050,13 +1052,13 @@ initDrainParameters( DG_RESERVOIR_2 ); rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - isThisLastDrain = TRUE; + isThisLastDrain = TRUE; // Set the chemical disinfect state that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_FLUSH_AFTER_DISINFECT; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_FLUSH_AFTER_DISINFECT; writeDisinfectDataToNV(); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; } else { @@ -1108,7 +1110,7 @@ { chemDisinfectReservoirTime = 0; isChemDisinfectTemperatureAboveTarget = FALSE; - ischemDisinfectWarmupTargetReached = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; R1ChemDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); isRsrvrLeaking = FALSE; @@ -1155,7 +1157,7 @@ /*********************************************************************//** * @brief * The handleChemicalDisinfectCancelModeWaterPathState function handles the - * chemical disinfect cancel mode cold water path state. It drains the tanks + * chemical disinfect cancel mode cold water path state. It drains the reservoirs * before the cancel basic path mode is entered. * @details Inputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer * @details Outputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer, @@ -1352,9 +1354,9 @@ /*********************************************************************//** * @brief * The getRsrvrFillToFullStatus function checks whether the target reservoir - * is full or not based on a plateau in the tank readings. + * is full or not based on a plateau in the reservoir readings. * If the fill times out, it sets an alarm. - * @details Inputs: rsrvrFillToFullStableTimeCounter, stateTimer, tank volume + * @details Inputs: rsrvrFillToFullStableTimeCounter, stateTimer, reservoir volume * @details Outputs: alarm, reservoir fill status * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 * @param timeout is the fill up timeout @@ -1412,6 +1414,7 @@ { rsrvrFillToFullStableTimeCounter = 0; } + return status; } @@ -1443,7 +1446,7 @@ * The controlDRPByReservoirVolume function implements the volume control of the * drain pump to maintain a specified volume in one of the reservoirs. It uses * a PI control loop to accomplish this. - * @details Inputs: tank volume, PI coefficients, full volume, + * @details Inputs: reservoir volume, PI coefficients, full volume, * volume below full to maintain, min and max drain pump control RPM * @details Outputs: Sets drain pump RPM * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 @@ -1468,21 +1471,22 @@ F32 tgtVolume = (F32)DRP_VOLUME_CONTROL_TARGET_VOLUME_ML; // this is the default if no full volume is available F32 actVolume; U32 newRPM; + if ( DG_RESERVOIR_1 == r ) { actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); if ( R1FullVolume > 0.0 ) - { // If a tank full volume is known, use a set volume below full. This compensates for variations in - // the tank and load cell that may affect the volume read when the tank is full. + { // If a reservoir full volume is known, use a set volume below full. This compensates for variations in + // the reservoir and load cell that may affect the volume read when the reservoir is full. tgtVolume = R1FullVolume - RESERVOIR_VOLUME_BELOW_FULL_ML; } } else if ( DG_RESERVOIR_2 == r ) { actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); if ( R2FullVolume > 0.0 ) - { // If a tank full volume is known, use a set volume below full. This compensates for variations in - // the tank and load cell that may affect the volume read when the tank is full. + { // If a reservoir full volume is known, use a set volume below full. This compensates for variations in + // the reservoir and load cell that may affect the volume read when the reservoir is full. tgtVolume = R2FullVolume - RESERVOIR_VOLUME_BELOW_FULL_ML; } } @@ -1514,12 +1518,10 @@ // 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 ) { isChemDisinfectTemperatureAboveTarget = TRUE; ischemDisinfectWarmupTargetReached = TRUE; - } else if ( TdiTemp < CHEM_DISINFECT_MINIMUM_TEMPERATURE_C ) { @@ -1590,7 +1592,7 @@ * chemical disinfect is cancelled. If the conductivity of the diluted disinfectant * mix is not within the specified limits, an alarm is set and disinfect is * cancelled. - * @details Inputs: chemDisinfectState, tank volumes, tank volume monitor timer, + * @details Inputs: chemDisinfectState, reservoir volumes, reservoir volume monitor timer, * inlet water temperature, pressure, and conductivity, disinfectant conductivity. * @details Outputs: prevChemDisinfectState, chemDisinfectState, cancel state, * alarmDetectedPendingTrigger @@ -1644,6 +1646,7 @@ // will not be raising the alarm at end of the cancel water path. The recoverable alarm is raised here in this function U32 ConcCap = (U32)getSwitchStatus( CONCENTRATE_CAP ); U32 DialysateCap = (U32)getSwitchStatus( DIALYSATE_CAP ); + prevChemDisinfectState = chemDisinfectState; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; @@ -1654,6 +1657,7 @@ BOOL hasConductivityFailed = TRUE; BOOL hasInletPressureFailed = TRUE; BOOL hasInletTemperatureFailed = TRUE; + haveInletWaterChecksPassed= TRUE; hasConductivityFailed = ( ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) > MAX_INLET_CONDUCTIVITY_US_PER_CM ) || @@ -1671,7 +1675,7 @@ #endif if ( hasInletTemperatureFailed || hasConductivityFailed || hasInletPressureFailed ) { // Inlet check failed, - haveInletWaterChecksPassed= FALSE; // set flag for flush drain state + haveInletWaterChecksPassed= FALSE; // set flag for flush drain state // increment timer/counter and check for timeout if ( ++inletWaterChecksFailCounter >= INLET_WATER_CHECK_FAILURE_TASK_INT ) { @@ -1687,7 +1691,7 @@ case DG_CHEM_DISINFECT_STATE_FLUSH_CIRCULATION: case DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT: case DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH: - prevChemDisinfectState = chemDisinfectState; + prevChemDisinfectState = chemDisinfectState; alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE; //ALARM_ID_NEW_WAT; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; break; @@ -1716,7 +1720,8 @@ F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); BOOL isCD2OutofRange = ( cd2Conductivity < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Conductivity > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); -#ifndef _RELEASE_ + + #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) { isCD2OutofRange = FALSE;