Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -ra7a7874f47ccddc122af67273851881477880ff9 -r256d5cb05f1ef09e19e2f2733a111f600c73a7ee --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision a7a7874f47ccddc122af67273851881477880ff9) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 256d5cb05f1ef09e19e2f2733a111f600c73a7ee) @@ -8,7 +8,7 @@ * @file ModeFill.c * * @author (last) Dara Navaei -* @date (last) 24-May-2022 +* @date (last) 12-Aug-2022 * * @author (original) Leonardo Baloa * @date (original) 19-Nov-2019 @@ -20,6 +20,7 @@ #include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "FPGA.h" +#include "CPLD.h" #include "Heaters.h" #include "LoadCell.h" #include "ModeFill.h" @@ -128,7 +129,6 @@ 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, @@ -147,7 +147,7 @@ static BOOL areInletWaterConditionsAlarmsActive( void ); static void checkDialysateTemperatureSensors( void ); -static void handleDialysateMixing( F32 measuredROFlowRate_mL_min ); +static void handleDialysateMixing( F32 measuredROFlowRate_mL_min, F32 acidMixingRatio, F32 bicarbMixingRatio ); static void setFillInfoToRTCRAM( void ); static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ); static void publishFillModeData( void ); @@ -199,6 +199,7 @@ DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); initFillMode(); + reservoirBaseWeight = getReservoirWeight( inactiveReservoir ); // Set initial actuator states @@ -214,6 +215,7 @@ setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); startHeater( DG_PRIMARY_HEATER ); + setCPLDCleanLEDColor( CPLD_CLEAN_LED_OFF ); return fillState; } @@ -457,8 +459,19 @@ } else { + DG_ACID_CONCENTRATES_RECORD_T acid; + F32 acidMix; + DG_BICARB_CONCENTRATES_RECORD_T bicarb; + F32 bicarbMix; + + getAcidConcentrateCalRecord( &acid ); + getBicarbConcentrateCalRecord( &bicarb ); + + acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); - handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER ); + handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER, acidMix, bicarbMix ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; @@ -566,7 +579,7 @@ } #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BICARB_CONDUCTIVITY_TEST ) == SW_CONFIG_ENABLE_VALUE ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_BICARB_CONDUCTIVITY_TEST ) ) { isConductivityInRange = TRUE; } @@ -637,17 +650,27 @@ } #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BICARB_CONDUCTIVITY_TEST ) == SW_CONFIG_ENABLE_VALUE ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_ACID_CONDUCTIVITY_TEST ) ) { haveTestsPassed = TRUE; } #endif if ( TRUE == haveTestsPassed ) { - setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); + DG_ACID_CONCENTRATES_RECORD_T acid; + F32 acidMix; + DG_BICARB_CONCENTRATES_RECORD_T bicarb; + F32 bicarbMix; - handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER ); + getAcidConcentrateCalRecord( &acid ); + getBicarbConcentrateCalRecord( &bicarb ); + + acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + + setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); + handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER, acidMix, bicarbMix ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); // Do the necessary setup here before transition to Produce Dialysate State @@ -675,9 +698,19 @@ static DG_FILL_MODE_STATE_T handleProduceDialysateState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + DG_ACID_CONCENTRATES_RECORD_T acid; + F32 acidMix; + DG_BICARB_CONCENTRATES_RECORD_T bicarb; + F32 bicarbMix; + getAcidConcentrateCalRecord( &acid ); + getBicarbConcentrateCalRecord( &bicarb ); + + acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + // Prime mixing before deliver result to reservoir - handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER ); + handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER, acidMix, bicarbMix ); if ( concentratePumpPrimeCount++ > CONCENTRATE_PUMP_PRIME_INTERVAL ) { @@ -701,13 +734,23 @@ *************************************************************************/ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ) { + DG_ACID_CONCENTRATES_RECORD_T acid; + F32 acidMix; + DG_BICARB_CONCENTRATES_RECORD_T bicarb; + F32 bicarbMix; DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); F32 bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + getAcidConcentrateCalRecord( &acid ); + getBicarbConcentrateCalRecord( &bicarb ); + + acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + // Set concentrate pumps speed based on the RO pump flow rate - handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER ); + handleDialysateMixing( getMeasuredROFlowRateLPM() * ML_PER_LITER, acidMix, bicarbMix ); integratedVolumeML += getMeasuredROFlowRateWithConcPumpsLPM() * ( (F32)TASK_GENERAL_INTERVAL / (F32)( SEC_PER_MIN ) ); usedAcidVolumeML.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; @@ -736,6 +779,8 @@ F32 integratedVolumeToLoadCellReadingPercent = fabs( 1.0F - ( filledVolumeML / integratedVolumeML ) ); F32 avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; F32 avgBicarbConductivity = bicarbConductivityTotal / conductivitySampleCount; + F32 acidNormalConductivity = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConductivityUSPerCM; + F32 bicarbNormalConductivity = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConductivityUSPerCM; #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_FLOW_VS_LOAD_CELL_CHECK_IN_FILL ) != SW_CONFIG_ENABLE_VALUE ) @@ -752,20 +797,20 @@ #endif { // SRSDG 400 - if ( FALSE == isValueWithinPercentRange( avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) + if ( FALSE == isValueWithinPercentRange( avgBicarbConductivity, bicarbNormalConductivity, FIVE_PERCENT_FACTOR ) ) { setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, bicarbNormalConductivity ); // trigger replace bottles alarm #1 clearAlarm( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); } - if ( FALSE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) + if ( FALSE == isValueWithinPercentRange( avgAcidConductivity, acidNormalConductivity, FIVE_PERCENT_FACTOR ) ) { setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 then + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, acidNormalConductivity ); // trigger replace bottles alarm #1 then clearAlarm( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); } @@ -778,12 +823,13 @@ fillStatus.fillTemperatureAverage = fillStatus.fillTemperatureRunningSum / (F32)fillStatus.fillSampleCounter; fillStatus.fillFlowRateRunningSum = 0.0; fillStatus.fillTemperatureRunningSum = 0.0; - fillStatus.fillSampleCounter = 1; + fillStatus.fillSampleCounter = 0; fillStatus.fillLastTemperature = getTemperatureValue( (U32)TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + calculateHeaterEstimationGain( DG_PRIMARY_HEATER ); + // Write the latest fill data into the RTC RAM for heaters control - // TODO test this and make sure it is writing it correctly - setFillInfoToRTCRAM(); // SRSDG ??? + // setFillInfoToRTCRAM(); // TODO we do not need to write to NV memory for now requestNewOperationMode( DG_MODE_GENE ); } @@ -906,22 +952,22 @@ * @details Inputs: none * @details Outputs: Set concentrate pump speed relative to RO pump flow rate * @param measuredROFlowRate_mL_min measured RO flow rate in mL/min + * * @return none *************************************************************************/ -static void handleDialysateMixing( F32 measuredROFlowRate_mL_min ) +static void handleDialysateMixing( F32 measuredROFlowRate_mL_min, F32 acidMixingRatio, F32 bicarbMixingRatio ) { - // TODO what should we do with start volume from the structure? - DG_ACID_CONCENTRATES_RECORD_T acid = getAcidConcentrateCalRecord(); - DG_BICARB_CONCENTRATES_RECORD_T bicarb = getBicarbConcentrateCalRecord(); - // Set concentrate pumps speed based off RO pump flow rate - F32 acidCP1PumpFlowRate = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio * measuredROFlowRate_mL_min; - F32 bicarbCP2PumpFlowRate = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio * measuredROFlowRate_mL_min; + F32 acidCP1PumpFlowRate = acidMixingRatio * measuredROFlowRate_mL_min; + F32 bicarbCP2PumpFlowRate = bicarbMixingRatio * measuredROFlowRate_mL_min; // Cap to the maximum allowed concentrate pumps rate acidCP1PumpFlowRate = MIN( acidCP1PumpFlowRate, CONCENTRATE_PUMP_MAX_SPEED ); bicarbCP2PumpFlowRate = MIN( bicarbCP2PumpFlowRate, CONCENTRATE_PUMP_MAX_SPEED ); + acidCP1PumpFlowRate = MAX( acidCP1PumpFlowRate, 0.0F ); + bicarbCP2PumpFlowRate = MAX( bicarbCP2PumpFlowRate, 0.0F ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, acidCP1PumpFlowRate ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, bicarbCP2PumpFlowRate ); }