Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r5a7466b55633b0c439a2ca8ed6d4c4f4356feae9 -r764d85698b625d8b8fc1f53d60b6c0f10dad82b8 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 5a7466b55633b0c439a2ca8ed6d4c4f4356feae9) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 764d85698b625d8b8fc1f53d60b6c0f10dad82b8) @@ -47,8 +47,7 @@ #define MAX_SALINE_VOLUME_DELIVERED 800 ///< Maximum saline volume delivered for a treatment. #define SALINE_BOLUS_RATE_ML_MIN 150 ///< Fixed rate for saline bolus delivery. -#define MIN_SALINE_BOLUS_VOLUME_PCT 0.8 ///< Minimum saline bolus volume measured by independent means (as % of target). -#define MAX_SALINE_BOLUS_VOLUME_PCT 1.2 ///< Maximum saline bolus volume measured by independent means (as % of target). +#define MAX_BOLUS_ERROR_PCT 0.2 ///< Maximum error in saline bolus volume delivered (as a percentage of target). #define MAX_ACTIVE_LOAD_CELL_CHANGE_G 50.0 ///< Maximum delta between new and previous measured UF volume. @@ -78,8 +77,9 @@ static BOOL salineBolusStartRequested; ///< Flag indicates a saline bolus start has been requested by user. static BOOL salineBolusAbortRequested; ///< Flag indicates a salien bolus abort has been requested by user. static BOOL salineBolusAutoResumeUF = FALSE; ///< Flag indicates UF should be auto-resumed after saline bolus completes. -static F32 totalSalineVolumeDelivered; ///< Volume (mL) in total of saline delivered so far (cumulative for all boluses including current one). -static F32 bolusSalineVolumeDelivered; ///< Volume (mL) of current bolus delivered so far. +static F32 totalSalineVolumeDelivered_mL; ///< Volume (mL) in total of saline delivered so far (cumulative for all boluses including current one). +static F32 bolusSalineVolumeDelivered_mL; ///< Volume (mL) of current bolus delivered so far (calculated from measured blood flow rate). +static F32 expectedSalineBolusVolume_mL; ///< Volume (mL) of current bolus delivered so far (calculated from target blood flow rate). static U32 bolusSalineLastVolumeTimeStamp; ///< Time stamp for last saline volume update. static U32 uFAccuracyCheckTimerCtr; ///< Timer counter to determine when next to check ultrafiltration accuracy. @@ -136,7 +136,7 @@ setUFRate = 0.0; salineBolusBroadcastTimerCtr = 0; - totalSalineVolumeDelivered = 0.0; + totalSalineVolumeDelivered_mL = 0.0; uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; @@ -157,7 +157,8 @@ { salineBolusStartRequested = FALSE; salineBolusAbortRequested = FALSE; - bolusSalineVolumeDelivered = 0.0; + bolusSalineVolumeDelivered_mL = 0.0; + expectedSalineBolusVolume_mL = 0.0; if ( currentSalineBolusState != SALINE_BOLUS_STATE_MAX_DELIVERED ) { currentSalineBolusState = SALINE_BOLUS_STATE_IDLE; @@ -356,7 +357,7 @@ { rejReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; } - else if ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) + else if ( totalSalineVolumeDelivered_mL >= (F32)MAX_SALINE_VOLUME_DELIVERED ) { rejReason = REQUEST_REJECT_REASON_SALINE_MAX_VOLUME_REACHED; } @@ -486,7 +487,7 @@ *************************************************************************/ F32 getTotalSalineBolusVolumeDelivered( void ) { - return totalSalineVolumeDelivered; + return totalSalineVolumeDelivered_mL; } /*********************************************************************//** @@ -868,7 +869,7 @@ if ( ( FALSE == isBloodPumpRunning() ) && ( FALSE == isDialInPumpRunning() ) && ( FALSE == isDialOutPumpRunning() ) ) { // Reset bolus data before we start - bolusSalineVolumeDelivered = 0.0; + bolusSalineVolumeDelivered_mL = 0.0; bolusSalineLastVolumeTimeStamp = getMSTimerCount(); // Bypass dialyzer @@ -910,13 +911,16 @@ BOOL errorFound = FALSE; F32 timeSinceLastVolumeUpdateMin = (F32)calcTimeSince( bolusSalineLastVolumeTimeStamp ) / (F32)( MS_PER_SECOND * SEC_PER_MIN ); F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + F32 maxBolusErrorMl = bolusTargetVolume * MAX_BOLUS_ERROR_PCT; F32 bldFlowRate = getMeasuredBloodFlowRate(); // TODO - should I use raw flow instead of filtered here??? F32 volSinceLastUpdateMl = bldFlowRate * timeSinceLastVolumeUpdateMin; + F32 expVolSinceLastUpdateMl = (F32)getTargetBloodFlowRate() * timeSinceLastVolumeUpdateMin; // Update saline bolus volumes bolusSalineLastVolumeTimeStamp = getMSTimerCount(); - bolusSalineVolumeDelivered += volSinceLastUpdateMl; - totalSalineVolumeDelivered += volSinceLastUpdateMl; + bolusSalineVolumeDelivered_mL += volSinceLastUpdateMl; + totalSalineVolumeDelivered_mL += volSinceLastUpdateMl; + expectedSalineBolusVolume_mL += expVolSinceLastUpdateMl; // Check for empty saline bag per arterial line pressure if ( TRUE == isSalineBagEmpty() ) @@ -927,14 +931,14 @@ } // Determine if we have reached maximum saline delivery volume - if ( ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) ) + if ( ( totalSalineVolumeDelivered_mL >= (F32)MAX_SALINE_VOLUME_DELIVERED ) ) { result = SALINE_BOLUS_STATE_MAX_DELIVERED; } else { // Determine if bolus is complete - if ( bolusSalineVolumeDelivered >= bolusTargetVolume ) + if ( bolusSalineVolumeDelivered_mL >= bolusTargetVolume ) { result = SALINE_BOLUS_STATE_IDLE; } @@ -945,8 +949,8 @@ result = SALINE_BOLUS_STATE_IDLE; } #ifndef DISABLE_PUMP_FLOW_CHECKS - // Determine if saline bolus delivery is taking too long to complete - else if ( TBD ) + // Determine if saline bolus is under/over delivering + else if ( fabs( expectedSalineBolusVolume_mL - bolusSalineVolumeDelivered_mL ) > maxBolusErrorMl ) { activateAlarmNoData( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE ); errorFound = TRUE; @@ -964,8 +968,8 @@ // Send last saline bolus data salineBolusBroadcastTimerCtr = SALINE_BOLUS_DATA_PUB_INTERVAL; publishSalineBolusData(); - sendTreatmentLogEventData( SALINE_BOLUSES_CHANGE_EVENT, bolusSalineVolumeDelivered, totalSalineVolumeDelivered ); - bolusSalineVolumeDelivered = 0.0; + sendTreatmentLogEventData( SALINE_BOLUSES_CHANGE_EVENT, bolusSalineVolumeDelivered_mL, totalSalineVolumeDelivered_mL ); + bolusSalineVolumeDelivered_mL = 0.0; // Dialysis back to UF state *dialysisState = DIALYSIS_UF_STATE; // End dialyzer bypass and resume dialysis if no alarms triggered @@ -1021,8 +1025,8 @@ SALINE_BOLUS_DATA_PAYLOAD_T data; data.tgtSalineVolumeMl = getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); - data.cumSalineVolumeMl = totalSalineVolumeDelivered; - data.bolSalineVolumeMl = bolusSalineVolumeDelivered; + data.cumSalineVolumeMl = totalSalineVolumeDelivered_mL; + data.bolSalineVolumeMl = bolusSalineVolumeDelivered_mL; broadcastData( MSG_ID_SALINE_BOLUS_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( SALINE_BOLUS_DATA_PAYLOAD_T ) ); salineBolusBroadcastTimerCtr = 0; }