Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -r44a100f8e5210a02c23b8fcc4527d8e96d577381 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) @@ -16,13 +16,15 @@ ***************************************************************************/ #include "DialInFlow.h" +#include "Dialysis.h" #include "DGDefs.h" +#include "DGInterface.h" #include "ModeInitPOST.h" -#include "ModeTreatment.h" +#include "ModeTreatment.h" +#include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "Timers.h" -#include "DGInterface.h" /** * @addtogroup DGInterface @@ -36,6 +38,8 @@ #define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). +#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. + #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. /// States of the treatment reservoir management state machine. @@ -226,6 +230,19 @@ } resUseTimer = getMSTimerCount(); + // Alarm if active reservoir is full and inactive reservoir is not yet ready + if ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) + { + if ( currentTrtResMgmtState < TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH, getReservoirWeight( getDGActiveReservoir() ), (F32)currentTrtResMgmtState ) + } + else + { + clearAlarmCondition( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH ); + } + } + // Treatment reservoir mgmt. state machine switch ( currentTrtResMgmtState ) { @@ -265,8 +282,14 @@ if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) - { - cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML ); + { + U32 fillToVolume = FILL_RESERVOIR_TO_VOLUME_ML; + + if ( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) <= SLOW_DIALYSATE_FLOW_ML_MIN ) + { + fillToVolume = FILL_RESERVOIR_TO_VOLUME_LOW_FLOW_ML; + } + cmdStartDGFill( fillToVolume ); } } else @@ -297,9 +320,8 @@ case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE: // Reservoir switch during treatment should only occur in this state (i.e. when DG is ready). - // Switch reservoirs when active reservoir is spent (i.e. we have pumped fill volume through dialyzer) and DG ready - if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) && - ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) ) + // Switch reservoirs when active reservoir is spent or full (i.e. we have pumped fill volume through dialyzer) and DG ready + if ( ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) || ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) ) { DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); @@ -518,6 +540,23 @@ return result; } +/*********************************************************************//** + * @brief + * The getReservoirWeight function gets the load cell weight of a given + * reservoir. + * @details Inputs: loadCellWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get weight for + * @return the current weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ) +{ + LOAD_CELL_ID_T lc = ( DG_RESERVOIR_1 == resID ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); + F32 wt = getLoadCellWeight( lc ); + + return wt; +} + /*********************************************************************//** * @brief * The setDGOpMode function sets the latest DG operating mode reported by @@ -670,7 +709,7 @@ loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_BACKUP ].data = res2Backup; - // feed new weight samples into filters and update moving averages + // Feed new weight samples into filters and update moving averages for ( res = DG_RESERVOIR_1; res < NUM_OF_DG_RESERVOIRS; res++ ) { F32 wt = ( res == DG_RESERVOIR_1 ? res1Primary : res2Primary ); @@ -680,6 +719,9 @@ lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; } lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); + + // Update Dialysis sub-mode with new reservoir volumes + updateReservoirVolumes( res1Primary, res2Primary ); } /*********************************************************************//**