Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r45a4f6517bd771cde7cba75c9150acef8176fa13 -r750a8b61a1e9a63823ecc6ed441cd01524ffc02b --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 45a4f6517bd771cde7cba75c9150acef8176fa13) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 750a8b61a1e9a63823ecc6ed441cd01524ffc02b) @@ -49,6 +49,7 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define RO_PUMP_400_ML_PER_MIN 400.0F ///< RO pump speed of 400.0 mL/minute. #define RO_PUMP_800_ML_PER_MIN 800.0F ///< RO pump speed of 800.0 mL/minute. +#define TARGET_RO_FLOW_RATE_IN_PAUSE_L 0.3F ///< Target flow rate for RO pump during pause in liters. #define MILLILITERS_PER_LITER 1000.0F ///< One liter is 1000 milliliters #define ACID_PUMP_20_ML_PER_MIN 20.0F ///< Acid pump speed of 20.0 mL/minute. #define BICARB_PUMP_40_ML_PER_MIN 40.0F ///< Bicarb pump speed of 40.0 mL/minute. @@ -68,13 +69,11 @@ #define RO_PUMP_LOOKUP_TABLE_SIZE 4 ///< Size of array used as RO pump speed lookup table. #define CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN 5.0F ///< Concentrate pump additional speed during priming in mL/min. #define CONCENTRATE_TEST_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Concentrate test time out period in ms. -#define WATER_QUALITY_TEST_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Inlet water quality test time out period in ms. #define PRIME_CONCENTRATE_LINES_TIME_OUT_MS ( 95 * MS_PER_SECOND ) ///< Time required to prime the concentrate lines. #define FLUSH_BUBBLES_PUMP_TIME_OUT_MS ( 2 * MS_PER_SECOND ) ///< RO pump on during flush bubble interval in ms. #define DIALYSATE_TEMPERATURE_TOLERANCE_C 2.0F ///< Dialysate temperature tolerance in degree C. #define DIALYSATE_TEMPERATURE_SENSORS_MAX_DRIFT_C 2.0F ///< Dialysate temperature sensors maximum allowed drift in C. -#define DIALYSATE_TEMPERATURE_SENSORS_DRIFT_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature sensors drift timeout in milliseconds. - +#define DIALYSATE_TEMP_SNSRS_OUT_OF_RANGE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature sensors drift timeout in milliseconds. #define DATA_PUBLISH_COUNTER_START_COUNT 63 ///< Data publish counter start count. /// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. @@ -105,13 +104,12 @@ static F32 reservoirBaseWeight; ///< Fill reservoir base weight. static FILL_CONDITION_STATUS_T fillStatus; ///< Fill condition status. -static U32 waterQualityTestStartTime; ///< Starting time for inlet water quality test. static U32 concentrateTestStartTime; ///< Starting time for concentrate test. static U32 concentratePrimingStartTime; ///< Starting time for concentrate priming. static U32 flushBubblesStartTime; ///< Starting time for flush bubbles. static U32 concentratePumpPrimeCount; ///< Interval count for concentrate pump prime. -static F32 integratedVolumeML; ///< Total RO flow rate over period of time. +static F32 integratedVolumeML; ///< Total RO flow rate over period of time. static F32 acidConductivityTotal; ///< Total of acid conductivity during fill. static F32 bicarbConductivityTotal; ///< Total of bicarb conductivity during fill. static U32 conductivitySampleCount; ///< Sample count of conductivity during fill. @@ -127,12 +125,12 @@ static F32 totalAcidConductivity; ///< Total acid conductivity over 30 seconds. static U32 pumpSpeedIndex; ///< Index used to access the desired pump speed in roPumpFlushBubblesSpeed table. +static BOOL havePauseActuatorsBeenSet; ///< Flag to indicate the actuators have been set to pause for the first time. static OVERRIDE_F32_T usedAcidVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated acid concentration volume has been used in mL. static OVERRIDE_F32_T usedBicarbVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated bicarb concentration volume has been used in mL. static OVERRIDE_U32_T fillModeDataPublishInterval = { FILL_MODE_DATA_PUB_INTERVAL, - FILL_MODE_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish fill mode data to CAN bus. + FILL_MODE_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish fill mode data to CAN bus. // ********** private function prototypes ********** @@ -145,7 +143,8 @@ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ); static DG_FILL_MODE_STATE_T handlePausedState( void ); -static void checkDialysateTemperatureSensorsDrift( void ); +static BOOL areInletWaterConditionsOutOfRange( void ); +static void checkDialysateTemperatureSensors( void ); static void handleDialysateMixing( F32 measuredROFlowRate_mL_min ); static void setFillInfoToRTCRAM( void ); static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ); @@ -157,7 +156,7 @@ * @details Inputs: none * @details Outputs: fillState, dialysateFillStartTime, reservoirBaseWeight, * totalROFlowRateMLPM, concentrateTestStartTime, acidConductivityTotal, - * bicarbConductivityTotal, conductivitySampleCount, + * bicarbConductivityTotal, conductivitySampleCount, havePauseActuatorsBeenSet * concentratePumpPrimeCount * @return none *************************************************************************/ @@ -167,7 +166,7 @@ dialysateFillStartTime = 0; dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; reservoirBaseWeight = 0.0; - integratedVolumeML = 0.0; + integratedVolumeML = 0.0; concentrateTestStartTime = 0; acidConductivityTotal = 0.0; bicarbConductivityTotal = 0.0; @@ -181,8 +180,9 @@ acidConductivitySampleCount = 0; totalBicarbConductivity = 0.0; totalAcidConductivity = 0.0; + havePauseActuatorsBeenSet = FALSE; - initPersistentAlarm( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_DRIFT_TIMEOUT, 0, DIALYSATE_TEMPERATURE_SENSORS_DRIFT_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, 0, DIALYSATE_TEMP_SNSRS_OUT_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** @@ -228,26 +228,22 @@ *************************************************************************/ U32 execFillMode( void ) { - // Check inlet water conductivity, temperature, pressure, and RO rejection ratio - checkInletWaterConductivity(); - checkInletWaterTemperature(); - checkInletPressure(); checkRORejectionRatio(); - checkDialysateTemperatureSensorsDrift(); + checkDialysateTemperatureSensors(); // TODO: Check for open straw door status and alarm if closed // Check if run out of time to fill the reservoir if ( TRUE == didTimeout( dialysateFillStartTime, DIALYSATE_FILL_TIME_OUT ) ) { activateAlarmNoData( ALARM_ID_DG_DIALYSATE_FILL_OUT_OF_TIME ); - requestNewOperationMode( DG_MODE_GENE ); } + fillState = ( TRUE == areInletWaterConditionsOutOfRange() ? DG_FILL_MODE_STATE_PAUSED : fillState ); + // Execute current Fill state switch ( fillState ) { case DG_FILL_MODE_STATE_START: - waterQualityTestStartTime = getMSTimerCount(); fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; break; @@ -343,6 +339,7 @@ void resetFillStatusParameters( void ) { DG_HEATERS_RECORD_T heaterInfo; + // There is no number of NV data to check for the heaters info so it is passed as 0 U08 numOfNVData2Check = 0; // Get the heaters info from the NV data management. Do not alarm on the status of the data since it has already been checked in NV POST @@ -355,9 +352,9 @@ fillStatus.fillTemperatureRunningSum = 0.0; // At the beginning the last and average temperatures are considered as the trimmer heater target temperature which // is the dialysate temperature - fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); - fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; - fillStatus.isThisFirstFill = TRUE; + fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); + fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; + fillStatus.isThisFirstFill = TRUE; } /*********************************************************************//** @@ -454,7 +451,7 @@ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); // TODO if + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); concentratePrimingStartTime = getMSTimerCount(); @@ -469,15 +466,6 @@ result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; } - // TODO get back to this -#ifndef DISABLE_DIALYSATE_CHECK - if ( TRUE == didTimeout( waterQualityTestStartTime, WATER_QUALITY_TEST_TIME_OUT_MS ) ) - { - activateAlarmNoData( ALARM_ID_DG_BAD_INLET_WATER_QUALITY ); // alarm is recoverable should go to fill paused state - result = DG_FILL_MODE_STATE_PAUSED; // paused state should go back to DG_FILL_MODE_STATE_TEST_INLET_WATER - } // when alarm acknowledged -#endif - return result; } @@ -777,41 +765,81 @@ * @brief * The handlePausedState function executes the paused state of the fill * mode state machine. - * @details Inputs: Empty bottle alarm active - * @details Outputs: none + * @details Inputs: havePauseActuatorsBeenSet + * @details Outputs: havePauseActuatorsBeenSet * @return the next state *************************************************************************/ static DG_FILL_MODE_STATE_T handlePausedState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_PAUSED; - if ( FALSE == isAlarmActive( ALARM_ID_DG_BAD_INLET_WATER_QUALITY ) ) + if ( FALSE == havePauseActuatorsBeenSet ) { - result = DG_FILL_MODE_STATE_TEST_INLET_WATER; + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_IN_PAUSE_L, TARGET_RO_PRESSURE_PSI ); + + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + + havePauseActuatorsBeenSet = TRUE; } + if ( FALSE == areInletWaterConditionsOutOfRange() ) + { + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + + havePauseActuatorsBeenSet = FALSE; + result = DG_FILL_MODE_STATE_START; + } + + return result; } /*********************************************************************//** * @brief - * The checkDialysateTemperatureSensorsDrift function checks whether the + * The areInletWaterConditionsOutOfRange function checks whether the inlet + * water conditions are in range. + * @details Inputs: none + * @details Outputs: None + * @return TRUE if the inlet water conditions are in range otherwise, FALSE + *************************************************************************/ +static BOOL areInletWaterConditionsOutOfRange( void ) +{ + // Check inlet water conductivity, temperature, pressure, and RO rejection ratio + BOOL status = FALSE; + BOOL inletConductivityStatus = isInletWaterConductivityInRange(); + BOOL inletTemperatureStatus = isInletWaterTemperatureInRange(); + BOOL inletPressureStatus = isInletPressureInRange(); + + // If any of the inlet water conditions that are recoverable are not met, transition to pause mode + if ( ( FALSE == inletConductivityStatus ) || ( FALSE == inletTemperatureStatus ) || ( FALSE == inletPressureStatus ) ) + { + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The checkDialysateTemperatureSensors function checks whether the * dialysate temperature sensors have drifted. If they are drifted, it raises * an alarm. * @details Inputs: none * @details Outputs: None * @return none *************************************************************************/ -static void checkDialysateTemperatureSensorsDrift( void ) +static void checkDialysateTemperatureSensors( void ) { #ifndef THD_USING_TRO_CONNECTOR // Do not use until TRo is back in line F32 TDi = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); F32 TRo = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); BOOL isDriftOut = ( fabs( TDi - TRo ) >= DIALYSATE_TEMPERATURE_SENSORS_MAX_DRIFT_C ? TRUE : FALSE ); - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_DRFIT_TIMEOUT, isDriftOut ) ) + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, isDriftOut ) ) { - activateAlarmNoData( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_DRFIT_TIMEOUT ); + activateAlarmNoData( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE ); } #endif }