Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r27cf459aaabea8e98188e929d2d762942b3e78e1 -re9036ee8e37aa4f6709e6b3ad5578e2baa51c8f9 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 27cf459aaabea8e98188e929d2d762942b3e78e1) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision e9036ee8e37aa4f6709e6b3ad5578e2baa51c8f9) @@ -52,12 +52,15 @@ #define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. #define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. +#define CONCENTRATE_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 1 * MS_PER_SECOND ) ///< Persistent period for empty concentrate bottle detect. #define CONCENTRATE_PUMP_PRIME_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Persistent time interval for concentrate pumps prime. #define ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER 1.06 ///< Acid and bicarbonate concentrates make up around 6% to total volume. #define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1 ///< Flow integrated volume has 10% tolerance compare to load cell reading. +#define CONDUCTIVITY_WHEN_ACID_JUG_EMPTY 10000.0 ///< The conductivity value when the acid jug is empty. +#define CONDUCTIVITY_WHEN_BICARB_JUG_EMPTY 12000.0 ///< The conductivity value when the bicard jug is empty. #define ACID_TEST_CD1_TCD 12252.1 ///< Used for testing CD1 acid theoretical conductivity. #define ACID_TEST_CD2_TCD ACID_TEST_CD1_TCD ///< Used for testing CD2 acid theoretical conductivity. #define BICARD_TEST_CD2_TCD 6820.91 ///< Used for testing CD2 bicard theoretical conductivity. @@ -178,6 +181,10 @@ initPersistentAlarm( ALARM_ID_ACID_CONDUCTIVITY_OUT_OF_RANGE, 0, EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ); initPersistentAlarm( ALARM_ID_BICARB_CONDUCTIVITY_OUT_OF_RANGE, 0, EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ); + + initPersistentAlarm( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME, 0, CONCENTRATE_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ); + initPersistentAlarm( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME, 0, CONCENTRATE_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ); + initPersistentAlarm( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_DRFIT_TIMEOUT, 0, DIALYSATE_TEMPERATURE_SENSORS_DRIFT_TIMEOUT_MS ); } @@ -392,7 +399,7 @@ setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN, TARGET_RO_PRESSURE_PSI ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); // TODO if requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); #endif concentratePrimingStartTime = getMSTimerCount(); @@ -601,8 +608,8 @@ // Prime mixing before deliver result to reservoir handleDialysateMixing( measuredROFlowRateMLPM ); #ifndef DISABLE_MIXING - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); // SRSDG 217 + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); // SRSDG 217 if ( concentratePumpPrimeCount++ > CONCENTRATE_PUMP_PRIME_INTERVAL ) #endif @@ -631,19 +638,21 @@ *************************************************************************/ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ) { - DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); + F32 integratedVolumeML; - F32 measuredROFlowRateMLPM = getMeasuredROFlowRateLPM() * ML_PER_LITER; - F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); - F32 bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - BOOL isAcidConductivityOutOfRange = ( acidConductivity <= MIN_ACID_CONCENTRATE_CONDUCTIVITY ) || - ( acidConductivity >= MAX_ACID_CONCENTRATE_CONDUCTIVITY ) ? TRUE : FALSE; - BOOL isBicarbConductivityOutOfRange = ( bicarbConductivity <= MIN_BICARB_CONCENTRATE_CONDUCTIVITY ) || - ( bicarbConductivity >= MAX_BICARB_CONCENTRATE_CONDUCTIVITY ) ? TRUE : FALSE; + F32 measuredROFlowRateMLPM = getMeasuredROFlowRateLPM() * ML_PER_LITER; + F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); + F32 bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); + 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 off RO pump flow rate + BOOL isAcidConductivityOutOfRange = isValueWithinPercentRange( acidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ); + BOOL isBicarbConductivityOutOfRange = isValueWithinPercentRange( bicarbConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ); + + // Set concentrate pumps speed based on the RO pump flow rate handleDialysateMixing( measuredROFlowRateMLPM ); totalROFlowRateMLPM += measuredROFlowRateMLPM; @@ -661,15 +670,15 @@ fillStatus.fillTemperatureRunningSum += getTemperatureValue( (U32)TEMPSENSORS_OUTLET_PRIMARY_HEATER ); #ifndef DISABLE_DIALYSATE_CHECK - if ( ( isWaterQualityGood() != TRUE ) || ( checkDialysateTemperature() != TRUE ) ) + if ( ( isWaterQualityGood() != TRUE ) || ( checkDialysateTemperature() != TRUE ) ) // SRSDG 240 , SRSDG 397 { requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - result = DG_FILL_MODE_STATE_DIALYSATE_PRODUCTION; + result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; } - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ACID_CONDUCTIVITY_OUT_OF_RANGE, isAcidConductivityOutOfRange ) ) + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ACID_CONDUCTIVITY_OUT_OF_RANGE, isAcidConductivityOutOfRange ) ) // SRSDG 558 { usedAcidVolumeML.data = 0.0; requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); @@ -678,7 +687,7 @@ result = DG_FILL_MODE_STATE_PAUSED; } - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BICARB_CONDUCTIVITY_OUT_OF_RANGE, isBicarbConductivityOutOfRange ) ) + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BICARB_CONDUCTIVITY_OUT_OF_RANGE, isBicarbConductivityOutOfRange ) ) // SRSDG 630 { usedBicarbVolumeML.data = 0.0; requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); @@ -687,39 +696,58 @@ result = DG_FILL_MODE_STATE_PAUSED; } #endif + #ifndef DISABLE_MIXING - if ( ( ACID_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedAcidVolumeML ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) + // Detect empty bottles using integrated volumes and 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; } - if ( ( BICARB_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedBicarbVolumeML ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) + 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; } #endif - // If we've reached our target fill to volume (by weight), we're done filling - go back to generation idle mode + + // If we've reached our target fill to volume (by weight), we're done filling - go back to generation idle mode // SRSDG 398 if ( TRUE == hasTargetFillVolumeBeenReached( inactiveReservoir ) ) { F32 filledVolumeML = getReservoirWeight( inactiveReservoir ) - reservoirBaseWeight; F32 integratedVolumeToLoadCellReadingPercent = fabs( 1 - ( filledVolumeML / integratedVolumeML ) ); - F32 avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; // TODO - should we be checking this below? - F32 avgDialysateConductivity = bicarbConductivityTotal / conductivitySampleCount; + F32 avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; + F32 avgBicardConductivity = bicarbConductivityTotal / conductivitySampleCount; - if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) - { #ifndef DISABLE_FLOW_CHECK_IN_FILL + if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) // SRSDG 439 + { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FLOW_METER_CHECK_FAILURE, filledVolumeML, integratedVolumeML ); + } #endif + +#ifndef DISABLE_DIALYSATE_CHECK // SRSDG 400 + if ( TRUE == isValueWithinPercentRange( avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY ); } -#ifndef DISABLE_DIALYSATE_CHECK - if ( ( avgDialysateConductivity < MIN_DIALYSATE_CONDUCTIVITY ) || ( avgDialysateConductivity > MAX_DIALYSATE_CONDUCTIVITY ) ) + if ( TRUE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgAcidConductivity, avgDialysateConductivity ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); } #endif - // Done with this fill. Calculate the average fill flow rate and average temperature // Reset the variables for the next fill // Get the last fill temperature before leaving to Generation Idle @@ -732,7 +760,7 @@ // Write the latest fill data into the RTC RAM for heaters control // TODO test this and make sure it is writing it correctly - setFillInfoToRTCRAM(); + setFillInfoToRTCRAM(); // SRSDG ??? requestNewOperationMode( DG_MODE_GENE ); }