Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -rbd896114f304304a7096b30b2a85067a64645e82 -r9d2242ea86f1e311f6ccc16bb00b203afceb91a8 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision bd896114f304304a7096b30b2a85067a64645e82) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 9d2242ea86f1e311f6ccc16bb00b203afceb91a8) @@ -7,13 +7,14 @@ * * @file ModeGenDialysate.c * -* @author (last) Michael Garthwaite -* @date (last) 29-Jan-2026 +* @author (last) Jashwant Gantyada +* @date (last) 13-Mar-2026 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 * ***************************************************************************/ +#include "math.h" // for 'exp' #include "BalancingChamber.h" #include "ConcentratePumps.h" @@ -33,6 +34,7 @@ #include "TaskGeneral.h" #include "TDInterface.h" #include "Temperature.h" +#include "TestSupport.h" #include "Timers.h" #include "Ultrafiltration.h" #include "Valves.h" @@ -62,9 +64,35 @@ #define LOW_DIAL_FLOW_RATE 150.0F ///< Dialysate flow rate lesser than 150 considered to be low Qds. #define ZERO_DIAL_FLOW_RATE 0.0F ///< Zero dialysate flow rate #define SPENT_CHAMBER_FILL_MAX_COUNT 10 ///< Total number of spent chamber fill allowed. -#define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. +#define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. +#define B1B2_HEAT_DIS_FIRST_COEFF 0.00000000487858F ///< First coefficient for Heat loss dissipation calculation from D4 to D28(cubic equation). +#define B1B2_HEAT_DIS_SEC_COEFF 0.0000063124F ///< Second coefficient for Heat loss dissipation calculation from D4 to D28. +#define B1B2_HEAT_DIS_THIRD_COEFF 0.00258513F ///< Third coefficient for Heat loss dissipation calculation from D4 to D28. +#define B1B2_HEAT_DIS_FOURTH_COEFF 0.242013F ///< Fourth coefficient for Heat loss dissipation calculation from D4 to D28. +#define B3_HEAT_DIS_FIRST_COEFF 0.0000000067756F ///< First coefficient for Heat loss dissipation calculation from D28 to Dialyzer(cubic equation). +#define B3_HEAT_DIS_SEC_COEFF 0.0000085278F ///< Second coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define B3_HEAT_DIS_THIRD_COEFF 0.0035126F ///< Third coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define B3_HEAT_DIS_FOURTH_COEFF 0.63893F ///< Fourth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. + +#define BETA2_0_B1B2_HEAT_DIS_FIRST_COEFF 0.0000000000323F ///< First coefficient for Heat loss dissipation calculation from D4 to D28(Beta2.0 quartic equation). +#define BETA2_0_B1B2_HEAT_DIS_SEC_COEFF 0.0000000557449F ///< Second coefficient for Heat loss dissipation calculation from D4 to D28. +#define BETA2_0_B1B2_HEAT_DIS_THIRD_COEFF 0.0000358378838F ///< Third coefficient for Heat loss dissipation calculation from D4 to D28. +#define BETA2_0_B1B2_HEAT_DIS_FOURTH_COEFF 0.01072756717F ///< Fourth coefficient for Heat loss dissipation calculation from D4 to D28. +#define BETA2_0_B1B2_HEAT_DIS_FIFTH_COEFF 1.28454963635F ///< Fifth coefficient for Heat loss dissipation calculation from D4 to D28. +#define BETA2_0_B3_HEAT_DIS_FIRST_COEFF 0.000000000109F ///< First coefficient for Heat loss dissipation calculation from D28 to Dialyzer(Beta2.0 quartic equation). +#define BETA2_0_B3_HEAT_DIS_SEC_COEFF 0.000000188979F ///< Second coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define BETA2_0_B3_HEAT_DIS_THIRD_COEFF 0.000120516848F ///< Third coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define BETA2_0_B3_HEAT_DIS_FOURTH_COEFF 0.033806726263F ///< Fourth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define BETA2_0_B3_HEAT_DIS_FIFTH_COEFF 3.691985090908F ///< Fifth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. + +#define PUMP_SPEED_SLOPE_FACTOR_DIENER_2000 1.24F ///< D48 Diener 2000 pump speed slope (y = 1.24x + 30). +#define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000 30.0F ///< D48 Diener 2000 pump speed intercept. +#define PUMP_SPEED_SLOPE_FACTOR_DIENER_1000 2.869F ///< D48 Diener 1000 pump speed slope (y = 2.869x + 25.956). +#define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000 25.956F ///< D48 Diener 1000 pump speed intercept. +#define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. + //Testing -#define DELAY_BC_SWITCHING_AT_START_UP ( 10 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., +#define DELAY_BC_SWITCHING_AT_START_UP ( 10 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., /// Payload record structure for Gen dialysate execution state set request typedef struct { @@ -88,6 +116,7 @@ static U32 bypassStateDelayStartTimeMS; ///< Delay balancing chamber switching for a second to preapre pump steady state. static BOOL delayBypassStateFlag; ///< To indicate change in treatment parameters static F32 dialysateToDialyzerFlowRate; ///< Current dialysate to dialyzer flow rate (ml/min) +static U32 d48PumpSpeed; ///< Initial D48 pump speed based on the Qd. // ********** private function prototypes ********** @@ -103,7 +132,13 @@ static void updateDialysateToDialyzerFlowRate( void ); static void checkDialysateTemperature( void ); static void monitorChamberLevelStatus( void ); +static F32 calculateBeta2HeatDissipationB1andB2( void ); +static F32 calculateBeta2HeatDissipationB3( void ); +static F32 calculateHeatDissipationB1andB2( void ); +static F32 calculateHeatDissipationB3( void ); +static F32 calculateInitialTemp( F32 targetTemp, F32 heatDissipation ); static void publishGenDialysateModeData( void ); +static U32 getFreshDialPumpInitialRpm( void ); /*********************************************************************//** * @brief @@ -137,6 +172,7 @@ bicarbFillStartTimeMS = 0; pendingSpentChamberFill = FALSE; pendingBicarbChamberFill = FALSE; + d48PumpSpeed = getDialysatePumpMinRPM( D48_PUMP ); //Testing bypassStateDelayStartTimeMS = 0; delayBypassStateFlag = TRUE; @@ -160,8 +196,13 @@ *************************************************************************/ U32 transitionToGenDialysateMode( void ) { + U32 initialD48PumpSpeed = 0U; + initGenDialysateMode(); setCurrentSubState( NO_SUB_STATE ); + //calculateD48PumpSpeedForBCFill(); + initialD48PumpSpeed = getCalculatedD48PumpSpeedForBCFill(); + setD48PumpSpeedForBCFill( initialD48PumpSpeed ); transitionToUltrafiltration(); return genDialysateState; @@ -194,6 +235,26 @@ /*********************************************************************//** * @brief + * The getFreshDialPumpInitialRpm function returns fresh dialysate pump initial + * rpm based on hardwawre configuration. + * @details Inputs: FRESH_DIAL_PUMP_INITIAL_RPM, FRESH_DIAL_PUMP_INITIAL_RPM_B1_9_B2_0 + * @details Outputs: none + * @return fresh dialysate pump initial RPM for the active hardware variant + *************************************************************************/ +static U32 getFreshDialPumpInitialRpm( void ) +{ + U32 rpm = FRESH_DIAL_PUMP_INITIAL_RPM_B1_9_B2_0; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) ) + { + rpm = FRESH_DIAL_PUMP_INITIAL_RPM; + } + + return rpm; +} + +/*********************************************************************//** + * @brief * The setModeGenDStateTransition function sets the actuators and variables * for the state transition in generate dialysis mode. * @details Inputs: Valve states, Pump speed @@ -216,21 +277,34 @@ setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve - setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve - setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + setValveState( D8_VALV, VALVE_STATE_CLOSED ); + setValveState( D54_VALV, VALVE_STATE_CLOSED ); + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + setValveState( D31_VALV, VALVE_STATE_CLOSED ); + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + } + // Turn on the primary heater calculateTargetDialysateTemp(); setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + //Turn on Trimmer heater + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + startHeater( D45_HEAT ); + //Testing : Enable close loop once testing is complete //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -245,7 +319,11 @@ case DD_GEND_DIALYSATE_DELIVERY_STATE: //Previous state setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve - setValveState( D64_VALV, VALVE_STATE_CLOSED ); + setValveState( D8_VALV, VALVE_STATE_CLOSED ); + setValveState( D54_VALV, VALVE_STATE_CLOSED ); + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + setValveState( D31_VALV, VALVE_STATE_CLOSED ); setValveState( D14_VALV, VALVE_STATE_OPEN ); setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve @@ -255,10 +333,14 @@ setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + //Turn on Trimmer heater + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + startHeater( D45_HEAT ); + //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -267,17 +349,33 @@ setValveState( D34_VALV, VALVE_STATE_CLOSED ); // Bypass valve setValveState( D35_VALV, VALVE_STATE_OPEN ); // VDI setValveState( D40_VALV, VALVE_STATE_OPEN ); // VDO - setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + } break; case DD_GEND_SPENT_CHAMBER_FILL_STATE: //Set valves and actuators setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO + setValveState( D8_VALV, VALVE_STATE_CLOSED ); + setValveState( D54_VALV, VALVE_STATE_CLOSED ); + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + setValveState( D31_VALV, VALVE_STATE_CLOSED ); setValveState( D14_VALV, VALVE_STATE_OPEN ); setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve - setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + } + setValveState( D47_VALV, VALVE_STATE_OPEN ); // Spent chamber purge valve requestConcentratePumpOff( D76_PUMP, FALSE ); @@ -289,8 +387,10 @@ setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + // Stop trimmer heater + stopHeater( D45_HEAT ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_FILL_RPM, TRUE ); //Rinse pump On @@ -313,8 +413,13 @@ setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve - setValveState( D64_VALV, VALVE_STATE_OPEN ); // Bicarb chamber purge valve - setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve + setValveState( D64_VALV, VALVE_STATE_OPEN ); // Bicarb chamber purge valve + } + bicarbFillStartTimeMS = getMSTimerCount(); // Turn on the primary heater @@ -328,11 +433,11 @@ setRinsePumpState( RINSE_PUMP_STATE_ON ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); @@ -353,7 +458,6 @@ setValveState( D40_VALV, VALVE_STATE_CLOSED ); setValveState( D31_VALV, VALVE_STATE_CLOSED ); setValveState( D47_VALV, VALVE_STATE_CLOSED ); - setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D54_VALV, VALVE_STATE_CLOSED ); setValveState( D14_VALV, VALVE_STATE_CLOSED ); setValveState( D52_VALV, VALVE_STATE_CLOSED ); @@ -365,7 +469,12 @@ setValveState( D34_VALV, VALVE_STATE_OPEN ); setValveState( D53_VALV, VALVE_STATE_OPEN ); - setValveState( D80_VALV, VALVE_STATE_OPEN ); + + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + } break; case DD_GEND_ISOLATED_UF_STATE: @@ -496,6 +605,68 @@ /*********************************************************************//** * @brief + * The getD48PumpSpeedForBCFill function returns the calculated D48 pump speed + * @details \b Inputs: d48PumpSpeed + * @details \b Outputs: none + * @return D48 pump speed. + *************************************************************************/ +U32 getD48PumpSpeedForBCFill( void ) +{ + return d48PumpSpeed; +} + +/*********************************************************************//** + * @brief + * The setD48PumpSpeedForBCFill function sets the updated D48 pump speed. + * @details \b Inputs: none + * @details \b Outputs: d48PumpSpeed + * @param pumpSpeed Dialysate pump speed + * @return none. + *************************************************************************/ +void setD48PumpSpeedForBCFill( U32 pumpSpeed ) +{ + d48PumpSpeed = pumpSpeed; +} + +/*********************************************************************//** + * @brief + * The calculateUpdatedD28TargetDialysateTemp function calculate the delta temperature + * required for dialysate temperature to meet the set temperature at dialyzer. + * @details \b Inputs: Qd and target temperature. + * @details \b Outputs: Adjusted D28 Target temperature + * @return none. + *************************************************************************/ +F32 calculateUpdatedD28TargetDialysateTemp( void ) +{ + // Get the dialysate flow rate from TD + F32 dialFlowrate = getTDDialysateFlowrate(); + F32 deltaTemp = 0.0F; + F32 heatDissipation_b3 = 0.0F; + F32 targetTemp = getTDTargetDialysateTemperature(); + F32 targetTempAtD28 = 0.0F; + + // Heat loss model predicts the heat loss ( B3) in the DD flow path and + // finds the delta temperature to be added with the target temperature + // to maintain the target temperature at dialyzer. + //Lets calculate B3 heat dissipation factor + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) ) + { + // based on Beta2.0 heat loss model + heatDissipation_b3 = calculateBeta2HeatDissipationB3(); + } + else + { + heatDissipation_b3 = calculateHeatDissipationB3(); + } + + // Reverse calculation of target temp at D28 to get the target dialyzer temperature + targetTempAtD28 = calculateInitialTemp( targetTemp, heatDissipation_b3 ); + + return targetTempAtD28; +} + +/*********************************************************************//** + * @brief * The monitorChamberLevelStatus function checks the spent chamber and bicarb * chamber level status and updates the corrosponding flags. * @details \b Inputs: Spent and bicarb chamber levels. @@ -529,12 +700,18 @@ static void calculateTargetDialysateTemp( void ) { // Get the dialysate flow rate from TD - F32 dialFlowrate = getTDDialysateFlowrate(); - F32 deltaTemp = 0.0F; + F32 dialFlowrate = getTDDialysateFlowrate(); + F32 deltaTemp = 0.0F; + F32 heatDissipation_b1b2 = 0.0F; + F32 heatDissipation_b3 = 0.0F; + F32 targetTemp = getTDTargetDialysateTemperature(); + F32 targetTempAtD28 = 0.0F; + F32 targetTempAtD4 = 0.0F; +#ifndef __REVISED_HEATER_MODEL__ if ( dialFlowrate >= LOW_DIAL_FLOW_RATE ) { - // linear releationship seen against high dialysate flowrate Vs DeltaTemp + // linear relationship seen against high dialysate flowrate Vs DeltaTemp // deltaTemp = (-0.0029 * Qd) + 3.47 deltaTemp = ( LINEAR_SLOPE_FACTOR * dialFlowrate ) + LINEAR_INTERCEPT_FACTOR; } @@ -544,13 +721,201 @@ deltaTemp = ( QUAD_FIRST_COEFFICIENT * dialFlowrate * dialFlowrate ) + ( QUAD_SECOND_COEFFICIENT * dialFlowrate ) + QUAD_THIRD_COEFFICIENT; } - // Adjust the D4 target temperature targetHydChamberFluidTemp.data = getTDTargetDialysateTemperature() + deltaTemp; +#else + // Heat loss model predicts the heat loss ( B1,B2 and B3) in the DD flow path and + // finds the delta temperature to be added with the target temperature + // to maintain the target temperature at dialyzer. + // Lets calculate the B1,B2 and B3 heat dissipation factors + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) ) + { + // based on Beta2.0 heat loss model + heatDissipation_b3 = calculateBeta2HeatDissipationB3(); + heatDissipation_b1b2 = calculateBeta2HeatDissipationB1andB2(); + } + else + { + heatDissipation_b3 = calculateHeatDissipationB3(); + heatDissipation_b1b2 = calculateHeatDissipationB1andB2(); + } + + // Reverse calculation of target temp at D28 to get the target dialyzer temperature + targetTempAtD28 = calculateInitialTemp( targetTemp, heatDissipation_b3 ); + // calculation of target temp at D4 to get the target temp at D28 level + targetTempAtD4 = calculateInitialTemp( targetTempAtD28, heatDissipation_b1b2 ); + + targetHydChamberFluidTemp.data = targetTempAtD4; +#endif } /*********************************************************************//** * @brief + * The calculateBeta2HeatDissipationB1andB2 function calculates the heat dissipation + * constants called B1 and B2 that describes the heat loss between D4 to D28 in + * the PID flow path for Beta2.0 hardware. + * @details \b Inputs: Qd. + * @details \b Outputs: none + * @return the calculated heat dissipation constants. + *************************************************************************/ +static F32 calculateBeta2HeatDissipationB1andB2( void ) +{ + // Get the dialysate flow rate from TD + F32 b1b2 = 0.0F; + F32 qd = getTDDialysateFlowrate(); + F32 firstPart = BETA2_0_B1B2_HEAT_DIS_FIRST_COEFF * qd * qd * qd * qd; + F32 secondPart = BETA2_0_B1B2_HEAT_DIS_SEC_COEFF * qd * qd * qd; + F32 thirdPart = BETA2_0_B1B2_HEAT_DIS_THIRD_COEFF * qd * qd; + F32 fourthPart = BETA2_0_B1B2_HEAT_DIS_FOURTH_COEFF * qd; + + // B1B2 = 0.0000000000323x4-0.0000000557449x3+0.0000358378838x2-0.01072756717x + 1.28454963635 + b1b2 = firstPart - secondPart + thirdPart - fourthPart + BETA2_0_B1B2_HEAT_DIS_FIFTH_COEFF; + + return b1b2; +} + +/*********************************************************************//** + * @brief + * The calculateBeta2HeatDissipationB3 function calculates the heat dissipation + * constants called B3 that describes the heat loss between D28 to dialyzer in + * the PID flow path for Beta2.0 hardware. + * @details \b Inputs: Qd. + * @details \b Outputs: none + * @return the calculated heat dissipation constant. + *************************************************************************/ +static F32 calculateBeta2HeatDissipationB3( void ) +{ + // Get the dialysate flow rate from TD + F32 b3 = 0.0F; + F32 qd = getTDDialysateFlowrate(); + F32 firstPart = BETA2_0_B3_HEAT_DIS_FIRST_COEFF * qd * qd * qd * qd; + F32 secondPart = BETA2_0_B3_HEAT_DIS_SEC_COEFF * qd * qd * qd; + F32 thirdPart = BETA2_0_B3_HEAT_DIS_THIRD_COEFF * qd * qd; + F32 fourthPart = BETA2_0_B3_HEAT_DIS_FOURTH_COEFF * qd; + + // B3 = 0.000000000109x4-0.000000188979x3+0.000120516848x2-0.033806726263x+3.691985090908 + b3 = firstPart - secondPart + thirdPart - fourthPart + BETA2_0_B3_HEAT_DIS_FIFTH_COEFF; + + return b3; +} + +/*********************************************************************//** + * @brief + * The calculateHeatDissipationB1andB2 function calculates the heat dissipation + * constants called B1 and B2 that describes the heat loss between D4 to D28 in + * the PID flow path. + * @details \b Inputs: Qd. + * @details \b Outputs: none + * @return the calculated heat dissipation constants. + *************************************************************************/ +static F32 calculateHeatDissipationB1andB2( void ) +{ + // Get the dialysate flow rate from TD + F32 b1b2 = 0.0F; + F32 qd = getTDDialysateFlowrate(); + F32 firstPart = B1B2_HEAT_DIS_FIRST_COEFF * qd * qd * qd; + F32 secondPart = B1B2_HEAT_DIS_SEC_COEFF * qd * qd; + F32 thirdPart = B1B2_HEAT_DIS_THIRD_COEFF * qd; + + // B1B2 = 4.87858E-09x3 - 6.31264E-06x2 + 2.58513E-03x - 2.42013E-01 + b1b2 = firstPart - secondPart + thirdPart - B1B2_HEAT_DIS_FOURTH_COEFF; + + return b1b2; +} + +/*********************************************************************//** + * @brief + * The calculateHeatDissipationB3 function calculates the heat dissipation + * constants called B3 that describes the heat loss between D28 to dialyzer in + * the PID flow path. + * @details \b Inputs: Qd. + * @details \b Outputs: none + * @return the calculated heat dissipation constant. + *************************************************************************/ +static F32 calculateHeatDissipationB3( void ) +{ + // Get the dialysate flow rate from TD + F32 b3 = 0.0F; + F32 qd = getTDDialysateFlowrate(); + F32 firstPart = B3_HEAT_DIS_FIRST_COEFF * qd * qd * qd; + F32 secondPart = B3_HEAT_DIS_SEC_COEFF * qd * qd; + F32 thirdPart = B3_HEAT_DIS_THIRD_COEFF * qd; + + // B3 = 6.7756E-09x3 - 8.5278E-06x2 + 3.5126E-03x - 6.3893E-01 + b3 = firstPart - secondPart + thirdPart - B3_HEAT_DIS_FOURTH_COEFF; + + return b3; +} + +/*********************************************************************//** + * @brief + * The calculateInitialTemp function calculates the initial temperature + * required to get the target temperature considering heat loss. + * @details \b Inputs: ambient temperature + * @details \b Outputs: none + * @param targetTemp the target/final temperature + * @param heatDissipation the heat dissipation constant + * @return the calculated initial temperature. + *************************************************************************/ +static F32 calculateInitialTemp( F32 targetTemp, F32 heatDissipation ) +{ + // Get the ambient temperature from TD + //TODO : replace once amb temp is in place. using board temperature + // to make use of feeding the value via dialin + F32 ambTemp = getTemperatureValue( BRD_TEMP ); + F32 expB = exp(-heatDissipation); + F32 tempDiff = targetTemp - ambTemp; + F32 T0 = 0.0F; + + // T0 = Tamb + (Tf -Tamb)e^-B + T0 = ambTemp + ( tempDiff * expB ); + + return T0; +} + +/*********************************************************************//** + * @brief + * The getCalculatedD48PumpSpeedForBCFill function returns the D48 pump speed + * calculated from dialysate flow rate (Qd) for continuous delivery. + * @details \b Inputs: Qd from TD, test config TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP. + * @details \b Outputs: none + * @return Calculated D48 pump speed in RPM (Diener 1000 or 2000 formula per test config). + *************************************************************************/ +U32 getCalculatedD48PumpSpeedForBCFill( void ) +{ + F32 dialFlowrate = getTDDialysateFlowrate(); + F32 slope; + F32 intercept; + F32 calculatedSpeed; + U32 rpm; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) + { + slope = PUMP_SPEED_SLOPE_FACTOR_DIENER_2000; + intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000; + } + else + { + slope = PUMP_SPEED_SLOPE_FACTOR_DIENER_1000; + intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000; + } + + // Calculate nominal speed from Qd. + calculatedSpeed = ( slope * dialFlowrate ) + intercept; + + // Prevent negative before converting to unsigned and round up using ceilf. + if ( calculatedSpeed < 0.0F ) + { + calculatedSpeed = 0.0F; + } + + rpm = (U32)ceilf( calculatedSpeed ); + + return rpm; +} + +/*********************************************************************//** + * @brief * The handleGenDDialysateIsolatedUFState function performs the * Isolated ultrafiltration operations. * @details \b Inputs: none. @@ -838,6 +1203,8 @@ *************************************************************************/ void updateTreatmentSettings( void ) { + F32 initialPumpSpeed = 0.0F; + // Update any dynamic treatment parameter changes if ( TRUE == isTreatmentParamUpdated ) { @@ -856,6 +1223,11 @@ //TODO: update others parameters setting as needed. signalUFRateUpdate(); + //Update D48 pump speed + //calculateD48PumpSpeedForBCFill(); + initialPumpSpeed = getCalculatedD48PumpSpeedForBCFill(); + setD48PumpSpeedForBCFill( initialPumpSpeed ); + //reset the flag isTreatmentParamUpdated = FALSE; } @@ -1056,8 +1428,8 @@ * @brief * The testDialDeliveryInProgressOverride function sets the override value * of the dialysate delivery In progress flag. - * @details Inputs: isDialDeliveryInProgress - * @details Outputs: isDialDeliveryInProgress + * @details \b Inputs: isDialDeliveryInProgress + * @details \b Outputs: isDialDeliveryInProgress * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not @@ -1073,8 +1445,8 @@ * @brief * The testDialGoodToDeliverStatusOverride function sets the override value * of the dialysate good to deliver status flag. - * @details Inputs: isDialysateGoodtoDeliver - * @details Outputs: isDialysateGoodtoDeliver + * @details \b Inputs: isDialysateGoodtoDeliver + * @details \b Outputs: isDialysateGoodtoDeliver * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not