Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r124b3745d056ac667280cfa0ae1fab8610d44ed2 -r38a89cb53b4ed2e467f51d41e30d43010fdd23e3 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 124b3745d056ac667280cfa0ae1fab8610d44ed2) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 38a89cb53b4ed2e467f51d41e30d43010fdd23e3) @@ -77,6 +77,13 @@ static const U32 EMPTY_SALINE_BAG_PERSISTENCE = ( 250 / TASK_GENERAL_INTERVAL ); ///< Time that saline bag looks empty before saying it is empty. #define PRES_ALARM_PERSISTENCE ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for pressure alarms. + +/// Measured arterial pressure is filtered w/ 10 second moving average for pressure compensation of flow. +#define SIZE_OF_LONG_ART_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 10 ) +/// Measured arterial pressure is filtered w/ 1 second moving average for inline pressure. +#define SIZE_OF_SHORT_ART_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) +/// Measured venous pressure is filtered w/ 1 second moving average for inline pressure and unfiltered for occlusion detection. +#define SIZE_OF_SHORT_VEN_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) /// Defined states for the pressure and occlusion monitor state machine. typedef enum PresOccl_States @@ -107,6 +114,9 @@ static OVERRIDE_U32_T bloodPumpOcclusion = {0, 0, 0, 0 }; ///< Measured blood pump occlusion pressure. static OVERRIDE_U32_T dialInPumpOcclusion = {0, 0, 0, 0 }; ///< Measured dialysate inlet pump occlusion pressure. static OVERRIDE_U32_T dialOutPumpOcclusion = {0, 0, 0, 0 }; ///< Measured dialysate outlet pump occlusion pressure. +static F32 longFilteredArterialPressure; ///< Measured arterial pressure after long (10 s) filter. +static F32 shortFilteredArterialPressure; ///< Measured arterial pressure after short (1 s) filter. +static F32 shortFilteredVenousPressure; ///< Measured venous pressure after short (1 s) filter. static U32 bloodPumpOcclusionAfterCartridgeInstall; ///< Measured blood pump occlusion reading taken after cartridge install. static U32 dialInPumpOcclusionAfterCartridgeInstall; ///< Measured dialysate inlet pump occlusion reading taken after cartridge install. @@ -123,6 +133,21 @@ static U08 lastDPIErrorCtr; ///< Previous DPi error count. static U08 lastDPOErrorCtr; ///< Previous DPo error count. +static F32 artPressureReadingsLong[ SIZE_OF_LONG_ART_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. +static U32 artPressureReadingsLongIdx = 0; ///< Index for next sample in rolling average array. +static F32 artPressureReadingsLongTotal = 0.0; ///< Rolling total - used to calc average. +static U32 artPressureReadingsLongCount = 0; ///< Number of samples in flow rolling average buffer. + +static F32 artPressureReadingsShort[ SIZE_OF_SHORT_ART_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. +static U32 artPressureReadingsShortIdx = 0; ///< Index for next sample in rolling average array. +static F32 artPressureReadingsShortTotal = 0.0; ///< Rolling total - used to calc average. +static U32 artPressureReadingsShortCount = 0; ///< Number of samples in flow rolling average buffer. + +static F32 venPressureReadingsShort[ SIZE_OF_SHORT_VEN_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. +static U32 venPressureReadingsShortIdx = 0; ///< Index for next sample in rolling average array. +static F32 venPressureReadingsShortTotal = 0.0; ///< Rolling total - used to calc average. +static U32 venPressureReadingsShortCount = 0; ///< Number of samples in flow rolling average buffer. + // ********** private function prototypes ********** static PRESSURE_STATE_T handlePresOcclContReadState( void ); @@ -132,6 +157,7 @@ static void checkVenousPressureInRange( void ); static void checkOcclusions( void ); static void publishPresOcclData( void ); +static void filterInlinePressureReadings( F32 artPres, F32 venPres ); /*********************************************************************//** * @brief @@ -171,6 +197,10 @@ lastDPIErrorCtr = 0; lastDPOErrorCtr = 0; + longFilteredArterialPressure = 0.0; + shortFilteredArterialPressure = 0.0; + shortFilteredVenousPressure = 0.0; + bloodPumpOcclusionAfterCartridgeInstall = 0; dialInPumpOcclusionAfterCartridgeInstall = 0; dialOutPumpOcclusionAfterCartridgeInstall = 0; @@ -339,8 +369,6 @@ F32 venTemp = getTemperatureValue( TEMPSENSOR_VENOUS_PRESSURE_SENSOR ); U08 venReadCtr = getFPGAVenousPressureReadCounter(); - // TODO - any filtering required??? - // Convert arterial pressure to mmHg if no fault if ( 0 == artPresAlarm ) { @@ -394,6 +422,9 @@ { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, venTemp ) } + + // Filter inline pressure readings + filterInlinePressureReadings( getMeasuredArterialPressure(), getMeasuredVenousPressure() ); } /*********************************************************************//** @@ -466,7 +497,7 @@ *************************************************************************/ static void checkArterialPressureInRange( void ) { - F32 artPres = getMeasuredArterialPressure(); + F32 artPres = getFilteredArterialPressure(); #ifndef DISABLE_PRESSURE_CHECKS // Check arterial pressure is in range @@ -518,7 +549,7 @@ *************************************************************************/ static void checkVenousPressureInRange( void ) { - F32 venPres = getMeasuredVenousPressure(); + F32 venPres = getFilteredVenousPressure(); #ifndef DISABLE_PRESSURE_CHECKS // Check arterial pressure is in range @@ -638,6 +669,30 @@ return result; } + +/*********************************************************************//** + * @brief + * The getFilteredArterialPressure function gets the current filtered arterial pressure. + * @details Inputs: shortFilteredArterialPressure + * @details Outputs: none + * @return the current filtered arterial pressure (in mmHg). + *************************************************************************/ +F32 getFilteredArterialPressure( void ) +{ + return shortFilteredArterialPressure; +} + +/*********************************************************************//** + * @brief + * The getLongFilteredArterialPressure function gets the current long filtered arterial pressure. + * @details Inputs: longFilteredArterialPressure + * @details Outputs: none + * @return the current long filtered arterial pressure (in mmHg). + *************************************************************************/ +F32 getLongFilteredArterialPressure( void ) +{ + return longFilteredArterialPressure; +} /*********************************************************************//** * @brief @@ -657,6 +712,18 @@ return result; } + +/*********************************************************************//** + * @brief + * The getFilteredVenousPressure function gets the measured filtered venous pressure. + * @details Inputs: shortFilteredVenousPressure + * @details Outputs: none + * @return the current filtered venous pressure (in mmHg). + *************************************************************************/ +F32 getFilteredVenousPressure( void ) +{ + return shortFilteredVenousPressure; +} /*********************************************************************//** * @brief @@ -717,6 +784,55 @@ return result; } + +/*********************************************************************//** + * @brief + * The filterInlinePressureReadings function adds a new arterial and venous + * pressure sample to the filters. + * @details Inputs: none + * @details Outputs: artPressureReadingsLong[], artPressureReadingsLongIdx, artPressureReadingsLongTotal, artPressureReadingsLongCount, + * artPressureReadingsShort, artPressureReadingsShortIdx, artPressureReadingsShortTotal, artPressureReadingsShortCount, + * venPressureReadingsShort, venPressureReadingsShortIdx, venPressureReadingsShortTotal, venPressureReadingsShortCount, + * longFilteredArterialPressure, shortFilteredArterialPressure, shortFilteredVenousPressure + * @param artPres newest arterial pressure sample to add to filters + * @param venPres newest venous pressure sample to add to filter + * @return none + *************************************************************************/ +static void filterInlinePressureReadings( F32 artPres, F32 venPres ) +{ + // Long filter for arterial pressure. + if ( artPressureReadingsLongCount >= SIZE_OF_LONG_ART_ROLLING_AVG ) + { + artPressureReadingsLongTotal -= artPressureReadingsLong[ artPressureReadingsLongIdx ]; + } + artPressureReadingsLong[ artPressureReadingsLongIdx ] = artPres; + artPressureReadingsLongTotal += artPres; + artPressureReadingsLongIdx = INC_WRAP( artPressureReadingsLongIdx, 0, SIZE_OF_LONG_ART_ROLLING_AVG - 1 ); + artPressureReadingsLongCount = INC_CAP( artPressureReadingsLongCount, SIZE_OF_LONG_ART_ROLLING_AVG ); + longFilteredArterialPressure = artPressureReadingsLongTotal / (F32)artPressureReadingsLongCount; + + // Short filter for arterial pressure. + if ( artPressureReadingsShortCount >= SIZE_OF_SHORT_ART_ROLLING_AVG ) + { + artPressureReadingsShortTotal -= artPressureReadingsShort[ artPressureReadingsShortIdx ]; + } + artPressureReadingsShort[ artPressureReadingsShortIdx ] = artPres; + artPressureReadingsShortTotal += artPres; + artPressureReadingsShortIdx = INC_WRAP( artPressureReadingsShortIdx, 0, SIZE_OF_SHORT_ART_ROLLING_AVG - 1 ); + artPressureReadingsShortCount = INC_CAP( artPressureReadingsShortCount, SIZE_OF_SHORT_ART_ROLLING_AVG ); + shortFilteredArterialPressure = artPressureReadingsShortTotal / (F32)artPressureReadingsShortCount; + + // Short filter for venous pressure. + if ( venPressureReadingsShortCount >= SIZE_OF_SHORT_VEN_ROLLING_AVG ) + { + venPressureReadingsShortTotal -= venPressureReadingsShort[ venPressureReadingsShortIdx ]; + } + venPressureReadingsShort[ venPressureReadingsShortIdx ] = venPres; + venPressureReadingsShortTotal += venPres; + venPressureReadingsShortIdx = INC_WRAP( venPressureReadingsShortIdx, 0, SIZE_OF_SHORT_VEN_ROLLING_AVG - 1 ); + venPressureReadingsShortCount = INC_CAP( artPressureReadingsShortCount, SIZE_OF_SHORT_VEN_ROLLING_AVG ); + shortFilteredVenousPressure = venPressureReadingsShortTotal / (F32)venPressureReadingsShortCount; +} /*********************************************************************//** * @brief @@ -733,8 +849,8 @@ { PRESSURE_OCCLUSION_DATA_T data; - data.arterialPressure = getMeasuredArterialPressure(); - data.venousPressure = getMeasuredVenousPressure(); + data.arterialPressure = shortFilteredArterialPressure; + data.venousPressure = shortFilteredVenousPressure; data.bldPumpOcclusion = getMeasuredBloodPumpOcclusion(); data.diPumpOcclusion = getMeasuredDialInPumpOcclusion(); data.doPumpOcclusion = getMeasuredDialOutPumpOcclusion(); @@ -757,8 +873,8 @@ U32 const bpPressure = getMeasuredBloodPumpOcclusion(); U32 const dialysateInPressure = getMeasuredDialInPumpOcclusion(); U32 const dialysateOutPressure = getMeasuredDialOutPumpOcclusion(); - F32 const arterialPressure = getMeasuredArterialPressure(); - F32 const venousPressure = getMeasuredVenousPressure(); + F32 const arterialPressure = getFilteredArterialPressure(); + F32 const venousPressure = getFilteredVenousPressure(); if ( bpPressure > CARTRIDGE_LOADED_THRESHOLD ) { Index: firmware/App/Controllers/PresOccl.h =================================================================== diff -u -re64816def7cd98e7dcb6d133b3a56c9fea835af3 -r38a89cb53b4ed2e467f51d41e30d43010fdd23e3 --- firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision e64816def7cd98e7dcb6d133b3a56c9fea835af3) +++ firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision 38a89cb53b4ed2e467f51d41e30d43010fdd23e3) @@ -67,11 +67,14 @@ void execPresOcclTest( void ); SELF_TEST_STATUS_T execPresOcclDryTest( void ); -F32 getMeasuredArterialPressure( void ); -F32 getMeasuredVenousPressure( void ); -U32 getMeasuredBloodPumpOcclusion( void ); -U32 getMeasuredDialInPumpOcclusion( void ); -U32 getMeasuredDialOutPumpOcclusion( void ); +F32 getMeasuredArterialPressure( void ); +F32 getFilteredArterialPressure( void ); +F32 getLongFilteredArterialPressure( void ); +F32 getMeasuredVenousPressure( void ); +F32 getFilteredVenousPressure( void ); +U32 getMeasuredBloodPumpOcclusion( void ); +U32 getMeasuredDialInPumpOcclusion( void ); +U32 getMeasuredDialOutPumpOcclusion( void ); BOOL isCartridgeLoaded( void ); BOOL isCartridgeUnloaded( void ); Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r124b3745d056ac667280cfa0ae1fab8610d44ed2 -r38a89cb53b4ed2e467f51d41e30d43010fdd23e3 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 124b3745d056ac667280cfa0ae1fab8610d44ed2) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 38a89cb53b4ed2e467f51d41e30d43010fdd23e3) @@ -1461,8 +1461,8 @@ if ( timeElapsedSinceLastCollect_ms >= TREATMENT_PERIODIC_DATA_LOG_INTERVAL ) { - F32 const arterialPres = getMeasuredArterialPressure(); - F32 const venousPres = getMeasuredArterialPressure(); + F32 const arterialPres = getFilteredArterialPressure(); + F32 const venousPres = getFilteredVenousPressure(); lastTreatmentPeriodicDataCollectTimeStamp = treatmentTimeMS; bloodFlowRateSum_mL_min += getMeasuredBloodFlowRate(); Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -r38a89cb53b4ed2e467f51d41e30d43010fdd23e3 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 38a89cb53b4ed2e467f51d41e30d43010fdd23e3) @@ -841,8 +841,8 @@ } else { - previousNormalArterialPressure = getMeasuredArterialPressure(); - previousNormalVenousPressure = getMeasuredVenousPressure(); + previousNormalArterialPressure = getFilteredArterialPressure(); + previousNormalVenousPressure = getFilteredVenousPressure(); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); @@ -868,8 +868,8 @@ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( SELF_TEST_STATUS_T *result ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_STATE; - F32 const arterialPressure = getMeasuredArterialPressure(); - F32 const venousPressure = getMeasuredVenousPressure(); + F32 const arterialPressure = getFilteredArterialPressure(); + F32 const venousPressure = getFilteredVenousPressure(); // End the test when reaching target pressure or time out if ( ( TRUE == didTimeout( pressureSelfTestBloodPumpRunStartTime, BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) || @@ -912,8 +912,8 @@ { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE; - F32 const arterialPressureDiff = fabs( getMeasuredArterialPressure() - previousNormalArterialPressure ); - F32 const venousPressureDiff = fabs( getMeasuredVenousPressure() - previousNormalVenousPressure ); + F32 const arterialPressureDiff = fabs( getFilteredArterialPressure() - previousNormalArterialPressure ); + F32 const venousPressureDiff = fabs( getFilteredVenousPressure() - previousNormalVenousPressure ); if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_TIME ) ) {