Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -rb67373adbc581690febb1e1c2bb521f108d9b92e -rd371983d84daf213db3e39d21cf30c13161ce062 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision b67373adbc581690febb1e1c2bb521f108d9b92e) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision d371983d84daf213db3e39d21cf30c13161ce062) @@ -8,7 +8,7 @@ * @file ModeFill.c * * @author (last) Dara Navaei -* @date (last) 18-Aug-2023 +* @date (last) 20-Sep-2023 * * @author (original) Leonardo Baloa * @date (original) 19-Nov-2019 @@ -63,8 +63,8 @@ #define CONC_PUMPS_PRIME_AT_MAX_SPEED_TIME_OUT_MS ( 7 * MS_PER_SECOND ) ///< Concentrate pumps prime at maximum speed timeout in milliseconds. #define CONC_PUMPS_PRIME_CHECK_COND_SNSRS_TIME_OUT_MS ( 10 * MS_PER_SECOND ) ///< Concentrate pumps prime check conductivity sensors timeout in milliseconds. -#define CONC_PUMPS_PRIME_MAX_ALLOWED_PRIME_TIME_OUT_MS ( 25 * MS_PER_SECOND ) ///< Concentrate pumps prime maximum allowed timeout in prime in milliseconds. - +#define CONC_PUMPS_PRIME_MAX_ALLOWED_PRIME_TIME_OUT_MS ( 60 * MS_PER_SECOND ) ///< Concentrate pumps prime maximum allowed timeout in prime in milliseconds. +#define HUNDRED_PERCENT_FACTOR 1.00F ///< Hundred percent of expected conductivity when first time reaches it. #define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1F ///< Flow integrated volume has 10% tolerance compare to load cell reading. #define FIVE_PERCENT_FACTOR 0.05F ///< 5.0 / 100.0 used to calculate conductivity within range of -/+ 5%. @@ -116,10 +116,13 @@ static U32 dataPublishCounter; ///< Used to schedule dialysate fill data publication to CAN bus. static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. -static U32 dialysateFillStartTimeMS; ///< Current time when starting to fill dialysate in milliseconds. static F32 reservoirBaseWeight; ///< Fill reservoir base weight. static FILL_CONDITION_STATUS_T fillStatus; ///< Fill condition status. +static BOOL didFillRecoverFromPause; ///< Flag to indicate whether the previous state was pause or not. +static U32 dialysateFillStartTimeMS; ///< Current time when starting to fill dialysate in milliseconds. +static U32 dialysatePauseStartTimeMS; ///< Current time when starting a pause during fill dialysate in milliseconds. +static U32 dialysatePauseElapsedTimeMS; ///< Elapsed time in pause during fill dialysate in milliseconds. static U32 concentrateTestStartTime; ///< Starting time for concentrate test. static U32 concentratePrimingStartTime; ///< Starting time for concentrate priming. static U32 flushBubblesStartTime; ///< Starting time for flush bubbles. @@ -145,8 +148,6 @@ static U32 fillCPoConductivitySampleCnt; ///< Number of samples in sum of CPo and Rej. Ratio conductivity readings for fill. 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 BOOL didFillRecoverFromPause; ///< Flag to indicate whether the previous state was pause or not. static FILL_ACID_BICARB_TYPES_T chemicalsTypes; ///< Chemicals Types (acid and bicarb). static DG_CHEMICALS_FILL_COND_CAL_RECORD_T chemicalsCond; ///< Chemicals fill conductivity records. static F32 acidMixRatio; ///< Acid conductivity mix ratio. @@ -194,32 +195,35 @@ getAcidConcentrateCalRecord( &acid ); getBicarbConcentrateCalRecord( &bicarb ); + acidConductivitySampleCount = 0; + acidConductivityTotal = 0.0F; acidMixRatio = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + averageAcidConductivity = 0.0F; + averageBicarbConductivity = 0.0F; + bicarbConductivitySampleCount = 0; + bicarbConductivityTotal = 0.0F; bicarbMixRatio = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; - fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; - dialysateFillStartTimeMS = 0; - dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; - reservoirBaseWeight = 0.0F; - integratedVolumeML.data = 0.0F; - didFMPCheckStart = FALSE; concentrateTestStartTime = 0; - acidConductivityTotal = 0.0F; - bicarbConductivityTotal = 0.0F; - conductivitySampleCount = 0; concPumpPrimeStartTimeMS = getMSTimerCount(); - pumpSpeedIndex = 0; - averageBicarbConductivity = 0.0F; - averageAcidConductivity = 0.0F; + conductivitySampleCount = 0; + dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + // This timer is set to 0 to be checked whether we were in pause but this is still 0 so so we the start time regardless + // If we were filling and then went to pause we do not reset this anymore + dialysateFillStartTimeMS = 0; + dialysatePauseElapsedTimeMS = 0; + dialysatePauseStartTimeMS = 0; + didFillRecoverFromPause = FALSE; + didFMPCheckStart = FALSE; + fillCPoConductivitySampleCnt = 0; + fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; + integratedVolumeML.data = 0.0F; pctDiffInConductivity = 0.0F; - bicarbConductivitySampleCount = 0; - acidConductivitySampleCount = 0; - totalBicarbConductivity = 0.0F; - totalAcidConductivity = 0.0F; - havePauseActuatorsBeenSet = FALSE; + pumpSpeedIndex = 0; + reservoirBaseWeight = 0.0F; sumFillCPoConductivity = 0.0F; sumFillRejRatio = 0.0F; - fillCPoConductivitySampleCnt = 0; - didFillRecoverFromPause = FALSE; + totalAcidConductivity = 0.0F; + totalBicarbConductivity = 0.0F; } /*********************************************************************//** @@ -233,17 +237,19 @@ { F32 targetFlowLPM = getTargetFillFlowRateLPM(); - if ( ( getTestConfigStatus( TEST_CONFIG_RECOVER_TREATMENT ) != TRUE ) || ( getPreviousOperationMode() != DG_MODE_FAUL ) ) - { - initFillMode(); - setCurrentSubState( NO_SUB_STATE ); + initFillMode(); + setCurrentSubState( NO_SUB_STATE ); + // Set initial actuator states + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); +#if 0 + // Reset the state machine + // Note: the substate timers, and operation flags need to be reset on recovery, consider + // reinitializing the state variables, the resetting the state, by calling setModeFillStateTransition() + if ( ( TRUE == getTestConfigStatus( TEST_CONFIG_RECOVER_TREATMENT ) ) && ( DG_MODE_FAUL == getPreviousOperationMode() ) ) + { // Restore the prior fillstate to a valid, running fill state, with timer state reset. + fillState = restoreFillState; - // Set initial actuator states - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - } - else - { setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); @@ -290,20 +296,18 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - dialysateFillStartTimeMS = getMSTimerCount(); fillStatus.isThisFirstFill = FALSE; break; case DG_FILL_MODE_STATE_PAUSED: targetFlowLPM = TARGET_RO_FLOW_RATE_IN_PAUSE_L; - havePauseActuatorsBeenSet = FALSE; + dialysatePauseStartTimeMS = getMSTimerCount(); break; } } - +#endif getFillChemicalCondRecord( &chemicalsCond ); - turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); @@ -330,9 +334,13 @@ checkDialysateTemperatureSensors(); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); - if ( ( TRUE == areInletWaterConditionsAlarmsActive() ) || ( TRUE == areConductivityAlarmsActive() ) ) + if ( fillState != DG_FILL_MODE_STATE_PAUSED ) { - fillState = DG_FILL_MODE_STATE_PAUSED; + if ( ( TRUE == areInletWaterConditionsAlarmsActive() ) || ( TRUE == areConductivityAlarmsActive() ) ) + { + setModeFillStateTransition( DG_FILL_MODE_STATE_PAUSED ); + fillState = DG_FILL_MODE_STATE_PAUSED; + } } // Execute current Fill state @@ -375,7 +383,6 @@ fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; break; } - publishFillModeData(); return fillState; @@ -430,6 +437,7 @@ F32 getIntegratedVolumeML( void ) { F32 integratedVolume = getF32OverrideValue( &integratedVolumeML ); + return integratedVolume; } @@ -529,7 +537,7 @@ * @param flag to TRUE if prime is needed otherwise FALSE * @return none *************************************************************************/ -void setThisFisrtFillFlag( BOOL flag ) +void setThisFirstFillFlag( BOOL flag ) { fillStatus.isThisFirstFill = flag; } @@ -600,7 +608,6 @@ { result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; } - setModeFillStateTransition( result ); return result; @@ -791,15 +798,18 @@ if ( TRUE == didTimeout( concPumpPrimeStartTimeMS, CONC_PUMPS_PRIME_CHECK_COND_SNSRS_TIME_OUT_MS ) ) { /* Once the time for priming the concentrate lines has elapsed, check the mixing conductivity of the sensors - * If the acid and bicarb conductivity values are at about 50% of the target concentrate during fill, transition to the next state - * If the acid and bicarb conductivity values are not at 50% but the maximum prime time has elapsed, transition to the next state + * If the acid and bicarb conductivity values are at about 100% of the target concentrate during fill, transition to the next state + * If the acid and bicarb conductivity values are not at 100% but the maximum prime time has elapsed, transition to the next state */ F32 acidConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); F32 bicarbConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); F32 acidFillConduSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].acidConduSPerCM; F32 bicarbFillConduSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].bicarbConduSPerCM; - if ( ( acidConduSPerCM >= ( acidFillConduSPerCM * HALF ) ) && ( bicarbConduSPerCM >= ( bicarbFillConduSPerCM * HALF ) ) ) + /* we are insisting conductivity reach 100% of expected level since signal is very noisy and peak noise will reach 100% when average is about 93%. + * if sensor noise is reduced, this level should also be reduced accordingly. + */ + if ( ( acidConduSPerCM >= ( acidFillConduSPerCM * HUNDRED_PERCENT_FACTOR ) ) && ( bicarbConduSPerCM >= ( bicarbFillConduSPerCM * HUNDRED_PERCENT_FACTOR ) ) ) { result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; setModeFillStateTransition( result ); @@ -869,7 +879,6 @@ didFMPCheckStart = TRUE; reservoirBaseWeight = getReservoirWeight( getInactiveReservoir() ); } - integratedVolumeML.data += getMeasuredROFlowRateWithConcPumpsLPM() * ML_PER_LITER * FLOW_INTEGRATOR; } @@ -885,8 +894,10 @@ fillStatus.fillTemperatureRunningSum += inletTemperature; // TODO: Check for open straw door status and alarm if closed - // Check if run out of time to fill the reservoir - if ( TRUE == didTimeout( dialysateFillStartTimeMS, DIALYSATE_FILL_TIME_OUT ) ) + // Check if run out of time to fill the reservoir, disregarding time paused, + // because pause time isn't the reservoir's, or loadcell's fault + // the 5 minutes DIALYSATE_FILL_TIME_OUT is a mystery number. + if ( TRUE == didTimeout( dialysateFillStartTimeMS, DIALYSATE_FILL_TIME_OUT + dialysatePauseElapsedTimeMS ) ) { activateAlarmNoData( ALARM_ID_DG_DIALYSATE_FILL_OUT_OF_TIME ); } @@ -939,7 +950,7 @@ ( getTargetFillVolumeML() > MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML ) && ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) { setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected - setThisFisrtFillFlag( TRUE ); + setThisFirstFillFlag( TRUE ); resetChemicalUsedVolumeML( BICARB ); resetChemicalUsedVolumeML( ACID ); SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConduSPerCM, bicarbNormalConduSPerCM ); // trigger replace bottles alarm #1 @@ -968,21 +979,19 @@ * @brief * The handlePausedState function executes the paused state of the fill * mode state machine. - * @details Inputs: havePauseActuatorsBeenSet - * @details Outputs: havePauseActuatorsBeenSet, didFillRecoverFromPause + * @details Inputs: Inlet water conditions and conductivity + * @details Outputs: didFillRecoverFromPause * @return the next state *************************************************************************/ static DG_FILL_MODE_STATE_T handlePausedState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_PAUSED; - setModeFillStateTransition( result ); - if ( ( FALSE == areInletWaterConditionsAlarmsActive() ) && ( FALSE == areConductivityAlarmsActive() ) ) { didFillRecoverFromPause = TRUE; - havePauseActuatorsBeenSet = FALSE; result = DG_FILL_MODE_STATE_TEST_INLET_WATER; + setModeFillStateTransition( result ); } return result; @@ -992,17 +1001,28 @@ * @brief * The setModeFillStateTransition function sets the actuators and variables * for the state transition in mode fill. - * @details Inputs: pumpSpeedIndex, havePauseActuatorsBeenSet, + * @details Inputs: pumpSpeedIndex, dialysatePauseStartTimeMS * didFillRecoverFromPause * @details Outputs: concPumpPrimeStartTimeMS, fillStatus, pumpSpeedIndex, * concentratePrimingStartTime, totalBicarbConductivity, averageBicarbConductivity, * bicarbConductivitySampleCount, concentrateTestStartTime, fillStatus, - * havePauseActuatorsBeenSet, flushBubblesStartTime, didFillRecoverFromPause + * flushBubblesStartTime, didFillRecoverFromPause + * dialysatePauseElapsedTimeMS, dialysatePauseStartTimeMS * @param state mode fill state enum * @return none *************************************************************************/ static void setModeFillStateTransition( DG_FILL_MODE_STATE_T state ) { + // Execute cleanup on exiting pause + if ( state != fillState ) + { + if ( DG_FILL_MODE_STATE_PAUSED == fillState ) + { // accumulate pause + dialysatePauseElapsedTimeMS += calcTimeSince( dialysatePauseStartTimeMS ); + } + } + + // Execute on running state switch( state ) { case DG_FILL_MODE_STATE_TEST_INLET_WATER: @@ -1071,7 +1091,7 @@ case DG_FILL_MODE_STATE_DELIVER_DIALYSATE: setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - if ( didFillRecoverFromPause != TRUE ) + if ( ( didFillRecoverFromPause != TRUE ) || ( 0 == dialysateFillStartTimeMS ) ) { dialysateFillStartTimeMS = getMSTimerCount(); } @@ -1080,14 +1100,11 @@ break; case DG_FILL_MODE_STATE_PAUSED: - if ( FALSE == havePauseActuatorsBeenSet ) - { - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_IN_PAUSE_L, TARGET_RO_PRESSURE_PSI ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - havePauseActuatorsBeenSet = TRUE; - } + dialysatePauseStartTimeMS = getMSTimerCount(); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_IN_PAUSE_L, TARGET_RO_PRESSURE_PSI ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); break; default: