Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r0bcac6885c8461b05da276fd245b580b7339ddfd -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 0bcac6885c8461b05da276fd245b580b7339ddfd) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -59,7 +59,8 @@ #define BICARB_CHAMBER_PERIODIC_FILL_TIME ( 1 * SEC_PER_MIN * \ ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) ///< Periodic bicarb chamber fill request 60 sec x 20 = 1200 #define BAL_CHAMBER_FILL_TIMEOUT_FACTOR 3.0F ///< Balancing Chamber fill timeout factor (300% of observed fill count) - +#define COMP_SLOPE -0.000376F ///< Balancing chamber temperature compensation slope factor +#define COMP_INTERCEPT 1.007269F ///< Balancing chamber temperature compensation intercept factor /// Payload record structure for balancing chamber switch only request typedef struct { @@ -105,6 +106,7 @@ static F32 pendingTdDialysateFlowrate; ///< Pending TD dialysate flow rate; applied at FillEnd after a BC switch completes. static BOOL isBalChamberSwitchingPeriodUpdatePending; ///< BC switching period update pending apply at fill end. static U32 bcSwitchingBasedOnClosedPeriodCounter; ///< Valve-close segments remaining before first-cycle relaxations clear after Qd timing apply. +static F32 balancingError; ///< balancing error that has been calculated during balancing chamber switching. //TODO: remove later once level sensor working static U32 bicarbChamberPeriodicFillCounter; @@ -126,6 +128,7 @@ static void applyBalChamberSwitchingPeriod( F32 tdDialysateFlowrate ); static BOOL isBalChamberTimeBasedSwitching( void ); static void scheduleFirstCycleRelaxAfterQdApply( void ); +static void calculateBalancingChamberError( void ); /*********************************************************************//** * @brief @@ -184,6 +187,7 @@ pendingTdDialysateFlowrate = 0.0F; isBalChamberSwitchingPeriodUpdatePending = FALSE; bcSwitchingBasedOnClosedPeriodCounter = 0; + balancingError = 0.0F; //TODO:remove once level sensor working bicarbChamberPeriodicFillCounter = 0; } @@ -341,6 +345,12 @@ currentBalChamberSwitchingCounter += 1; currentBalChamberFillCounter += 1; + //Calculate balancing error to be used to adjust UF rate + if ( balChamberExecState > BAL_CHAMBER_STATE_IDLE ) + { + calculateBalancingChamberError(); + } + if ( ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE ) && ( balChamberExecState > BAL_CHAMBER_STATE_IDLE ) ) { #ifdef CONDUCTIVE_LEVEL_SENSOR_ENABLED @@ -1524,6 +1534,50 @@ /*********************************************************************//** * @brief + * The calculateBalancingChamberError function calculates the balancing error + * based on the fresh and spent dialysate temperature differences. + * @details \b Inputs: D4 and D50 temperature + * @details \b Outputs: balancing error + * @return balancing error the balancing error that impacts ultrafilteration. + *************************************************************************/ +static void calculateBalancingChamberError( void ) +{ + F32 freshDensity = 0.0F; + F32 spentDensity = 0.0F; + F32 compFreshFlowrate = 0.0F; + F32 compSpentFlowrate = 0.0F; + + // Fresh side dialysate density + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + freshDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D4_TEMP ) ) + COMP_INTERCEPT; + } + else + { + freshDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D99_TEMP ) ) + COMP_INTERCEPT; + } + + spentDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D50_TEMP ) ) + COMP_INTERCEPT; // spent side dialysate density + compFreshFlowrate = getTDDialysateFlowrate() * freshDensity; // Qd * fresh density + compSpentFlowrate = getTDDialysateFlowrate() * spentDensity; // Qd * spent density + balancingError = compFreshFlowrate - compSpentFlowrate; // Error in g/min +} + +/*********************************************************************//** + * @brief + * The getBalancingChamberError function gets the calcualted balancing chamber + * error that may be used for adjusting the ultrafiltration rate. + * @details \b Inputs: none + * @details \b Outputs: none + * @return balancing chamber error + *************************************************************************/ +F32 getBalancingChamberError( void ) +{ + return balancingError; +} + +/*********************************************************************//** + * @brief * The publishBalChamberData function broadcasts the balancing chamber * execution data at defined interval. * @details \b Inputs: balChamberDataPublicationTimerCounter Index: firmware/App/Controllers/BalancingChamber.h =================================================================== diff -u -ra6737c3bcc8286c153b778c2c395f465e76aaafb -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Controllers/BalancingChamber.h (.../BalancingChamber.h) (revision a6737c3bcc8286c153b778c2c395f465e76aaafb) +++ firmware/App/Controllers/BalancingChamber.h (.../BalancingChamber.h) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -72,6 +72,7 @@ BOOL getBalChamberSwitchingOnlyStatus( void ); // Get balancing chamber switching only status void setBalChamberSwitchingOnlyStatus( BOOL OnOff ); // Set balancing chamber switching only status U32 getBalChamberSwitchingPeriod( void ); // Get balancing chamber switching period +F32 getBalancingChamberError( void ); // Get balancing chamber error to adjust UF rate. BOOL testDDBalChamberDataPublishIntervalOverride( MESSAGE_T *message ); // To override the balancing chamber data publish interval BOOL testBalChamberSwFreqOverride( MESSAGE_T *message ); // To override the balancing chamber switching frequency Index: firmware/App/Controllers/Ultrafiltration.c =================================================================== diff -u -r0bcac6885c8461b05da276fd245b580b7339ddfd -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision 0bcac6885c8461b05da276fd245b580b7339ddfd) +++ firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "BalancingChamber.h" #include "ConcentratePumps.h" #include "Messaging.h" #include "OperationModes.h" @@ -34,13 +35,10 @@ #define UF_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the ultrafiltration data published. #define UF_COMPENSATION_PERIOD ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Interval at which the ultrafiltration compenstaion executed. #define UF_COMP_INTERVAL ( UF_COMPENSATION_PERIOD / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the peroidic ultrafiltration compensation calculated. -#define COMP_SLOPE -0.000376F ///< UF Temperature compensation slope factor -#define COMP_INTERCEPT 1.007269F ///< UF temperature compensation intercept factor #define ZERO_RATE 0.0F ///< Zero value. // ********** private data ********** -static UF_EXEC_STATE_T ufExecState; ///< Current ultrafiltration executive state. static BOOL isUltrafiltrationRequested; ///< Flag indicating ultrafiltration request. static U32 currentUFCompCounter; ///< Counter (in task interval) to initiate the periodic ultrafiltration temperature compensation. static F32 compUFrate; ///< compensated UF rate @@ -50,10 +48,7 @@ // ********** private function prototypes ********** -static UF_EXEC_STATE_T handleUFRunningState( void ); -static UF_EXEC_STATE_T handleUFPausedState( void ); static void updateUFRequest( void ); -static void UpdateUFCompensation( void ); static void publishUltrafiltrationData( void ); /*********************************************************************//** @@ -65,7 +60,6 @@ *************************************************************************/ void initUltrafiltration( void ) { - ufExecState = DD_UF_PAUSED; ufDataPublishInterval.data = UF_DATA_PUBLISH_INTERVAL; ufDataPublishInterval.ovData = UF_DATA_PUBLISH_INTERVAL; ufDataPublishInterval.ovInitData = 0; @@ -74,7 +68,7 @@ currentUFCompCounter = 0; compUFrate = getTDUFRate(); ufDataPublicationTimerCounter = 0; - isUFRateUpdated = FALSE; + isUFRateUpdated = TRUE; } /*********************************************************************//** @@ -92,106 +86,55 @@ /*********************************************************************//** * @brief - * The execUFControl function executes the ultrafiltration state machine. - * @details \b Inputs: ufExecState - * @details \b Outputs: ufExecState - * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong ultrafiltration - * state invoked. + * The handleUFControl function handles the ultrafiltration run/stop states + * and calcualtes the final ultrafilration rate if the temp compensation is enbaled. + * @details \b Inputs: balancing error, TD UF rate + * @details \b Outputs: calculated UF rate * @details Warning: The compensated UF should be caclulated first and then * call 'updateUFRequest' function. * @return current state. *************************************************************************/ -U32 execUFControl( void ) +void handleUFControl( void ) { - // Trimmer heater enabled, hence UF temp compensation is optional + F32 balancingError; + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_UF_TEMP_COMPENSATION ) != TRUE ) { - // Compensate balancing error at defined interval - UpdateUFCompensation(); + if ( ( ++currentUFCompCounter >= UF_COMP_INTERVAL ) || ( TRUE == isUFRateUpdated ) ) + { + // Find the offset + balancingError = getBalancingChamberError(); + // Update compensate UF rate with the balancing chamber error + compUFrate = getTDUFRate() + balancingError; + + currentUFCompCounter = 0; + isUFRateUpdated = FALSE; + } } else if ( TRUE == isUFRateUpdated ) { - //get updated UF rate + // Get updated UF rate compUFrate = getTDUFRate(); - - // Update UF rate - setConcentratePumpTargetSpeed( D76_PUMP, compUFrate, DOSING_CONT_VOLUME ); - isUFRateUpdated = FALSE; + // Reset the flag + isUFRateUpdated = FALSE; } // Calculate UF volume and determine UF pause/run updateUFRequest(); - // execute current ultrafiltration exec state - switch ( ufExecState ) - { - case DD_UF_PAUSED: - ufExecState = handleUFPausedState(); - break; - - case DD_UF_RUNNING: - ufExecState = handleUFRunningState(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_UF_INVALID_EXEC_STATE, ufExecState ) - ufExecState = DD_UF_PAUSED; - break; - } - - //Publish ultrafiltration data - publishUltrafiltrationData(); - - return ufExecState; -} - -/*********************************************************************//** - * @brief - * The handleUFPausedState function handles the ultrafiltration - * paused state. - * @details \b Inputs:isUltrafiltrationRequested - * @details \b Outputs: UF state - * @return next UF state. - *************************************************************************/ -static UF_EXEC_STATE_T handleUFPausedState( void ) -{ - UF_EXEC_STATE_T state = DD_UF_PAUSED; - + // UF pump run or stop based on the flag if ( TRUE == isUltrafiltrationRequested ) { - // start with TD UF rate - compUFrate = getTDUFRate(); - currentUFCompCounter = 0; - setConcentratePumpTargetSpeed( D76_PUMP, compUFrate, DOSING_CONT_VOLUME ); requestConcentratePumpOn( D76_PUMP ); - - //Tranistion to run state - state = DD_UF_RUNNING; } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleUFPausedState function handles the ultrafiltration - * running state. - * @details \b Inputs:isUltrafiltrationRequested - * @details \b Outputs: UF state - * @return next UF state. - *************************************************************************/ -static UF_EXEC_STATE_T handleUFRunningState( void ) -{ - UF_EXEC_STATE_T state = DD_UF_RUNNING; - - if ( TRUE != isUltrafiltrationRequested ) + else { requestConcentratePumpOff( D76_PUMP, FALSE ); - state = DD_UF_PAUSED; } - return state; + //Publish ultrafiltration data + publishUltrafiltrationData(); } /*********************************************************************//** @@ -234,62 +177,6 @@ /*********************************************************************//** * @brief - * The UpdateUFCompensation function updates the ultrafiltration rate - * based on the dialysate temperature compensation. - * @details \b Inputs: D4 and D50 temperature - * @details \b Outputs: updated UF rate - * @return none. - *************************************************************************/ -static void UpdateUFCompensation( void ) -{ - if ( ( ++currentUFCompCounter >= UF_COMP_INTERVAL ) || ( TRUE == isUFRateUpdated ) ) - { - F32 freshDensity = 0.0F; - F32 spentDensity = 0.0F; - F32 compFreshFlowrate = 0.0F; - F32 compSpentFlowrate = 0.0F; - F32 balancingError = 0.0F; - - // Fresh side dialysate density - if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) - { - freshDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D4_TEMP ) ) + COMP_INTERCEPT; - } - else - { - freshDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D99_TEMP ) ) + COMP_INTERCEPT; - } - spentDensity = ( COMP_SLOPE * getFilteredTemperatureValue( D50_TEMP ) ) + COMP_INTERCEPT; // spent side dialysate density - compFreshFlowrate = getTDDialysateFlowrate() * freshDensity; // Qd * fresh density - compSpentFlowrate = getTDDialysateFlowrate() * spentDensity; // Qd * spent density - balancingError = compFreshFlowrate - compSpentFlowrate; // Error in g/min - - //Update compensate UF rate with the balancing chamber error - compUFrate = getTDUFRate() + balancingError; - - // Update UF rate - setConcentratePumpTargetSpeed( D76_PUMP, compUFrate, DOSING_CONT_VOLUME ); - - currentUFCompCounter = 0; - isUFRateUpdated = FALSE; - } -} - -/*********************************************************************//** - * @brief - * The getCurrentUFExecState function returns the current state - * of the ultrafiltration. - * @details \b Inputs: ufExecState - * @details \b Outputs: none - * @return the current state of UF execution state. - *************************************************************************/ -UF_EXEC_STATE_T getCurrentUFExecState( void ) -{ - return ufExecState; -} - -/*********************************************************************//** - * @brief * The publishUltrafiltrationData function broadcasts the ultrafiltration * data at defined interval. * @details \b Inputs: ufDataPublicationTimerCounter @@ -304,7 +191,6 @@ { UF_DATA_T data; - data.ufExecState = (U32)ufExecState; data.ufRate = getTDUFRate(); data.compUFrate = compUFrate; data.isUFRequested = (U32)isUltrafiltrationRequested; Index: firmware/App/Controllers/Ultrafiltration.h =================================================================== diff -u -r830213bc6dcc1a684610caf78c79d55f2cb41e93 -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Controllers/Ultrafiltration.h (.../Ultrafiltration.h) (revision 830213bc6dcc1a684610caf78c79d55f2cb41e93) +++ firmware/App/Controllers/Ultrafiltration.h (.../Ultrafiltration.h) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -34,7 +34,6 @@ /// ultrafiltration data structure typedef struct { - U32 ufExecState; ///< Ultrafiltration execution state F32 ufRate; ///< Ultrafiltration rate from TD F32 compUFrate; ///< Compensated UF rate U32 isUFRequested; ///< Ultrafiltration run or puase request @@ -44,8 +43,7 @@ void initUltrafiltration( void ); // Initialize ultrafiltration unit void transitionToUltrafiltration( void ); // Prepares for transition to ultrafiltration execution -U32 execUFControl( void ); // Execute the ultrafiltration state machine -UF_EXEC_STATE_T getCurrentUFExecState( void ); // Get the current state of the balancing chamber execution +void handleUFControl( void ); // handle ultrafiltration control void signalUFRateUpdate( void ); // Update UF rate when there is a change in rate BOOL testDDUFDataPublishIntervalOverride( MESSAGE_T *message ); // To override the UF data publish interval Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r0bcac6885c8461b05da276fd245b580b7339ddfd -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 0bcac6885c8461b05da276fd245b580b7339ddfd) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -834,8 +834,8 @@ #endif else { - //Execute ultrafiltration - execUFControl(); + // Perform ultrafiltration + handleUFControl(); } return state; Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r5f1b50a1d9a7bd6ea17bb666e28ccfeafe56432c -r78dc7a98fb2a3d28bbdeb4eade1bba03641433d3 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 5f1b50a1d9a7bd6ea17bb666e28ccfeafe56432c) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 78dc7a98fb2a3d28bbdeb4eade1bba03641433d3) @@ -137,7 +137,7 @@ SW_FAULT_ID_POST_GEND_MODE_INVALID_EXEC_STATE = 106, SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE = 107, SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE1 = 108, - SW_FAULT_ID_UF_INVALID_EXEC_STATE = 109, + SW_FAULT_ID_AVAILABLE_TO_USE = 109, SW_FAULT_ID_SPENT_CHAMBER_FILL_INVALID_EXEC_STATE = 110, SW_FAULT_ID_TD_INVALID_BLOOD_LEAK_STATE = 111, SW_FAULT_ID_BLOOD_LEAK_EMBEDDED_MODE_INVALID_STATE = 112,