Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -rc90f3d61bde2a2b47d1048635be4dadf282e2195 -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision c90f3d61bde2a2b47d1048635be4dadf282e2195) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -60,7 +60,7 @@ #define D48_SPEED_RANGE_LIMIT 0.25F ///< D48 speed adjustment range check limit ( D48 speed can vary +/-25% of initial calculated speed) #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 2.5 ///< Balancing Chamber fill timeout factor (150% of observed fill count) +#define BAL_CHAMBER_FILL_TIMEOUT_FACTOR 2.5F ///< Balancing Chamber fill timeout factor (150% of observed fill count) /// Payload record structure for balancing chamber switch only request typedef struct Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -rbfd1ad206360b585a01b75ce2310bfba3ffd9e1f -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision bfd1ad206360b585a01b75ce2310bfba3ffd9e1f) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -59,7 +59,7 @@ #define D5_HEAT_TX_I_COEFFICIENT 0.001F ///< I Term for AC primary heater control during treatment mode. #define D45_HEAT_P_COEFFICIENT 0.05F //0.01F ///< P Term for trimmer heater control. -#define D45_HEAT_I_COEFFICIENT 0.0025F ///< I Term for trimmer heater control. +#define D45_HEAT_I_COEFFICIENT 0.0010F ///< I Term for trimmer heater control. #define D45_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control #define D45_HEAT_HIGHER_QD_P_COEFFICIENT 0.2F ///< P Term for trimmer heater control for higher dialysate flow rate. #define D45_HEAT_HIGHER_QD_I_COEFFICIENT 0.05F ///< I Term for trimmer heater control for higher dialysate flow rate. @@ -103,8 +103,12 @@ #define D5_HEAT_OUT_TX_I_COEFFICIENT 0.4F ///< I Term for AC primary heater outer loop control during treatment mode. #else #define D5_HEAT_OUT_TX_P_COEFFICIENT 0.75F //2.00F //0.5F ///< P Term for AC primary heater outer loop control during treatment mode. -#define D5_HEAT_OUT_TX_I_COEFFICIENT 0.1F //0.04F //0.08F //0.4F ///< I Term for AC primary heater outer loop control during treatment mode. +#define D5_HEAT_OUT_TX_I_COEFFICIENT 0.15F //0.04F //0.08F //0.4F ///< I Term for AC primary heater outer loop control during treatment mode. #endif +#define D5_HEAT_OUT_LOWQD_TX_P_COEFFICIENT 0.3F ///< P Term for AC primary heater outer loop - low Qd(<200) control during treatment mode. +#define D5_HEAT_OUT_LOWQD_TX_I_COEFFICIENT 0.1F ///< I Term for AC primary heater outer loop - low Qd(<200) control during treatment mode. +#define D5_HEAT_HIGH_DIAL_FLOW_RATE 200.0F ///< Decide Primary heater outer loop - PI control based on the dialysate flow rate + #define D5_HEAT_OUT_MIN_DELTA_TEMP 0.0F ///< Minimum Delta temperature that can be adjusted for D5 control #define D5_HEAT_OUT_MAX_DELTA_TEMP 50.0 ///< Maximum Delta temperature that can be adjusted for D5 control #define D5_HEAT_OUT_DEADBAND_CONTROL 0.1F ///< Heater outer loop dead band range for control. @@ -137,6 +141,9 @@ #define BETA2_0_B3_HEAT_DIS_FOURTH_COEFF 0.0092543272727F ///< Fourth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. #define BETA2_0_B3_HEAT_DIS_FIFTH_COEFF 1.079412363636F ///< Fifth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define BETA2_0_B_HEAT_DIS_FIRST_COEFF 0.38F ///< First coefficient for Heat loss dissipation calculation from D4 to D113 (natural logarthmic equation). +#define BETA2_0_B_HEAT_DIS_SEC_COEFF 2.72F ///< Second coefficient for Heat loss dissipation calculation from D4 to D113. + //static const F32 HEATERS_VOLTAGE_TOLERANCE_V = HEATERS_MAX_OPERATING_VOLTAGE_V * HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL; ///< Heaters voltage tolerance in volts. /// Heaters data structure @@ -197,6 +204,7 @@ static F32 calculateBeta2HeatDissipationB3( void ); static F32 calculateHeatDissipationB1andB2( void ); static F32 calculateHeatDissipationB3( void ); +static F32 calculateHeatDissipationB( void ); static F32 calculateInitialTemp( F32 targetTemp, F32 heatDissipation ); static F32 calculateDutyCycle( F32 flowrate, F32 deltaTemp, F32 power, F32 efficiency, F32 min, F32 max ); @@ -281,9 +289,14 @@ initializePIController( PI_CONTROLLER_ID_D5_HEAT, HEATERS_MIN_DUTY_CYCLE, D5_HEAT_TX_P_COEFFICIENT, D5_HEAT_TX_I_COEFFICIENT, HEATERS_MIN_DUTY_CYCLE, AC_HEATER_TX_MAX_DUTY_CYCLE, TRUE, D5_HEAT_TX_INIT_FEED_FORWARD ); - initializePIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, D5_HEAT_OUT_MIN_DELTA_TEMP, D5_HEAT_OUT_TX_P_COEFFICIENT, D5_HEAT_OUT_TX_I_COEFFICIENT, + // Outerloop control for high Qd (>200) + initializePIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_HIGHER_QD, D5_HEAT_OUT_MIN_DELTA_TEMP, D5_HEAT_OUT_TX_P_COEFFICIENT, D5_HEAT_OUT_TX_I_COEFFICIENT, D5_HEAT_OUT_MIN_DELTA_TEMP, D5_HEAT_OUT_MAX_DELTA_TEMP, FALSE, D5_HEAT_TX_INIT_FEED_FORWARD ); + // Outerloop control for Low Qd ( <200) + initializePIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, D5_HEAT_OUT_MIN_DELTA_TEMP, D5_HEAT_OUT_LOWQD_TX_P_COEFFICIENT, D5_HEAT_OUT_LOWQD_TX_I_COEFFICIENT, + D5_HEAT_OUT_MIN_DELTA_TEMP, D5_HEAT_OUT_MAX_DELTA_TEMP, FALSE, D5_HEAT_TX_INIT_FEED_FORWARD ); + // Initialize the trimmer heater PI controller initializePIController( PI_CONTROLLER_ID_D45_HEAT, HEATERS_MIN_DUTY_CYCLE, D45_HEAT_P_COEFFICIENT, D45_HEAT_I_COEFFICIENT, HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE, FALSE, D45_HEAT_TX_INIT_FEED_FORWARD ); @@ -424,12 +437,13 @@ { // Reset the adjusted temperature target isTargetTempAdjusted = FALSE; + // start outer loop control immediately upon changing Qd + flowrate = getTDDialysateFlowrate(); + primaryTargetTempAdjCounter = ( flowrate >= D5_HEAT_HIGH_DIAL_FLOW_RATE ? D5_TARGET_TEMP_ADJUST_HIGH_QD_INTERVAL : D5_TARGET_TEMP_ADJUST_LOW_QD_INTERVAL ); } if ( HEATER_EXEC_STATE_CONTROL_TO_TARGET == heatersStatus[ D45_HEAT ].state ) { - //Change back to ramp state to reset the controller - //heatersStatus[ D45_HEAT ].state = HEATER_EXEC_STATE_RAMP_TO_TARGET; F32 prevDuty = getHeaterControl( D45_HEAT ); // When Qd change happens, use previous PWM to calculate the new PWM @@ -467,7 +481,7 @@ F32 targetTemp = getTDTargetDialysateTemperature(); F32 targetTempAtD28 = 0.0F; F32 targetTempAtD4 = 0.0F; - +#ifndef __USE_D1_TEMP_ // 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. @@ -488,6 +502,14 @@ targetTempAtD28 = calculateInitialTemp( targetTemp, heatDissipation_b3 ); // calculation of target temp at D4 to get the target temp at D28 level targetTempAtD4 = calculateInitialTemp( targetTempAtD28, heatDissipation_b1b2 ); +#else + // heat loss model based on the temp sensor (D113) closely located to dialyzer. + // Find the difference in temperature between dialyzer temperature(D113) and + // D4 temperature and that is considered as heat loss factor(B). + heatDissipation_b1b2 = calculateHeatDissipationB(); + // calculation of target temp at D4 to get the target temp at D113 level + targetTempAtD4 = calculateInitialTemp( targetTemp, heatDissipation_b1b2 ); +#endif //Update target temperature setTargetHydChamberTemp( targetTempAtD4 ); } @@ -506,8 +528,8 @@ F32 deltaTempC = 0.0F; F32 ctrl = 0.0F; F32 measuredTempAtDialyzer = 0.0F; - F32 targetTempfromTD = 0.0F; - F32 diffTempC = 0.0F; + F32 flowrate = getTDDialysateFlowrate(); + F32 targetTempfromTD = getTDTargetDialysateTemperature(); if ( ++primaryTargetTempAdjCounter >= d5OuterLoopControlInterval ) { @@ -527,18 +549,32 @@ } #endif calcTargetTemp = getHeaterTargetTemperature( D5_HEAT ); - diffTempC = fabs( calcTargetTemp - measuredTempAtDialyzer ); - deltaTempC = targetTempfromTD - measuredTempAtDialyzer; + deltaTempC = fabs( targetTempfromTD - measuredTempAtDialyzer ); - if ( ( FALSE == isTargetTempAdjusted ) && ( diffTempC <= HEATER_TEMP_CONTROL_TRANSFER ) ) + if ( ( FALSE == isTargetTempAdjusted ) && ( deltaTempC <= HEATER_TEMP_CONTROL_TRANSFER ) ) { isTargetTempAdjusted = TRUE; adjustedPrimaryTargetTemp = calcTargetTemp; - resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, calcTargetTemp, HEATERS_MIN_DUTY_CYCLE ); + + if ( flowrate >= D5_HEAT_HIGH_DIAL_FLOW_RATE ) + { + resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_HIGHER_QD, calcTargetTemp, HEATERS_MIN_DUTY_CYCLE ); + } + else + { + resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, calcTargetTemp, HEATERS_MIN_DUTY_CYCLE ); + } } - else if ( ( fabs(deltaTempC) >= D5_HEAT_OUT_DEADBAND_CONTROL ) && ( TRUE == isTargetTempAdjusted ) ) + else if ( ( deltaTempC >= D5_HEAT_OUT_DEADBAND_CONTROL ) && ( TRUE == isTargetTempAdjusted ) ) { - ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, getTDTargetDialysateTemperature(), measuredTempAtDialyzer ); + if ( flowrate >= D5_HEAT_HIGH_DIAL_FLOW_RATE ) + { + ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_HIGHER_QD, getTDTargetDialysateTemperature(), measuredTempAtDialyzer ); + } + else + { + ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, getTDTargetDialysateTemperature(), measuredTempAtDialyzer ); + } adjustedPrimaryTargetTemp = ctrl; } @@ -769,6 +805,7 @@ // Reset PI Controllers resetPIController( PI_CONTROLLER_ID_D5_HEAT, HEATERS_MIN_DUTY_CYCLE, feedforward ); resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, targetTemperature, HEATERS_MIN_DUTY_CYCLE ); + resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_HIGHER_QD, targetTemperature, HEATERS_MIN_DUTY_CYCLE ); // Transfer Control to target when delta temp is minimal. state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; @@ -870,8 +907,8 @@ setPIControllerFeedForward( PI_CONTROLLER_ID_D5_HEAT, d5FeedForward ); // decide outer loop control interval based on the Qd - //flowrate = getTDDialysateFlowrate(); - //d5OuterLoopControlInterval = ( flowrate >= HIGH_DIAL_FLOW_RATE ? D5_TARGET_TEMP_ADJUST_HIGH_QD_INTERVAL : D5_TARGET_TEMP_ADJUST_LOW_QD_INTERVAL ); + flowrate = getTDDialysateFlowrate(); + d5OuterLoopControlInterval = ( flowrate >= D5_HEAT_HIGH_DIAL_FLOW_RATE ? D5_TARGET_TEMP_ADJUST_HIGH_QD_INTERVAL : D5_TARGET_TEMP_ADJUST_LOW_QD_INTERVAL ); // If D28 feedback control is enabled and adjusted temp calculation is done // then update the target temperature. @@ -1022,7 +1059,7 @@ * @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. + * the P&ID flow path for Beta2.0 hardware. * @details \b Inputs: Qd. * @details \b Outputs: none * @return the calculated heat dissipation constants. @@ -1047,7 +1084,7 @@ * @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. + * the P&ID flow path for Beta2.0 hardware. * @details \b Inputs: Qd. * @details \b Outputs: none * @return the calculated heat dissipation constant. @@ -1072,7 +1109,7 @@ * @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. + * the P&ID flow path. * @details \b Inputs: Qd. * @details \b Outputs: none * @return the calculated heat dissipation constants. @@ -1096,7 +1133,7 @@ * @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. + * the P&ID flow path. * @details \b Inputs: Qd. * @details \b Outputs: none * @return the calculated heat dissipation constant. @@ -1118,6 +1155,29 @@ /*********************************************************************//** * @brief + * The calculateHeatDissipationB function calculates the heat dissipation + * constants called B that describes the heat loss between D4 to (D113)dialyzer in + * the P&ID flow path. + * @details \b Inputs: Qd. + * @details \b Outputs: none + * @return the calculated heat dissipation constant. + *************************************************************************/ +static F32 calculateHeatDissipationB( void ) +{ + // Get the dialysate flow rate from TD + F32 b = 0.0F; + F32 qd = getTDDialysateFlowrate(); + F32 logQd = logf(qd); // natural logarthemic + F32 firstPart = BETA2_0_B_HEAT_DIS_FIRST_COEFF * logQd; + + // B = 0.38*LN(qd)-2.72 + b = firstPart - BETA2_0_B_HEAT_DIS_SEC_COEFF; + + return b; +} + +/*********************************************************************//** + * @brief * The calculateInitialTemp function calculates the initial temperature * required to get the target temperature considering heat loss. * @details \b Inputs: ambient temperature Index: firmware/App/DDCommon.h =================================================================== diff -u -r96a8221c98260150306117d81107ac28c426857e -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 96a8221c98260150306117d81107ac28c426857e) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -52,7 +52,7 @@ #define __HEATERS_DEBUG__ 1 //Uncomment below if D1 placement is used for Temp control at dialyzer -//#define __USE_D1_TEMP_ 1 +#define __USE_D1_TEMP_ 1 // comment below to disable bicarb multi level sensor for time based chamber F fill #define CONDUCTIVE_LEVEL_SENSOR_ENABLED 1 Index: firmware/App/Drivers/TemperatureSensors.c =================================================================== diff -u -r94789b2f2324d5901685b6ff7b6224d4af3a0276 -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 94789b2f2324d5901685b6ff7b6224d4af3a0276) +++ firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -141,7 +141,7 @@ tempSensors[ BRD_TEMP ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // TODO : for testing, fix the ambient temperature as 35DegC. - temperatureValue[ BRD_TEMP ].data = 35.0F; + temperatureValue[ BRD_TEMP ].data = 34.5F; // Persistent alarm for the temperature sensors range check initPersistentAlarm( ALARM_ID_DD_TEMPERATURE_SENSOR_OUT_OF_RANGE, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS ); Index: firmware/App/Monitors/Level.c =================================================================== diff -u -r2d295ca85f19e95da42476a57ca6b4496baf980a -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/Monitors/Level.c (.../Level.c) (revision 2d295ca85f19e95da42476a57ca6b4496baf980a) +++ firmware/App/Monitors/Level.c (.../Level.c) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -541,10 +541,10 @@ { DD_LEVEL_DATA_T data; - data.d6Level = (U32)getFloaterStatus( D6_LEVL ); data.d46Level = (U32)getLevelStatus( D46_LEVL ); data.d63Level = (U32)getLevelStatus( D63_LEVL ); data.d98Level = (U32)getLevelStatus( D98_LEVL ); + data.d6Level = (U32)getFloaterStatus( D6_LEVL ); data.bicarbLevel = (U32)getBicarbChamberLevelStatus(); levelsDataPublicationCounter = 0; Index: firmware/App/Monitors/Level.h =================================================================== diff -u -r2d295ca85f19e95da42476a57ca6b4496baf980a -r1eb7496d07548ac5fb33e1051542f42cd5ff529c --- firmware/App/Monitors/Level.h (.../Level.h) (revision 2d295ca85f19e95da42476a57ca6b4496baf980a) +++ firmware/App/Monitors/Level.h (.../Level.h) (revision 1eb7496d07548ac5fb33e1051542f42cd5ff529c) @@ -69,10 +69,10 @@ /// DD floater and level sensor data publish structure typedef struct { - U32 d6Level; ///< Floater level U32 d46Level; ///< Spent dialysate level U32 d63Level; ///< Bicarb lower level U32 d98Level; ///< Bicarb upper level + U32 d6Level; ///< Floater level U32 bicarbLevel; ///< Bicarb chamber level combination ( D63 + D98 ) } DD_LEVEL_DATA_T;