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 ) {