Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r9e5ee62245eb2a73b167eabd6c274a71a76a7b0e -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 9e5ee62245eb2a73b167eabd6c274a71a76a7b0e) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -649,11 +649,27 @@ *************************************************************************/ static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue ) { - F32 conductivity = pow( compensatedValue, 4 ) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].fourthOrderCoeff + - pow( compensatedValue, 3 ) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].thirdOrderCoeff + - pow( compensatedValue, 2 ) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].secondOrderCoeff + - compensatedValue * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].gain + - condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].offset; + CAL_DATA_DG_COND_SENSORS_T id = (CAL_DATA_DG_COND_SENSORS_T)sensorId; + F32 conductivity = 0.0F; + + if ( DG_MODE_CHEM == getCurrentOperationMode() ) + { + // If the mode is in chemical disinfect, use the chemical disinfect calibration data for CD1 and CD2 + if ( CAL_DATA_CD1_COND_SENSOR == id ) + { + id = CAL_DATA_CD1_CHEM_DIS_COND_SENSOR; + } + else if ( CAL_DATA_CD2_COND_SENSOR == id ) + { + id = CAL_DATA_CD2_CHEM_DIS_COND_SENSOR; + } + } + + conductivity = pow( compensatedValue, 4 ) * condSensorsCalRecord.condSensors[ id ].fourthOrderCoeff + + pow( compensatedValue, 3 ) * condSensorsCalRecord.condSensors[ id ].thirdOrderCoeff + + pow( compensatedValue, 2 ) * condSensorsCalRecord.condSensors[ id ].secondOrderCoeff + + compensatedValue * condSensorsCalRecord.condSensors[ id ].gain + + condSensorsCalRecord.condSensors[ id ].offset; return conductivity; } Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r1440a4a2be8d12edebd405a20807882e5d32d619 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 1440a4a2be8d12edebd405a20807882e5d32d619) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -217,6 +217,18 @@ /*********************************************************************//** * @brief + * The isHeaterOn function returns the heater status whether it is on or off + * @details Inputs: none + * @details Outputs: heaterStatus + * @return heater on/off status + *************************************************************************/ +BOOL isHeaterOn( DG_HEATERS_T heater ) +{ + return heatersStatus[ heater ].isHeaterOn; +} + +/*********************************************************************//** + * @brief * The startPrimaryHeater function starts the primary heaters. It resets * the primary heaters state and sets the main primary heater duty cycle. * @details Inputs: primaryHeaterTargetTemperature @@ -588,7 +600,7 @@ { HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; F32 currentTemperature = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 targetTemperature = heatersStatus[ DG_PRIMARY_HEATER ].targetTemp; + F32 targetTemperature = heatersStatus[ heater ].targetTemp; if ( currentTemperature < targetTemperature ) { Index: firmware/App/Controllers/Heaters.h =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -58,6 +58,8 @@ F32 getHeaterTargetTemperature( DG_HEATERS_T heater ); +BOOL isHeaterOn( DG_HEATERS_T heater ); + void stopHeater( DG_HEATERS_T heater ); void execHeaters( void ); Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r72bca5d2e489fa253f3bdfdb254261a32c7a0c19 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 72bca5d2e489fa253f3bdfdb254261a32c7a0c19) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -278,8 +278,6 @@ disinfectantMixRatio = 0.0F; #ifndef _RELEASE_ - nelsonSupport = NELSON_NONE; - setNelsonSupportConditions(); #endif @@ -450,6 +448,22 @@ return status; } +#ifndef _RELEASE_ +/*********************************************************************//** + * @brief + * The setNelsonSupportMode function sets the requested Nelson support + * mode (i.e. inoculate, ...) + * @details Inputs: none + * @details Outputs: nelsonSupport + * @param support the type Nelson support (i.e. inoculate, heat disinfect) + * @return none + *************************************************************************/ +void setChemNelsonSupportMode( NELSON_SUPPORT_T support ) +{ + nelsonSupport = support; +} +#endif + // ********** private functions ********** /*********************************************************************//** @@ -575,7 +589,14 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - turnOnUVReactor( INLET_UV_REACTOR ); + +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_POS_CONTROL_CHEM_DISINFECT ) +#endif + { + turnOnUVReactor( INLET_UV_REACTOR ); + } + stateTrialCounter = 0; stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_FLUSH_DRAIN; @@ -613,11 +634,18 @@ // set pumps and valves for next state, flush circulation setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - // Start heating the water while we are flushing - 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( OUTLET_UV_REACTOR ); + +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_POS_CONTROL_CHEM_DISINFECT ) +#endif + { + // Start heating the water while we are flushing + 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( OUTLET_UV_REACTOR ); + } + flushCircWaitTime = FLUSH_CICRCULATION_INITIAL_WAIT_TIME_MS; stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_STATE_FLUSH_CIRCULATION; @@ -746,7 +774,7 @@ handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); #ifndef _RELEASE_ - if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) || + if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) && ( nelsonSupport != NELSON_POS_CONTROL_CHEM_DISINFECT ) ) #endif { @@ -1677,7 +1705,7 @@ } #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) + if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) && ( NELSON_NONE == nelsonSupport ) ) #endif { // If the dialysate cap is open during any state, alarm @@ -1754,20 +1782,13 @@ *************************************************************************/ static void setNelsonSupportConditions( void ) { - F32 temperature = 0.0F; - switch ( nelsonSupport ) { case NELSON_POS_CONTROL_CHEM_DISINFECT: case NELSON_CHEM_DISINFECT: - // The target temperature is set to low so the heater will turn on but it will not heat because - // we are very close to the target. Set the stop temperature to a temperature lower by a couple degrees - // make sure the timer will continuously count against the disinfection time to inoculate. - // NOTE: this is not part of the commercial code so no #defines - temperature = 20.0F; // Set the valves to start flush circulation - setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); @@ -1779,10 +1800,17 @@ setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - setHeaterTargetTemperature( DG_PRIMARY_HEATER, temperature ); - startHeater( DG_PRIMARY_HEATER ); - turnOnUVReactor( INLET_UV_REACTOR ); - turnOnUVReactor( OUTLET_UV_REACTOR ); + +#ifndef _RELEASE_ + if ( NELSON_CHEM_DISINFECT == nelsonSupport ) +#endif + { + setHeaterTargetTemperature( DG_PRIMARY_HEATER, CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C ); + startHeater( DG_PRIMARY_HEATER ); + turnOnUVReactor( INLET_UV_REACTOR ); + turnOnUVReactor( OUTLET_UV_REACTOR ); + } + flushCircWaitTime = FLUSH_CICRCULATION_INITIAL_WAIT_TIME_MS; stateTimer = getMSTimerCount(); chemDisinfectState = DG_CHEM_DISINFECT_STATE_FLUSH_CIRCULATION; Index: firmware/App/Modes/ModeChemicalDisinfect.h =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Modes/ModeChemicalDisinfect.h (.../ModeChemicalDisinfect.h) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Modes/ModeChemicalDisinfect.h (.../ModeChemicalDisinfect.h) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -20,6 +20,7 @@ #include "DGCommon.h" #include "DGDefs.h" +#include "ModeHeatDisinfect.h" /** * @defgroup DGChemicalDisinfectMode DGChemicalDisinfectMode @@ -48,6 +49,10 @@ BOOL stopChemicalDisinfect( void ); +#ifndef _RELEASE_ +void setChemNelsonSupportMode( NELSON_SUPPORT_T support ); +#endif + /**@}*/ #endif Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r72bca5d2e489fa253f3bdfdb254261a32c7a0c19 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 72bca5d2e489fa253f3bdfdb254261a32c7a0c19) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -80,8 +80,9 @@ // Target temperature #define HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C 90.0F ///< Heat disinfect primary heater target temperature in C. -#define HEAT_DISINFECT_TRIM_HEATER_TARGET_TEMP_C 82.0F ///< Heat disinfect trimmer heater target temperature in C. +#define HEAT_DISINFECT_TRIM_HEATER_TARGET_TEMP_C 90.0F ///< Heat disinfect trimmer heater target temperature in C. #define HEAT_DISINFECT_CONC_PUMPS_START_TEMP_C 75.0F ///< Heat disinfect start concentrate pumps target temperature in C. +#define HEAT_DISINFECT_TRIMMER_HEATER_STOP_TEMP_C 75.0F ///< Heat disinfect trimmer heater stop temperature in C. #define HEAT_DISINFECT_START_TEMP_AT_77_C 77.0F ///< Heat disinfect start disinfect at 77 C in C. #define HEAT_DISINFECT_STOP_TEMP_AT_76_C 76.0F ///< Heat disinfect stop disinfect at 76 C in C. #define HEAT_DISINFECT_START_TEMP_AT_82_C 82.0F ///< Heat disinfect start disinfect at 82 C in C. @@ -91,7 +92,7 @@ #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F ///< Heat disinfect target RO flow rate in L/min. #define HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM 0.8F ///< Heat disinfect target RO flow rate in L/min when transferring between reservoirs. #define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. -#define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. +#define HEAT_DISINFECT_START_TEMP_TIMEOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 100.0F ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. @@ -141,15 +142,6 @@ NUM_OF_HEAT_DISINFECT_TIMES ///< Number of heat disinfect times. } HEAT_DISINFECT_TIMES_T; -/// Heat disinfect reset time enum -typedef enum Heat_Disinfect_Reset_Time -{ - RESET_NONE = 0, ///< Heat disinfect reset no disinfect timer. - RESET_RO, ///< Heat disinfect reset RO disinfect timers. - RESET_RSRVR, ///< Heat disinfect reset reservoirs disinfect timers. - NUM_OF_RESETS ///< Number of heat disinfect resets. -} RESET_DISINFECT_TIMES_T; - /// Non-volatile write structure typedef struct { @@ -192,6 +184,8 @@ static U32 tempGradOutOfRangeTimer; ///< Temperature gradient out of range start timer. static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. static HEAT_DISINFECT_TIME_STATUS_T timeStatus[ NUM_OF_HEAT_DISINFECT_TIMES ]; ///< Heat disinfect time status. +static F32 concPumpsStartTemperatureC; ///< Heat disinfect concentrate pumps start temperature in C. +static BOOL isRODisinfectDone; ///< Heat disinfect is RO disinfect done flag. #ifndef _RELEASE_ static NELSON_SUPPORT_T nelsonSupport; ///< Nelson support. @@ -223,7 +217,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T reservoir, F32 targetVol, U32 timeout ); static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ); static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ); -static BOOL hasDisinfectTimeElapsed( HEAT_DISINFECT_TIMES_T disinfectTime, RESET_DISINFECT_TIMES_T reset ); +static BOOL hasDisinfectTimeElapsed( HEAT_DISINFECT_TIMES_T disinfectTime ); static void publishHeatDisinfectData( void ); static void monitorModeHeatDisinfect( void ); static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); @@ -238,15 +232,15 @@ * The initHeatDisinfectMode function initializes the heat disinfect mode * module. * @details Inputs: none - * @details Outputs: heatDisinfectState, stateTimer, + * @details Outputs: heatDisinfectState, stateTimer, isRODisinfectDone * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, * rsrvr1RefVolML, rsrvr2RefVolML, overallHeatDisinfectTimer, * cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, heatDisinfectTimer * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer, areRsrvrsLeaking * haveDrainParamsBeenInit, tempGradOutOfRangeTimer, disinfectNVOps, - * dataPublishCounter, timeStatus + * dataPublishCounter, timeStatus, concPumpsStartTemperatureC * @return none *************************************************************************/ void initHeatDisinfectMode( void ) @@ -275,11 +269,9 @@ rsrvrsVolMonitorTimer = 0; areRsrvrsLeaking = FALSE; dataPublishCounter = 0; + concPumpsStartTemperatureC = HEAT_DISINFECT_CONC_PUMPS_START_TEMP_C; + isRODisinfectDone = FALSE; -#ifndef _RELEASE_ - nelsonSupport = NELSON_NONE; -#endif - // Initialize the disinfect times timeStatus[ RO_AT_77_C ].startTempC = HEAT_DISINFECT_START_TEMP_AT_77_C; timeStatus[ RO_AT_77_C ].startTimeMS = 0; @@ -745,9 +737,15 @@ setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - setHeaterTargetTemperature( DG_PRIMARY_HEATER, HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C ); - startHeater( DG_PRIMARY_HEATER ); +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_INOCULATE ) +#endif + { + setHeaterTargetTemperature( DG_PRIMARY_HEATER, HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C ); + startHeater( DG_PRIMARY_HEATER ); + } + // Set the NV data to FLASE to be able to write another NV data ops disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; stateTimer = getMSTimerCount(); @@ -993,14 +991,19 @@ setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VRD2, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); turnOnUVReactor( INLET_UV_REACTOR ); // Turn on the RO pump setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - // Start heating the water while we are filling up the reservoirs - setHeaterTargetTemperature( DG_PRIMARY_HEATER, HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C ); - startHeater( DG_PRIMARY_HEATER ); +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_INOCULATE ) +#endif + { + // Start heating the water while we are filling up the reservoirs + setHeaterTargetTemperature( DG_PRIMARY_HEATER, HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C ); + startHeater( DG_PRIMARY_HEATER ); + } rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; @@ -1050,7 +1053,6 @@ if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { turnOffUVReactor( INLET_UV_REACTOR ); - // Set the valves to drain R2 and no fill setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); @@ -1060,6 +1062,14 @@ // Set the drain pump to control mode setDrainPumpTargetOutletFlowLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM ); +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_INOCULATE ) +#endif + { + setHeaterTargetTemperature( DG_TRIMMER_HEATER, HEAT_DISINFECT_TRIM_HEATER_TARGET_TEMP_C ); + startHeater( DG_TRIMMER_HEATER ); + } + stateTimer = getMSTimerCount(); rsrvrsVolMonitorTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; @@ -1096,11 +1106,6 @@ DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; HEAT_DISINFECT_STATUS_T status = getHeatDisinfectStatus(); - // Constantly check the status of the RO disinfect times and do not reset its start time - // in case it elapsed before disinfecting the reservoirs. - hasDisinfectTimeElapsed( RO_AT_77_C, RESET_NONE ); - hasDisinfectTimeElapsed( RO_AT_82_C, RESET_NONE ); - if ( FALSE == isROPumpRunning() ) { setROPumpTargetDutyCycle( HEAT_DISINFECT_TARGET_RO_PUMP_DC ); @@ -1139,17 +1144,20 @@ 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. - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; - stateTimer = getMSTimerCount(); - rsrvr1RefVolML = 0.0F; - rsrvr2RefVolML = 0.0F; - // Reset the timer for the next disinfect state - tempGradOutOfRangeTimer = 0; - state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; + rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; + stateTimer = getMSTimerCount(); + rsrvr1RefVolML = 0.0F; + rsrvr2RefVolML = 0.0F; + tempGradOutOfRangeTimer = 0; + state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + timeStatus[ RSRVR_AT_77_C ].startTimeMS = 0; + timeStatus[ RSRVR_AT_82_C ].startTimeMS = 0; break; case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: @@ -1180,11 +1188,6 @@ heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_TRANSITION_HOT_WATER; - // Constantly check the status of the RO disinfect times and do not reset its start time - // in case it elapsed before disinfecting the reservoirs. - hasDisinfectTimeElapsed( RO_AT_77_C, RESET_NONE ); - hasDisinfectTimeElapsed( RO_AT_82_C, RESET_NONE ); - // First reservoir 1 must be partially full if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -1232,15 +1235,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; HEAT_DISINFECT_STATUS_T status = getHeatDisinfectStatus(); - BOOL isRODisinfectDone = FALSE; heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2; - // Constantly check the status of the RO disinfect times and do not reset its start time - // in case it elapsed before disinfecting the reservoirs. - isRODisinfectDone |= hasDisinfectTimeElapsed( RO_AT_77_C, RESET_NONE ); - isRODisinfectDone |= hasDisinfectTimeElapsed( RO_AT_82_C, RESET_NONE ); - if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ) ) { if ( ( rsrvr1RefVolML < NEARLY_ZERO ) && ( rsrvr2RefVolML < NEARLY_ZERO ) ) @@ -1261,18 +1258,22 @@ break; case HEAT_DISINFECT_COMPLETE: + if ( TRUE == isRODisinfectDone ) { - // RO disinfect has been elapsed, call the function to reset the RO start time - hasDisinfectTimeElapsed( RO_AT_77_C, RESET_RO ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); stopHeater( DG_PRIMARY_HEATER ); + stopHeater( DG_TRIMMER_HEATER ); - rsrvr1RefVolML = 0.0F; - rsrvr2RefVolML = 0.0F; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; + timeStatus[ RSRVR_AT_77_C ].startTimeMS = 0; + timeStatus[ RSRVR_AT_82_C ].startTimeMS = 0; + timeStatus[ RO_AT_77_C ].startTimeMS = 0; + timeStatus[ RO_AT_82_C ].startTimeMS = 0; + rsrvr1RefVolML = 0.0F; + rsrvr2RefVolML = 0.0F; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; } #ifndef _RELEASE_ if ( NELSON_INOCULATE == nelsonSupport ) @@ -1294,6 +1295,11 @@ rsrvr2RefVolML = 0.0F; state = DG_NELSON_HEAT_DISINFECT_STATE_FILL_R1_WITH_WATER; } + else if ( NELSON_HEAT_DISINFECT == nelsonSupport ) + { + deenergizeActuators( PARK_CONC_PUMPS ); + state = DG_HEAT_DISINFECT_STATE_COMPLETE; + } #endif break; @@ -1663,7 +1669,7 @@ { 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 if ( ( DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1 == heatDisinfectState) && ( DG_RESERVOIR_2 == reservoir ) ) @@ -1770,15 +1776,16 @@ static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ) { HEAT_DISINFECT_STATUS_T status = HEAT_DISINFECT_HEAT_UP_IN_PROGRESS; - F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + F32 TPoTempC = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + F32 ThdTempC = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + F32 TDiTempC = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); F32 loadCellA1 = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); F32 loadCellB1 = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); BOOL isR1OutOfRange = ( fabs( loadCellA1 - rsrvr1RefVolML ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); BOOL isR2OutOfRange = ( fabs( loadCellB1 - rsrvr2RefVolML ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); - BOOL isGradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ? TRUE : FALSE ); + BOOL isGradientOutOfRange = ( fabs( TPoTempC - ThdTempC ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ? TRUE : FALSE ); - if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMOUT_MS ) ) + if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMEOUT_MS ) ) { // Heating up to minimum temperature for heat disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; @@ -1833,12 +1840,30 @@ } } + if ( ALARM_ID_NO_ALARM == alarmDetectedPendingTrigger ) + { +#ifndef _RELEASE_ + if ( nelsonSupport != NELSON_INOCULATE ) +#endif + { + if ( TDiTempC >= HEAT_DISINFECT_TRIMMER_HEATER_STOP_TEMP_C ) + { + stopHeater( DG_TRIMMER_HEATER ); + } + else if ( ( TDiTempC < HEAT_DISINFECT_TRIMMER_HEATER_STOP_TEMP_C ) && ( FALSE == isHeaterOn( DG_TRIMMER_HEATER ) ) ) + { + setHeaterTargetTemperature( DG_TRIMMER_HEATER, HEAT_DISINFECT_TRIM_HEATER_TARGET_TEMP_C ); + startHeater( DG_TRIMMER_HEATER ); + } + } + } + // Perform check if no pending alarm if ( ALARM_ID_NO_ALARM == alarmDetectedPendingTrigger ) { BOOL disinfectStatus = FALSE; - if ( TPoTemp >= HEAT_DISINFECT_CONC_PUMPS_START_TEMP_C ) + if ( TPoTempC >= concPumpsStartTemperatureC ) { F32 acidSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ); F32 bicarbSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB ); @@ -1856,8 +1881,8 @@ } // Check whether the reservoir under disinfect has elapsed time. - disinfectStatus |= hasDisinfectTimeElapsed( RSRVR_AT_77_C, RESET_RSRVR ); - disinfectStatus |= hasDisinfectTimeElapsed( RSRVR_AT_82_C, RESET_RSRVR ); + disinfectStatus |= hasDisinfectTimeElapsed( RSRVR_AT_77_C ); + disinfectStatus |= hasDisinfectTimeElapsed( RSRVR_AT_82_C ); // If either of the reservoir's disinfect time has elapsed, call this section complete status = ( TRUE == disinfectStatus ? HEAT_DISINFECT_COMPLETE : status ); @@ -1874,10 +1899,9 @@ * @details Outputs: timeStatus * @param disinfectTime which is the time to check (i.e reservoir at 77 C or * RO disinfect at 82 C) - * @param reset which is the type of reset timer (i.e. reset reservoirs) * @return TRUE if the specified time has been elapsed otherwise FALSE *************************************************************************/ -static BOOL hasDisinfectTimeElapsed( HEAT_DISINFECT_TIMES_T disinfectTime, RESET_DISINFECT_TIMES_T reset ) +static BOOL hasDisinfectTimeElapsed( HEAT_DISINFECT_TIMES_T disinfectTime ) { BOOL status = FALSE; F32 temperatureValue = getTemperatureValue( timeStatus[ disinfectTime ].tempSensor ); @@ -1893,18 +1917,6 @@ } else if ( TRUE == didTimeout( timeStatus[ disinfectTime ].startTimeMS, timeStatus[ disinfectTime ].targetTimeMS ) ) { - // If either of the reservoir's disinfect has been elapsed, reset the timer for both to get ready for the next reservoir's disinfect - // The RO time is not reset because the RO disinfect time is not checked until both reservoirs are disinfected first. - if ( RESET_RO == reset ) - { - timeStatus[ RO_AT_77_C ].startTimeMS = 0; - timeStatus[ RO_AT_82_C ].startTimeMS = 0; - } - else if ( RESET_RSRVR == reset ) - { - timeStatus[ RSRVR_AT_77_C ].startTimeMS = 0; - timeStatus[ RSRVR_AT_82_C ].startTimeMS = 0; - } status = TRUE; } @@ -1966,8 +1978,12 @@ *************************************************************************/ static void monitorModeHeatDisinfect( void ) { + // Constantly check the status of the RO disinfect + isRODisinfectDone |= hasDisinfectTimeElapsed( RO_AT_77_C ); + isRODisinfectDone |= hasDisinfectTimeElapsed( RO_AT_82_C ); + #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) + if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) && ( nelsonSupport != NELSON_INOCULATE ) ) #endif { if ( ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) || ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) @@ -2031,9 +2047,10 @@ // make sure the timer will continuously count against the disinfection time to inoculate. // NOTE: this is not part of the commercial code so no #defines temperature = 20.0F; - stopTemperature = temperature - 3.0F; + stopTemperature = temperature - 5.0F; disinfectTime = 2 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND; heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + concPumpsStartTemperatureC = temperature; timeStatus[ RO_AT_77_C ].startTempC = temperature; timeStatus[ RO_AT_77_C ].startTimeMS = 0; @@ -2072,7 +2089,9 @@ signalROPumpHardStop(); setDrainPumpTargetOutletFlowLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM ); setHeaterTargetTemperature( DG_PRIMARY_HEATER, HEAT_DISINFECT_PRIM_HEATER_TARGET_TEMP_C ); + setHeaterTargetTemperature( DG_TRIMMER_HEATER, HEAT_DISINFECT_TRIM_HEATER_TARGET_TEMP_C ); startHeater( DG_PRIMARY_HEATER ); + startHeater( DG_TRIMMER_HEATER ); heatDisinfectState = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r72bca5d2e489fa253f3bdfdb254261a32c7a0c19 -re608f0a2bda2ad8df59a604a511cbd2a1c323dc3 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 72bca5d2e489fa253f3bdfdb254261a32c7a0c19) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e608f0a2bda2ad8df59a604a511cbd2a1c323dc3) @@ -4324,15 +4324,15 @@ *************************************************************************/ void handleTestDGNelsonDisinfectSupport( MESSAGE_T *message ) { - TEST_OVERRIDE_PAYLOAD_T payload; + U32 payload; BOOL result = FALSE; // verify payload length - if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + if ( sizeof( U32 ) == message->hdr.payloadLen ) { - memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + memcpy( &payload, message->payload, sizeof( U32 ) ); - NELSON_SUPPORT_T nelson = (NELSON_SUPPORT_T)payload.state.u32; + NELSON_SUPPORT_T nelson = (NELSON_SUPPORT_T)payload; switch( nelson ) { @@ -4347,12 +4347,12 @@ break; case NELSON_POS_CONTROL_CHEM_DISINFECT: - setNelsonSupportMode( nelson ); + setChemNelsonSupportMode( nelson ); requestNewOperationMode( DG_MODE_CHEM ); break; case NELSON_CHEM_DISINFECT: - setNelsonSupportMode( nelson ); + setChemNelsonSupportMode( nelson ); requestNewOperationMode( DG_MODE_CHEM ); break;