Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -re66857bf3bbc6be73802ca6596cbb9444541e21f -rfd5c3cff1d0beac03fb29c19f49f670568bc4178 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e66857bf3bbc6be73802ca6596cbb9444541e21f) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision fd5c3cff1d0beac03fb29c19f49f670568bc4178) @@ -264,10 +264,8 @@ *************************************************************************/ void stopPrimaryHeater( void ) { - mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); - setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + setMainPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); + setSmallPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); isPrimaryHeaterOn = FALSE; } @@ -280,8 +278,7 @@ *************************************************************************/ void stopTrimmerHeater( void ) { - trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setTrimmerHeaterPWM( trimmerHeaterDutyCycle ); + setTrimmerHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); isTrimmerHeaterOn = FALSE; } @@ -633,6 +630,9 @@ if ( isPrimaryHeaterOn != TRUE ) { + // Switch to off state. Set the duty cycles to 0 + mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; state = PRIMARY_HEATERS_EXEC_STATE_OFF; } @@ -694,6 +694,8 @@ if ( ! isTrimmerHeaterOn ) { + // Set the duty cycle to 0 and switch to off state + trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; state = TRIMMER_HEATER_EXEC_STATE_OFF; } Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -rfb79cc82233d712817d0c9ff6567253aa65bd622 -rfd5c3cff1d0beac03fb29c19f49f670568bc4178 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision fb79cc82233d712817d0c9ff6567253aa65bd622) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision fd5c3cff1d0beac03fb29c19f49f670568bc4178) @@ -596,6 +596,7 @@ // If it is out, go back to ramp up state and to try to reach to target flow again if ( ( targetROPumpMaxPressure - actualPressure ) > MAX_PRESSURE_TARGET_TOLERANCE ) { + resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet ); state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; roControlTimerCounter = 0; @@ -604,7 +605,6 @@ return state; } - /*********************************************************************//** * @brief * The handleROPumpOpenLoopState function handles the open loop state of Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -rfb79cc82233d712817d0c9ff6567253aa65bd622 -rfd5c3cff1d0beac03fb29c19f49f670568bc4178 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision fb79cc82233d712817d0c9ff6567253aa65bd622) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision fd5c3cff1d0beac03fb29c19f49f670568bc4178) @@ -32,11 +32,11 @@ // ********** private definitions ********** -#define PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN 16U ///< Primary heater external temperature sensors gain. +#define PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN 8U ///< Primary heater external temperature sensors gain. #define PRIMARY_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE 19600U ///< Primary heater external temperature sensors reference resistance. #define PRIMARY_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE 1000U ///< Primary heater external temperature sensors zero degree resistance. -#define COND_SENSORS_TEMP_SENSOR_GAIN 16U ///< Temperature sensor for conductivity gain. +#define COND_SENSORS_TEMP_SENSOR_GAIN 8U ///< Temperature sensor for conductivity gain. #define COND_SENSORS_TEMP_SENSOR_REF_RESISTANCE 19600U ///< Temperature sensor for conductivity reference resistance. #define COND_SENSORS_TEMP_SENSOR_0_DEGREE_RESISTANCE 1000U ///< Temperature sensor for conductivity zero degree resistance. @@ -76,56 +76,55 @@ #define TEMPERATURE_SENSORS_INTERNAL_ERROR_PERSISTENT_PERIOD ( 3 * MS_PER_SECOND ) ///< Temperature sensors internal error persistent period. #define FPGA_RAW_ADC_READ_INTERVAL_COUNT 8 ///< Time interval in counts to read the raw ADC reads from FPGA. - /// Temperature sensor self-test states. typedef enum tempSensors_Self_Test_States { - TEMPSENSORS_SELF_TEST_START = 0, ///< Temperature sensors self-test start - TEMPSENSORS_SELF_TEST_ADC_CHECK, ///< Temperature sensors self ADC check - TEMPSENSORS_SELF_TEST_COMPLETE, ///< Temperature sensors self-test complete - NUM_OF_TEMPSENSORS_SELF_TEST_STATES ///< Total number of self-test states + TEMPSENSORS_SELF_TEST_START = 0, ///< Temperature sensors self-test start + TEMPSENSORS_SELF_TEST_ADC_CHECK, ///< Temperature sensors self ADC check + TEMPSENSORS_SELF_TEST_COMPLETE, ///< Temperature sensors self-test complete + NUM_OF_TEMPSENSORS_SELF_TEST_STATES ///< Total number of self-test states } TEMPSENSORS_SELF_TEST_STATES_T; /// Temperature sensor exec states. typedef enum tempSensors_Exec_States { - TEMPSENSORS_EXEC_STATE_START = 0, ///< Temperature sensors exec start - TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES, ///< Temperature sensors exec get ADC values - NUM_OF_TEMPSENSORS_EXEC_STATES, ///< Total number of exec states + TEMPSENSORS_EXEC_STATE_START = 0, ///< Temperature sensors exec start + TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES, ///< Temperature sensors exec get ADC values + NUM_OF_TEMPSENSORS_EXEC_STATES, ///< Total number of exec states } TEMPSENSORS_EXEC_STATES_T; /// Temperature sensor struct. typedef struct { - F32 gain; ///< ADC gain - F32 refResistance; ///< ADC reference resistance - F32 conversionCoeff; ///< ADC conversion coefficient - F32 zeroDegreeResistance; ///< ADC zero degree resistance - S32 rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES ]; ///< Raw ADC reads array - S32 adcNextIndex; ///< Next ADC read index - S32 adcRunningSum; ///< ADC running sum - U32 readCount; ///< Read counts from FPGA - OVERRIDE_F32_T temperatureValues; ///< Temperature values with override + F32 gain; ///< ADC gain + F32 refResistance; ///< ADC reference resistance + F32 conversionCoeff; ///< ADC conversion coefficient + F32 zeroDegreeResistance; ///< ADC zero degree resistance + S32 rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES ]; ///< Raw ADC reads array + S32 adcNextIndex; ///< Next ADC read index + S32 adcRunningSum; ///< ADC running sum + U32 readCount; ///< Read counts from FPGA + OVERRIDE_F32_T temperatureValues; ///< Temperature values with override } TEMP_SENSOR_T; // ********** private data ********** -static SELF_TEST_STATUS_T tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Self-test result of the TemperatureSensors module. -static TEMPSENSORS_SELF_TEST_STATES_T tempSensorsSelfTestState; ///< TemperatureSensor self-test state. -static TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. -static TEMP_SENSOR_T tempSensors [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors' data structure. -static U32 fpgaRawADCReadInterval = 0; ///< FPGA raw ADC read interval count. -static U32 elapsedTime = 0; ///< Elapsed time variable. -static U32 internalHeatersConversionTimer = 0; ///< Conversion timer variable to calculate the heaters internal temperature. +static SELF_TEST_STATUS_T tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Self-test result of the TemperatureSensors module. +static TEMPSENSORS_SELF_TEST_STATES_T tempSensorsSelfTestState; ///< TemperatureSensor self-test state. +static TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. +static TEMP_SENSOR_T tempSensors [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors' data structure. +static U32 fpgaRawADCReadInterval = 0; ///< FPGA raw ADC read interval count. +static U32 elapsedTime = 0; ///< Elapsed time variable. +static U32 internalHeatersConversionTimer = 0; ///< Conversion timer variable to calculate the heaters internal temperature. -static F32 tempValuesForPublication [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors data publication array. -static U32 dataPublicationTimerCounter; ///< Temperature sensors data publish timer counter. +static F32 tempValuesForPublication [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors data publication array. +static U32 dataPublicationTimerCounter; ///< Temperature sensors data publish timer counter. static OVERRIDE_U32_T tempSensorsPublishInterval = { TEMP_SENSORS_DATA_PUBLISH_INTERVAL, - TEMP_SENSORS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Temperature sensors publish time interval override. + TEMP_SENSORS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Temperature sensors publish time interval override. -static const F32 POSITIVE_TC_EXP_A0 = 0.118597600000E0; ///< K TC positive temperature exponent coefficient A0. -static const F32 POSITIVE_TC_EXP_A1 = -0.118343200000E-3; ///< K TC positive temperature exponent coefficient A1. -static const F32 POSITIVE_TC_EXP_A2 = 0.126968600000E3; ///< K TC positive temperature exponent coefficient A2. +static const F32 POSITIVE_TC_EXP_A0 = 0.118597600000E0; ///< K TC positive temperature exponent coefficient A0. +static const F32 POSITIVE_TC_EXP_A1 = -0.118343200000E-3; ///< K TC positive temperature exponent coefficient A1. +static const F32 POSITIVE_TC_EXP_A2 = 0.126968600000E3; ///< K TC positive temperature exponent coefficient A2. static const F32 POSITIVE_TC_COEFFS [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = { @@ -134,18 +133,18 @@ 0.318409457190E-9, -0.560728448890E-12, 0.560750590590E-15,-0.320207200030E-18, 0.971511471520E-22,-0.121047212750E-25 -}; ///< Thermocouple correction coefficients for positive cold junction temperature. +}; ///< Thermocouple correction coefficients for positive cold junction temperature. static const F32 POSITIVE_TC_INVERSER_COEFFS [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = { 0.0, 2.508355E1, 7.860106E-2, -2.503131E-1, 8.315270E-2, -1.228034E-2, 9.804036E-4, -4.413030E-5, 1.057734E-6, -1.052755E-8 -}; ///< Thermocouple inverse coefficient for positive cold junction temperature. +}; ///< Thermocouple inverse coefficient for positive cold junction temperature. -static const U32 TEMP_SENSORS_ADC_MAX_COUNT = ( 1 << TEMP_SENSORS_ADC_BITS ) - 1; ///< ADC 24 bit max count which is (2^24 - 1). -static const U32 TEMP_EQUATION_RESISTOR_CALC = 1 << ( TEMP_SENSORS_ADC_BITS - 1 ); ///< Temperature sensors resistor calculation (2^(24 - 1)). -static const F32 TEMP_EQUATION_COEFF_A = 3.9083E-3; ///< ADC to temperature conversion coefficient A. -static const F32 TEMP_EQUATION_COEFF_B = -5.775E-7; ///< ADC to temperature conversion coefficient B. +static const U32 TEMP_SENSORS_ADC_MAX_COUNT = ( 1 << TEMP_SENSORS_ADC_BITS ) - 1; ///< ADC 24 bit max count which is (2^24 - 1). +static const U32 TEMP_EQUATION_RESISTOR_CALC = 1 << ( TEMP_SENSORS_ADC_BITS - 1 ); ///< Temperature sensors resistor calculation (2^(24 - 1)). +static const F32 TEMP_EQUATION_COEFF_A = 3.9083E-3; ///< ADC to temperature conversion coefficient A. +static const F32 TEMP_EQUATION_COEFF_B = -5.775E-7; ///< ADC to temperature conversion coefficient B. // ********** private function prototypes ********** Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rfb79cc82233d712817d0c9ff6567253aa65bd622 -rfd5c3cff1d0beac03fb29c19f49f670568bc4178 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision fb79cc82233d712817d0c9ff6567253aa65bd622) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision fd5c3cff1d0beac03fb29c19f49f670568bc4178) @@ -52,39 +52,39 @@ #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 ( 3 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo original time was 60 seconds +#define FLUSH_DRAIN_WAIT_TIME_MS ( 10 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo original time was 60 seconds #define MIN_INLET_TEMPERATURE_C 15.0 ///< Minimum water inlet temperature in C. TODO original temperature was 25 C #define MIN_INLET_CONDUCTIVITY_US_PER_CM 0.0 ///< Minimum water inlet conductivity in uS/cm #define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0 ///< Maximum water inlet conductivity in us/cm // Flush circulation path state defines #define RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM 0.8 ///< RO pump target flow rate during flush/fill in L/min. TODO original flow was 0.8 #define MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI 130 ///< Maximum RO pump pressure during flush/fill states in psi. -#define FLUSH_CICRCULATION_WAIT_TIME_MS ( 1 * MS_PER_SECOND ) ///< Flush/rinse circulation path wait time in milliseconds. TODO original time was 30 seconds +#define FLUSH_CICRCULATION_WAIT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Flush/rinse circulation path wait time in milliseconds. TODO original time was 30 seconds #define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 50.0 ///< Maximum flush circulation temperature difference tolerance in C. TODO original difference was 3.0 degrees #define NUM_OF_TEMP_SENSORS_TO_AVG 4.0 ///< Number of temperature sensors to average to check the difference. // Flush and drain R1 and R2 #define RSRVRS_FULL_VOL_ML 1800.0 ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0 ///< 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 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. +#define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. TODO original value was 5 mins #define RSRVRS_500ML_FILL_UP_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. // Fill and heat water #define HEAT_DISINFECT_TARGET_TEMPERATURE_C 85.0 ///< Heat disinfect target water temperature in C. TODO original temperature was 85.0 -#define HEAT_DISINFECT_START_TEMPERATURE_C 81.0 ///< Heat disinfect minimum acceptable temperature in C. TODO original temperature was 81.0 +#define HEAT_DISINFECT_START_TEMPERATURE_C 812.0 ///< Heat disinfect minimum acceptable temperature in C. TODO original temperature was 81.0 // R1 to R2 & R2 to R1 heat disinfect circulation #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 0.9 ///< Heat disinfect target RO flow rate in L/min. TODO original value was 0.8 #define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. -#define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 5.0 ///< Heat disinfect target drain outlet pressure in psi. +#define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 10.0 ///< Heat disinfect target drain outlet pressure in psi. #define HEAT_DISINFECT_TIME_MS ( 5 * 60 * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. TODO original time was 10 minutes #define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * 60 * 60 * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. TODO figure out this timeout #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disnfect. TODO change this to 5 seconds -#define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 100.0 ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. TODO original value is 100 mL -#define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 1 * 60 * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. +#define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 500.0 ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. TODO original value is 100 mL +#define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. // Rinse R1 to R2 #define ROF_MIN_LOW_PRESSURE_TEMPERATURE_C 45.0 ///< RO filter minimum temperature that the pressure must be no more than 30psi in C. TODO the actual value is 45.0 @@ -371,9 +371,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectStartState function handles the heat disinfect - * start state. - * @details Inputs: none - * @details Outputs: none + * start state. The state checks the inlet pressure and the difference in + * between TDi and TRo sensors and if they are not in range, it transitions + * to basic cancellation path. Otherwise, it transitions to the next + * state. + * @details Inputs: alarm, rsrvrFillStableTimeCounter, rsrvr1Status, + * stateTimer + * @details Outputs: alarm, rsrvrFillStableTimeCounter, rsrvr1Status, + * stateTimer * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStartState( void ) @@ -423,7 +428,9 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectDrainR1State function handles the heat disinfect - * drain R1 state. + * 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 Outputs: stateTimer, rsrvr1Status, rsrvr2Status * @return next state of the heat disinfect state machine @@ -482,9 +489,12 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectDrainR2State function handles the heat disinfect - * drain R2 state. - * @details Inputs: stateTimer, rsrvr2Status, isThisLastDrain - * @details Outputs: stateTimer, rsrvr2Status + * 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, + * stateTrialCounter + * @details Outputs: stateTimer, rsrvr2Status, stateTrialCounter * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDrainR2State( void ) @@ -520,9 +530,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFlushDrainState function handles the heat disinfect - * flush drain state. - * @details Inputs: stateTimer, stateTrialCounter - * @details Outputs: stateTimer, stateTrialCounter + * flush drain state. The state flushes the drain line for a period of time + * and then measure the temperature and conductivity of water. If they are + * not within the range, it transitions to basic cancellation path, otherwise + * it transitions to the next state. + * @details Inputs: stateTimer, stateTrialCounter, alarm, + * prevHeatDisinfectState + * @details Outputs: stateTimer, stateTrialCounter, alarm, + * prevHeatDisinfectState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFlushDrainState( void ) @@ -533,8 +548,8 @@ if ( didTimeout( stateTimer, FLUSH_DRAIN_WAIT_TIME_MS ) ) { // If the inlet temperature and conductivity are in range, move onto the next state - if ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) > MIN_INLET_TEMPERATURE_C /*&& TODO un-comment when the conductivity sensor is reading correctly - getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) > MIN_INLET_CONDUCTIVITY_US_PER_CM*/ ) + if ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) > MIN_INLET_TEMPERATURE_C && + getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) > MIN_INLET_CONDUCTIVITY_US_PER_CM ) { setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setROPumpTargetFlowRate( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); @@ -562,9 +577,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFlushCirculationState function handles the heat - * disinfect flush circulation state. - * @details Inputs: stateTimer, stateTrialCounter - * @details Outputs: stateTimer, stateTrialCounter + * disinfect flush circulation state. The state flushes the circulation + * line for a period of time. After the flush if the temperature sensors + * are not within a certain degrees from each other, the state transitions + * to basic cancellation path, otherwise, it transitions to the next state. + * @details Inputs: stateTimer, stateTrialCounter, prevHeatDisinfectState + * alarm, areTempSensorsInRange, rsrvr1Status, rsrvr2Status + * @details Outputs: stateTimer, stateTrialCounter, prevHeatDisinfectState, + * alarm, areTempSensorsInRange, rsrvr1Status, rsrvr2Status * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFlushCirculationState( void ) @@ -574,7 +594,7 @@ // Check if the flush circulation time has elapsed and the temperature sensors are not in range yet if ( didTimeout( stateTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) && FALSE == areTempSensorsInRange ) { - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); // TODO add TPm later. This is the new temp sensor of the coldest spot. It is temporarily TDi. + F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); // TODO add THd later. This is the new temp sensor of the coldest spot. F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); F32 TD1Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ); F32 TD2Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); @@ -633,9 +653,13 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFlushR1AndR2State function handles the heat - * disinfect flush reservoir 1 and reservoir 2 state. - * @details Inputs: stateTimer, isR1Full, isR2Full - * @details Outputs: stateTimer, isR1Full, isR2Full + * disinfect flush reservoir 1 and reservoir 2 state. If the reservoirs + * did not flush within a period time, the state transitions to water + * cancellation path. + * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status, + * prevHeatDisinfectState + * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, + * prevHeatDisinfectState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFlushR1AndR2State( void ) @@ -671,16 +695,26 @@ state = DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1; } } + else if ( rsrvr1Status == RESERVOIR_STATUS_UNKNOWN || rsrvr2Status == RESERVOIR_STATUS_UNKNOWN ) + { + prevHeatDisinfectState = state; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectFlushR2AndDrainR1State function handles the heat - * disinfect flush reservoir 2 and drain reservoir 1 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect flush reservoir 2 and drain reservoir 1 state. The state + * drains reservoir 1 and flushes reservoir 2 at the same time until the + * water in reservoir 2 overflows to reservoir 1. If this process is done + * within a certain period of time, it transitions to the next state. + * If the drain process times out, it transitions to basic cancellation and + * if the flush process times out, it transitions to water cancellation. + * @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 handleHeatDisinfectFlushR2AndDrainR1State( void ) @@ -691,7 +725,7 @@ if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { @@ -737,9 +771,12 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFlushDrainR2State function handles the heat - * disinfect flush drain reservoir 2 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect flush drain reservoir 2 state. The state drains reservoir 2 + * and if the drain times out, it transitions to basic cancellation. If the + * drain is finished within a certain period of time, 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 handleHeatDisinfectFlushDrainR2State( void ) @@ -767,9 +804,12 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFlushDrainR1State function handles the heat - * disinfect flush drain reservoir 1 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect flush drain reservoir 1 state. The state drains reservoir 1 + * and if the drain times out, it transitions to basic cancellation. If the + * drain is finished within a certain period of time, 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 handleHeatDisinfectFlushDrainR1State( void ) @@ -814,9 +854,15 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFillWithWaterState function handles the heat - * disinfect fill with water state. - * @details Inputs: stateTimer, isR1Full, isR2Full - * @details Outputs: stateTimer, isR1Full, isR2Full + * disinfect fill with water state. The state fills reservoir 1 until it + * overflows to reservoir 2. If the filling process times out, it + * transitions to water cancellation state, otherwise, it transitions to + * next state. The levels of the reservoirs are recorded to be monitored + * during heat disinfect. + * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status, R1HeatDisinfectVol + * R2HeatDisinfectVol, rsrvrsVolMonitorTimer + * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status R1HeatDisinfectVol + * R2HeatDisinfectVol, rsrvrsVolMonitorTimer * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterState( void ) @@ -854,7 +900,7 @@ // Start the trimmer heater since we are recirculating water //setTrimmerHeaterTargetTemperature( HEAT_DISINFECT_TARGET_TEMPERATURE_C ); - //startTrimmerHeater(); TODO do we need this? + //startTrimmerHeater(); TODO turn the trimmer heater on when THD is implemented // 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 heat disinfect cycle @@ -873,9 +919,13 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectDisinfectR1ToR2State function handles the heat - * disinfect R1 to R2 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect R1 to R2 state. The state runs reservoir 1 to reservoir 2 + * heat disinfect. If the reservoirs leak or it cannot reach to temperature + * within a certain period of time, it transitions to water cancellation. + * If heat disinfect reservoir 1 to reservoir 2 is completed, 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 handleHeatDisinfectDisinfectR1ToR2State( void ) @@ -918,9 +968,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectFillR2WithHotWaterState function handles fill R2 - * with water state. - * @details Inputs: R1HeatDisinfectVol, R2HeatDisinfectVol - * @details Outputs: R1HeatDisinfectVol, R2HeatDisinfectVol + * with water state. The state transfers hot water from reservoir 1 to + * reservoir 2 until hot water 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, R1HeatDisinfectVol, + * R2HeatDisinfectVol + * @details Outputs: rsrvr1Status, rsrvr2Status, R1HeatDisinfectVol, + * R2HeatDisinfectVol * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillR2WithHotWaterState( void ) @@ -956,9 +1011,12 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectDisinfectR2ToR1State function handles the heat - * disinfect R2 to R1 state. - * @details Inputs: hasPostHeatDisinfectWaitStarted, stateTimer - * @details Outputs: hasPostHeatDisinfectWaitStarted, stateTimer + * 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: hasPostHeatDisinfectWaitStarted, stateTimer, rsrvr1Status + * @details Outputs: hasPostHeatDisinfectWaitStarted, stateTimer, rsrvr1Status * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR2ToR1State( void ) @@ -1020,9 +1078,11 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectMixDrainR1State function handles the heat - * disinfect mix drain R1 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect mix drain R1 state. The state drains reservoir 1 and if it + * times out, it transitions to basic 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 handleHeatDisinfectMixDrainR1State( void ) @@ -1050,9 +1110,11 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectMixDrainR2State function handles the heat - * disinfect mix drain R2 state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect mix drain R2 state. The state drains reservoir 1 and if it + * times out, it transitions to basic 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 handleHeatDisinfectMixDrainR2State( void ) @@ -1079,9 +1141,10 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectCoolDownROFilterState function handles the heat - * disinfect cool down RO filter state. - * @details Inputs: stateTimer - * @details Outputs: stateTimer + * disinfect cool down RO filter state. The state monitors the temperature + * at THd and if it is less than 45 C, 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 handleHeatDisinfectCoolDownROFilterState( void ) @@ -1117,9 +1180,11 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectRinseR1ToR2State function handles the heat - * disinfect rinse R1 to R2 state. - * @details Inputs: stateTimer, isR1Full, isR2Full - * @details Outputs: stateTimer, isR1Full, isR2Full + * 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 ) @@ -1158,9 +1223,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectRinseR2ToR1AndDrainR1State function handles the - * heat disinfect rinse R2 to R1 and drain R1 state. - * @details Inputs: stateTimer, isR1Full, isR2Full, isThisLastDrain - * @details Outputs: stateTimer, isR1Full, isR2Full, isThisLastDrain + * 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 ) @@ -1170,7 +1240,7 @@ if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { @@ -1220,7 +1290,9 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectRinseCirculationState function handles the - * heat disinfect rinse RO circulation and conectrate pumps state. + * 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 @@ -1243,9 +1315,10 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectCancelModeBasicPath function handles the - * heat disinfect cancel mode basic path state. - * @details Inputs: none - * @details Outputs: none + * heat disinfect cancel mode basic path state. The state sets the state + * to complete and raises an alarm. + * @details Inputs: cancellationMode + * @details Outputs: cancellationMode * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeBasicPath( void ) @@ -1264,9 +1337,14 @@ /*********************************************************************//** * @brief * The handleHeatDisinfectCancelModeWaterPath function handles the - * heat disinfect cancel mode cold water path state. - * @details Inputs: isR1Full, isR2Full - * @details Outputs: isR1Full, isR2Full + * heat disinfect cancel mode cold water path state. The state resets all + * the actuators. If THd > 60 C, it runs a hot water cancellation to make sure + * the water that is drained is below 60 C. Otherwise, it runs a cold water + * drain. If the drain times out, it transitions to basic cancellation state. + * If the drain is completed within the define time, it transitions to the + * complete state. + * @details Inputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer + * @details Outputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPath( void ) @@ -1394,14 +1472,14 @@ * The isRsrvrFull function checks whether the target reservoir is full or * not. If the fill times out, it sets the state machine to complete and * exits the heat disinfect mode. - * @details Inputs: none + * @details Inputs: rsrvrFillStableTimeCounter, alarm, stateTimer * @details Outputs: none - * @param r is either R1 or R2 + * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 * @param targetVol is the target fill volume * @param timeout is the fill up timeout * @param cancellationState is the cancellation state to be called in case * the operation timed out. - * @return none + * @return the status of the reservoirs during filling *************************************************************************/ static RESERVOIRS_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout, DG_HEAT_DISINFECT_STATE_T cancellationState ) { @@ -1418,19 +1496,20 @@ } // Check the volume of the reservoir against the target volume - if ( volume >= targetVol && ++rsrvrFillStableTimeCounter >= RSRVRS_FULL_STABLE_TIME_COUNT ) + if ( volume >= targetVol ) { - status = RESERVOIR_STATUS_FULL; - rsrvrFillStableTimeCounter = 0; - // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); + if ( ++rsrvrFillStableTimeCounter >= RSRVRS_FULL_STABLE_TIME_COUNT ) + { + status = RESERVOIR_STATUS_FULL; + rsrvrFillStableTimeCounter = 0; + // Set the state timer in case it needs to be used for another timeout check + stateTimer = getMSTimerCount(); + } } else if ( didTimeout( stateTimer, timeout ) ) { // Failed to fill ontime. Update the previous heat disinfect state and transition to basic cancellation alarm = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; - prevHeatDisinfectState = heatDisinfectState; - heatDisinfectState = cancellationState; status = RESERVOIR_STATUS_UNKNOWN; } @@ -1439,13 +1518,16 @@ /*********************************************************************//** * @brief - * The getRsrvrDrainStatus function returns the status of - * @details Inputs: stateTimer, prevHeatDisinfectState, heatDisinfectState - * @details Outputs: stateTimer, heatDisinfectState + * The getRsrvrDrainStatus function returns the status of draining a + * reservoir. + * @details Inputs: stateTimer, prevHeatDisinfectState, heatDisinfectState, + * alarm + * @details Outputs: stateTimer, heatDisinfectState heatDisinfectState, + * alarm * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 * @param cancellationState is the cancellation state to be called in case * the operation timed out. - * @return TRUE if the reservoir is empty otherwise, FALSE + * @return the status of the reservoirs during draining *************************************************************************/ static RESERVOIRS_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout, DG_HEAT_DISINFECT_STATE_T cancellationState ) { @@ -1474,7 +1556,12 @@ /*********************************************************************//** * @brief * The getHeatDisinfectStatus function monitors and returns the current - * stage of heat disinfect cycle. + * stage of heat disinfect cycle. If the level of the reservoirs is drifted + * consecutively for the define period of time, it sets the reservoir leak + * time out alarm. If the target temperature is not reached within the + * defined period of time, it set the temperature out of range alarm. + * If the heat disinfect has started or has elapsed, it set the status of + * heat disinfect accordingly. * @details Inputs: areRsrvrsLeaking, areRsrvrsLeaking * @details Outputs: areRsrvrsLeaking, areRsrvrsLeaking * @return status of the heat disinfect (i.e in progress, complete) @@ -1516,7 +1603,7 @@ // reset the heat disinfect timers and check whether heating up has timed out if ( ThdTemp < HEAT_DISINFECT_START_TEMPERATURE_C ) { - // Keep reseting the disinfect timer so the elapsed time is always 0 until disinfection truly starts + // Keep reseting the disinfect timer so the elapsed time is always 0 until disinfect truly starts heatDisinfectTimer = getMSTimerCount(); isPartialDisinfectInProgress = FALSE;