Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -rd502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92 -r557f409455dde035899c9f89a8b93f57e8eb7f2b --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision d502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 557f409455dde035899c9f89a8b93f57e8eb7f2b) @@ -98,6 +98,9 @@ F32 fillLastTemperature; ///< Fill last temperature value. BOOL isThisFirstFill; ///< Fill flag to indicate whether it is the first fill or not. BOOL fillAvgConductivityOutOfRange; ///< Fill average conductivity out of range. + BOOL fillEmtyAcidBottleDetected; ///< Fill acid bottle empty detected. + BOOL fillEmtyBicarbBottleDetected; ///< Fill bicarb bottle empty detected. + BOOL fillBottlesNeedPrimeFlag; ///< Fill flag to indicate acid and bicarb bottle need priming. } FILL_CONDITION_STATUS_T; /// DG broadcast dialysate fill data structure. @@ -378,6 +381,9 @@ fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; fillStatus.isThisFirstFill = TRUE; fillStatus.fillAvgConductivityOutOfRange = FALSE; + fillStatus.fillEmtyAcidBottleDetected = FALSE; + fillStatus.fillEmtyBicarbBottleDetected = FALSE; + fillStatus.fillBottlesNeedPrimeFlag = FALSE; } /*********************************************************************//** @@ -408,6 +414,61 @@ /*********************************************************************//** * @brief + * The isEmptyBottle function returns the boolean flag that indicates + * whether the acid bottle is empty. + * @details Inputs: none + * @details Outputs: none + * @return fillStatus.fillEmtyAcidBottleDetected + *************************************************************************/ +BOOL isEmptyAcidBottle( void ) +{ + return fillStatus.fillEmtyAcidBottleDetected; +} + +/*********************************************************************//** + * @brief + * The isEmptyBottle function returns the boolean flag that indicates + * whether the bicarb bottle is empty. + * @details Inputs: none + * @details Outputs: none + * @return fillStatus.fillEmtyBicarbBottleDetected + *************************************************************************/ +BOOL isEmptyBicarbBottle( void ) +{ + return fillStatus.fillEmtyBicarbBottleDetected; +} + +/*********************************************************************//** + * @brief + * The setBottlesNeedPrimeFlag function sets the boolean flag that indicates + * the acid and bicarb bottle need priming. + * @details Inputs: none + * @details Outputs: none + * @return fillStatus.fillBottlesNeedPrimeFlag + * @param flag to TRUE if prime is needed otherwise FALSE + *************************************************************************/ +BOOL setBottlesNeedPrimeFlag( BOOL flag ) +{ + fillStatus.fillBottlesNeedPrimeFlag = flag; + + return fillStatus.fillBottlesNeedPrimeFlag; +} + +/*********************************************************************//** + * @brief + * The getBottlesNeedPrimeFlag function gets the boolean flag that indicates + * the acid and bicarb bottle need priming. + * @details Inputs: none + * @details Outputs: none + * @return fillStatus.fillBottlesNeedPrimeFlag + *************************************************************************/ +BOOL getBottlesNeedPrimeFlag( void ) +{ + return fillStatus.fillBottlesNeedPrimeFlag; +} + +/*********************************************************************//** + * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. @@ -426,7 +487,7 @@ // If this is the first fill of a treatment, prime acid and bicarb lines, otherwise transition // to dialysate production directly #ifndef DISABLE_MIXING - if ( TRUE == isThisTheFirstFill() ) + if ( TRUE == isThisTheFirstFill() || TRUE == getBottlesNeedPrimeFlag() ) { // Prepare the acid and bicarb pumps to prime the concentrate lines setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); @@ -681,10 +742,6 @@ F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); F32 bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - // Continuous conductivity testing will be implemented in the next phase - //BOOL isAcidConductivityBelowThreshold = ( acidConductivity < CONDUCTIVITY_WHEN_ACID_JUG_EMPTY ? TRUE : FALSE ); - //BOOL isBicarbConductivityBelowThreshold = ( bicarbConductivity < CONDUCTIVITY_WHEN_BICARB_JUG_EMPTY ? TRUE : FALSE ); - // Set concentrate pumps speed based on the RO pump flow rate handleDialysateMixing( measuredROFlowRateMLPM ); @@ -715,25 +772,27 @@ #ifndef DISABLE_MIXING // Detect empty bottles using integrated volumes // TODO: empty bottles detection using conductivity sensors if ( ( ( ACID_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedAcidVolumeML ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) ) // || // SRSDG 437 - //( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME, isAcidConductivityBelowThreshold ) ) ) { usedAcidVolumeML.data = 0.0; requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); - result = DG_FILL_MODE_STATE_PAUSED; + //activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); // trigger empty acid bottle alarm at the end of drain mode and set both bottles need prime + fillStatus.isThisFirstFill = TRUE; // empty bottles need replaced, set isThisFirstFill to FALSE so that prime, flush, acid & bicarb test are needed + fillStatus.fillEmtyAcidBottleDetected = TRUE; // set this variable to FALSE when user presses OK on the alarm to confirm bottle has been replaced and resume + //requestNewOperationMode( DG_MODE_GENE ); } if ( ( ( BICARB_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedBicarbVolumeML ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) ) // || // SRSDG 438 - //( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME, isBicarbConductivityBelowThreshold ) ) ) { usedBicarbVolumeML.data = 0.0; requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); - result = DG_FILL_MODE_STATE_PAUSED; + //activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); // trigger empty bicarb bottle alarm at the end of drain mode and set both bottles need prime + fillStatus.isThisFirstFill = TRUE; + fillStatus.fillEmtyBicarbBottleDetected = TRUE; + //requestNewOperationMode( DG_MODE_GENE ); // Fill -> Generation Idle } #endif @@ -745,7 +804,9 @@ F32 avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; F32 avgBicardConductivity = bicarbConductivityTotal / conductivitySampleCount; + fillStatus.fillAvgConductivityOutOfRange = FALSE; // init to FALSE when fill has reached target + #ifndef DISABLE_FLOW_CHECK_IN_FILL if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) // SRSDG 439 { @@ -756,25 +817,22 @@ #ifndef DISABLE_DIALYSATE_CHECK // SRSDG 400 if ( TRUE == isValueWithinPercentRange( avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { - fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode - requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg bicarb is out of range + fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode to handle bad fill + fillStatus.isThisFirstFill = TRUE; + setBottlesNeedPrimeFlag( TRUE ); SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY ); + requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg bicarb is out of range } - else - { - fillStatus.fillAvgConductivityOutOfRange = FALSE; - } if ( TRUE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { - fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode - requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg acid out of range + fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode to handle bad fill + fillStatus.isThisFirstFill = TRUE; + setBottlesNeedPrimeFlag( TRUE ); SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); + requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg acid out of range } - else - { - fillStatus.fillAvgConductivityOutOfRange = FALSE; - } + #endif // Done with this fill. Calculate the average fill flow rate and average temperature // Reset the variables for the next fill