Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -rf6b78d1fe6741043de38707211710ab0e8a08483 -r8b73263b38f449dacc0795c67a7cf6240cb79026 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 8b73263b38f449dacc0795c67a7cf6240cb79026) @@ -7,8 +7,8 @@ * * @file Dialysis.c * -* @author (last) Hung Nguyen -* @date (last) 15-Feb-2022 +* @author (last) Dara Navaei +* @date (last) 15-Jul-2022 * * @author (original) Sean * @date (original) 15-Jan-2020 @@ -39,18 +39,18 @@ // ********** private definitions ********** -#define MAX_UF_RATE_ML_PER_HOUR 2750.0 ///< Maximum ultrafiltration rate in mL/hour -#define MAX_UF_ACCURACY_ERROR_ML 250.0 ///< Maximum ultrafiltration accuracy error in mL over the entire treatment. +#define MAX_UF_RATE_ML_PER_HOUR 2750.0F ///< Maximum ultrafiltration rate in mL/hour +#define MAX_UF_ACCURACY_ERROR_ML 250.0F ///< Maximum ultrafiltration accuracy error in mL over the entire treatment. /// Saline bolus data broadcast interval (ms/task time) count. static const U32 SALINE_BOLUS_DATA_PUB_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); /// Ultrafiltration rate accuracy check interval count. static const U32 UF_ACCURACY_CHECK_INTERVAL = ((1 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); #define MAX_SALINE_VOLUME_DELIVERED 800 ///< Maximum saline volume delivered for a treatment. #define SALINE_BOLUS_RATE_ML_MIN 300 ///< Fixed rate for saline bolus delivery. -#define MAX_BOLUS_ERROR_PCT 0.2 ///< Maximum error in saline bolus volume delivered (as a percentage of target). +#define MAX_BOLUS_ERROR_PCT 0.2F ///< 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. +#define MAX_ACTIVE_LOAD_CELL_CHANGE_G 50.0F ///< Maximum delta between new and previous measured UF volume. // ********** private data ********** @@ -65,6 +65,7 @@ static F32 resCurrVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir current volume. static F32 resLastVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir previous volume. static F32 measUFVolumeFromPriorReservoirs; ///< Current total ultrafiltration volume from previous reservoirs in current treatment. +static F32 lcLastSteadyWeight[NUM_OF_LOAD_CELLS]; ///< Load Cell Last Steady Weight for drift test static U32 uFTimeMS; ///< Current elapsed ultrafiltration time (in ms). Used for calculating UF reference volume. static U32 lastUFTimeStamp; ///< HD timer value when we last took stock of ultrafiltration time (so we can determine how much time has elapsed since). @@ -106,6 +107,7 @@ static void updateUFVolumes( void ); static void publishSalineBolusData( void ); +static void checkLoadCellsStablePrimaryBackupDriftOutOfRange( DG_RESERVOIR_ID_T reservoirID ); /*********************************************************************//** * @brief @@ -118,6 +120,8 @@ *************************************************************************/ void initDialysis( void ) { + U16 i; + currentDialysisState = DIALYSIS_START_STATE; currentUFState = UF_START_STATE; currentSalineBolusState = SALINE_BOLUS_STATE_IDLE; @@ -142,6 +146,10 @@ uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; + for (i=0; i maxBolusErrorMl ) && - ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_FLOW_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) ) + else if ( fabs( expectedSalineBolusVolume_mL - bolusSalineVolumeDelivered_mL ) > maxBolusErrorMl ) { - activateAlarmNoData( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE ); - errorFound = TRUE; - result = SALINE_BOLUS_STATE_IDLE; +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_FLOW_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + activateAlarmNoData( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE ); + errorFound = TRUE; + result = SALINE_BOLUS_STATE_IDLE; + } } } @@ -1131,6 +1147,8 @@ // Set starting baseline volume for next reservoir before we switch to it resStartVolume[ reservoirID ] = resVolume; resFinalVolume[ reservoirID ] = resVolume; + + checkLoadCellsStablePrimaryBackupDriftOutOfRange( reservoirID ); } /*********************************************************************//** @@ -1168,6 +1186,8 @@ measUFVolumeFromPriorReservoirs -= ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); resFinalVolume[ inactiveRes ] = resVolume; measUFVolumeFromPriorReservoirs += ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); + + checkLoadCellsStablePrimaryBackupDriftOutOfRange( inactiveRes ); } /*********************************************************************//** @@ -1202,4 +1222,53 @@ return ( resFinalVolume[ reservoirID ] - resStartVolume[ reservoirID ] ); } +/*********************************************************************//** + * @brief + * The checkLoadCellsStablePrimaryBackupDriftOutOfRange function checks the + * load cells' primary and backup drift when the reservoir level has been stable + * for greater than large filter time. + * @details Inputs: none + * @details Outputs: none + * @param reservoirID which is the reservoir ID that is range checked + * @return none + *************************************************************************/ +static void checkLoadCellsStablePrimaryBackupDriftOutOfRange( DG_RESERVOIR_ID_T reservoirID ) +{ + F32 loadCellPrimaryWeight, loadCellBackupWeight; + F32 loadCellPreviousDrift, loadCellCurrentDrift; + F32 driftDiff = 0.0; + U16 lcPrimaryIndex, lcBackupIndex; + + if ( DG_RESERVOIR_1 == reservoirID ) + { + lcPrimaryIndex = LOAD_CELL_RESERVOIR_1_PRIMARY; + lcBackupIndex = LOAD_CELL_RESERVOIR_1_BACKUP; + } + else + { + lcPrimaryIndex = LOAD_CELL_RESERVOIR_2_PRIMARY; + lcBackupIndex = LOAD_CELL_RESERVOIR_2_BACKUP; + } + + loadCellPrimaryWeight = getReservoirWeightLargeFilter( reservoirID ); + loadCellBackupWeight = getReservoirBackupWeightLargeFilter( reservoirID ); + loadCellCurrentDrift = fabs( loadCellPrimaryWeight - loadCellBackupWeight ); + + if ( lcLastSteadyWeight[lcPrimaryIndex] > (LOAD_CELL_ILLEGAL_WEIGHT_VALUE + 1) ) + { + // Weight has been previously saved, ok to test + loadCellPreviousDrift = lcLastSteadyWeight[lcPrimaryIndex] - lcLastSteadyWeight[lcBackupIndex]; + driftDiff = fabs ( loadCellCurrentDrift - loadCellPreviousDrift ); + } + // Save latest reading for next test time + lcLastSteadyWeight[lcPrimaryIndex] = loadCellPrimaryWeight; + lcLastSteadyWeight[lcBackupIndex] = loadCellBackupWeight; + + // Check for drift out of range + if ( driftDiff > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_LOAD_CELL_PRIMARY_BACKUP_DRIFT_OUT_OF_RANGE, loadCellCurrentDrift, loadCellPreviousDrift ) + } +} + /**@}*/