Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r0fdb539277f865425aba65d98e8e9147484a99e0 -r2396d4a37bda6655349756098a5315cdd54a3803 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 0fdb539277f865425aba65d98e8e9147484a99e0) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 2396d4a37bda6655349756098a5315cdd54a3803) @@ -69,6 +69,26 @@ #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 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 BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. //Testing @@ -112,6 +132,11 @@ 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 ); @@ -175,6 +200,8 @@ initGenDialysateMode(); setCurrentSubState( NO_SUB_STATE ); + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); //calculateD48PumpSpeedForBCFill(); initialD48PumpSpeed = getCalculatedD48PumpSpeedForBCFill(); setD48PumpSpeedForBCFill( initialD48PumpSpeed ); @@ -243,7 +270,8 @@ switch( state ) { case DD_GEND_STATE_START: - // Do nothing + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); break; case DD_GEND_DIALYSATE_BYPASS_STATE: @@ -272,7 +300,14 @@ startHeater( D5_HEAT ); //Turn on Trimmer heater - setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + } + else + { + setHeaterTargetTemperature( D45_HEAT, getD99AverageTemperature() ); + } startHeater( D45_HEAT ); //Testing : Enable close loop once testing is complete @@ -285,13 +320,18 @@ setRinsePumpState( RINSE_PUMP_STATE_ON ); transitionToBalChamberFill(); + // Activate Balancing Chamber Switching + requestBalChamberSwitching( TRUE ); //Testing bypassStateDelayStartTimeMS = getMSTimerCount(); delayBypassStateFlag = TRUE; break; case DD_GEND_DIALYSATE_DELIVERY_STATE: + // Activate Balancing Chamber Switching + requestBalChamberSwitching( TRUE ); + //Previous state setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve setValveState( D8_VALV, VALVE_STATE_CLOSED ); @@ -309,7 +349,14 @@ startHeater( D5_HEAT ); //Turn on Trimmer heater - setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + } + else + { + setHeaterTargetTemperature( D45_HEAT, getD99AverageTemperature() ); + } startHeater( D45_HEAT ); //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); @@ -333,6 +380,9 @@ break; case DD_GEND_SPENT_CHAMBER_FILL_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); + //Set valves and actuators setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO @@ -376,6 +426,9 @@ break; case DD_GEND_BICARB_CHAMBER_FILL_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); + requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); requestConcentratePumpOff( D76_PUMP, FALSE ); @@ -412,6 +465,8 @@ break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); @@ -453,6 +508,8 @@ break; case DD_GEND_ISOLATED_UF_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); //TODO : define actuators states break; @@ -605,6 +662,43 @@ /*********************************************************************//** * @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. @@ -638,9 +732,15 @@ 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 relationship seen against high dialysate flowrate Vs DeltaTemp @@ -653,13 +753,160 @@ 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. @@ -741,11 +988,6 @@ delayBypassStateFlag = FALSE; } } - else - { - //Execute balancing chamber - execBalancingChamberControl(); - } if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_SPENT_CHAMBER_H_FILL ) == TRUE ) { @@ -822,9 +1064,6 @@ #endif else { - //Execute balancing chamber - execBalancingChamberControl(); - //Execute ultrafiltration execUFControl(); } @@ -1214,8 +1453,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 @@ -1231,8 +1470,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