Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r5addd92e279ebc0871364fee70e3ac74db21001a -rf3c8ef49b4bef41b606325e3db0e053a7a72d98f --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 5addd92e279ebc0871364fee70e3ac74db21001a) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision f3c8ef49b4bef41b606325e3db0e053a7a72d98f) @@ -69,7 +69,10 @@ static F32 targetFillFlowLPM = 0.0; ///< Target fill flow in liters/minutes. static U32 previousDialysateFlowMLP = 0; ///< Previous dialysate flow rate in mL/min. static F32 previousUFFlowMLP = 0.0; ///< Previous ultrafiltration flow rate in mL/min. +static DG_MIXING_RATIOS_T ratios; ///< Mixing ratios and fill prep time in milliseconds structure. +static const F32 RESERVOIR_DILUTION_RATIO = MAX_RESERVOIR_DILUTION / ( 1.0 - MAX_RESERVOIR_DILUTION ); + // ********** private function prototypes ********** // Reservoir management functions @@ -95,7 +98,7 @@ * @details Outputs: reservoirsState, timeStartMS, timeDepletionMS, volTotalMl, * volSpentMl, reservoirsPublicationCounter, dilutionLevelPct, dgOpMode, dgSubMode, * timeReservoirInUseMS, volSpentUFML, activeReservoir, recirculationLevelPct, - * reservoirSwitchStartTimeMS, timeWaitToFillMS, targetFillFlowLPM, + * reservoirSwitchStartTimeMS, timeWaitToFillMS, targetFillFlowLPM, ratios * previousDialysateFlowRate * @return none *************************************************************************/ @@ -118,6 +121,9 @@ timeWaitToFillMS = 0; targetFillFlowLPM = 0.0; previousDialysateFlowMLP = 0; + ratios.acidMixingRatio = 0.0; + ratios.bicarbMixingRatio = 0.0; + ratios.timeFillPrepMS = 0; } /*********************************************************************//** @@ -150,6 +156,7 @@ activeReservoir = getDGActiveReservoir(); dgOpMode = getDGOpMode(); dgSubMode = getDGSubMode(); + ratios = getDGMixingRatios(); checkReservoirDepletionTime(); checkReservoirMaxVolume(); @@ -201,14 +208,14 @@ /*********************************************************************//** * @brief - * The setHeatersTemperatureAndTime function is an API to call other internal + * The setDialysateHeatingParams function is an API to call other internal * functions to set the trimmer's heater target temperature and times that are * required to calculated the heaters target temperature in DG. * @details Inputs: none * @details Outputs: none * @return none *************************************************************************/ -void setHeatersTemperatureAndTime( void ) +void setDialysateHeatingParams( void ) { calculateActiveReservoirCycleTime(); } @@ -228,7 +235,9 @@ // Check if the time that the reservoir has been use has exceeded the limit if ( TRUE == didTimeout( timeReservoirInUseMS, MAX_RESERVOIR_DEPLETION_TIME_MS ) ) { +#ifndef SKIP_RESERVOIR_ALARMS SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_DEPLETION_TIME_OUT, calcTimeSince( timeReservoirInUseMS ) ) +#endif } } @@ -295,15 +304,14 @@ *************************************************************************/ static U32 getFillTimeMS( void ) { - DG_MIXING_RATIOS_T ratios = getDGMixingRatios(); F32 targetFillFlowRate = getTargetFillFlowRateLPM(); // The target fill flow rate is RO flow rate plus acid and bicarb flow rates F32 totalTargetFillFlow = targetFillFlowRate + ( targetFillFlowRate * ratios.acidMixingRatio ) + ( targetFillFlowRate * ratios.bicarbMixingRatio ); // Time fill = Fill volume / Qfill. Qfill is converted from L/min to mL/min and the time is converted from minutes to milliseconds U32 timeFillMS = ( FILL_RESERVOIR_TO_VOLUME_ML / ( ML_PER_LITER * totalTargetFillFlow ) ) * SEC_PER_MIN * MS_PER_SECOND; // Add the prepare time in the DG mode fill to the calculated fill time in milliseconds - U32 timeTotalFillMS = timeFillMS + ratios.fillPrepTimeMS; + U32 timeTotalFillMS = timeFillMS + ratios.timeFillPrepMS; return timeTotalFillMS; } @@ -323,16 +331,21 @@ U32 dialysateFlowMLP = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); F32 fillTimeMS = ( (F32)FILL_RESERVOIR_TO_VOLUME_ML / ( getTargetFillFlowRateLPM() * ML_PER_LITER ) ) * SEC_PER_MIN * MS_PER_SECOND; F32 targetUFFlowMLP = getCurrentUFSetRate(); - F32 timeReservoirCycleMS = fillTimeMS; + F32 timeDepletionMS = ( (F32)FILL_RESERVOIR_TO_VOLUME_ML / dialysateFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; + F32 timeTotalCycleMS = fillTimeMS + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS + ratios.timeFillPrepMS; + F32 timeReservoirCycleMS = 0.0; + F32 timeUFDepletionMS = 0.0; // Check if target UF flow is not zero to consider it in the calculations too if ( targetUFFlowMLP > NEARLY_ZERO ) { // If UF is not 0, the active reservoir cycle time is minimum of UF depletion and fill time - F32 timeUFDepletionMS = ( (F32)FILL_RESERVOIR_TO_VOLUME_ML / targetUFFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; - timeReservoirCycleMS = MIN( fillTimeMS, timeUFDepletionMS ); + timeUFDepletionMS = ( ( (F32)FILL_RESERVOIR_TO_VOLUME_ML * RESERVOIR_DILUTION_RATIO ) / targetUFFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; } + timeDepletionMS = MIN( timeDepletionMS, timeUFDepletionMS ); + timeReservoirCycleMS = MAX( timeTotalCycleMS, timeDepletionMS ); + // If the target dialysate flow rate has changed, it means the cycle time (depletion time) has changed // So the new value has to be sent again. if ( ( previousDialysateFlowMLP != dialysateFlowMLP ) || ( previousUFFlowMLP != targetUFFlowMLP ) ) @@ -342,7 +355,7 @@ params.timeReservoirWait2SwitchMS = RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS; params.timeReservoirFillMS = fillTimeMS; params.timeReservoirCycleMS = timeReservoirCycleMS; - params.dialysateFlowLPM = dialysateFlowMLP / ML_PER_LITER; + params.dialysateFlowLPM = ( (F32)dialysateFlowMLP ) / ML_PER_LITER; cmdSetDGDialysateHeatingParams( params ); @@ -528,7 +541,9 @@ // diluted to much if ( recirculationLevelPct >= MAX_RESERVOIR_RECIRCULATION ) { +#ifndef SKIP_RESERVOIR_ALARMS SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_RECIRCULATION_OUT_OF_RANGE, recirculationLevelPct ) +#endif } // Check if DG has moved out of the fill mode