Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -rf3746f881341ba8bc8302cbba7d0e22e7b930d90 -rba7e088fc3308f844ea30376a78e1da6d32621c1 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision f3746f881341ba8bc8302cbba7d0e22e7b930d90) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision ba7e088fc3308f844ea30376a78e1da6d32621c1) @@ -58,12 +58,15 @@ #define D5_HEAT_TX_P_COEFFICIENT 0.034F ///< P Term for AC primary heater control during treatment mode. #define D5_HEAT_TX_I_COEFFICIENT 0.001F ///< I Term for AC primary heater control during treatment mode. -#define D45_HEAT_P_COEFFICIENT 0.01F ///< P Term for trimmer heater control. +#define D45_HEAT_P_COEFFICIENT 0.03F //0.01F ///< P Term for trimmer heater control. #define D45_HEAT_I_COEFFICIENT 0.0005F ///< 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.05F ///< P Term for trimmer heater control for higher dialysate flow rate. +#define D45_HEAT_HIGHER_QD_I_COEFFICIENT 0.015F ///< I Term for trimmer heater control for higher dialysate flow rate. +#define D45_HEAT_HIGH_DIAL_FLOW_RATE 200.0F ///< Decide Trimmer heater - high gain PI control based on the dialysate flow rate #define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. -#define HEATER_TEMP_CONTROL_TRANSFER 1.0F ///< Primary Heater temperature difference to switch to control function +#define HEATER_TEMP_CONTROL_TRANSFER 2.0F ///< Primary Heater temperature difference to switch to D28 outer loop control function #define HEATER_TARGET_TEMPERATURE_MIN 10.0F ///< Minimum allowed target temperature for the heaters. #define HEATER_TARGET_TEMPERATURE_MAX 90.0F ///< Maximum allowed target temperature for the heaters. #define DELTA_TEMP_ADJ_FLOW_RATE 150.0F ///< Fo Qd <= 150, the bottom range of second level temperature correction to be applied. @@ -95,8 +98,8 @@ #define RINSE_PUMP_EST_FLOWRATE 110 ///< Estimated rinse pump flow rate #define DATA_PUBLISH_COUNTER_START_COUNT 70 ///< Data publish counter start count. -#define D5_HEAT_OUT_TX_P_COEFFICIENT 0.5F ///< P Term for AC primary heater outer loop control during treatment mode. -#define D5_HEAT_OUT_TX_I_COEFFICIENT 0.40F ///< I Term for AC primary heater outer loop control during treatment mode. +#define D5_HEAT_OUT_TX_P_COEFFICIENT 2.00F //0.5F ///< P Term for AC primary heater outer loop control during treatment mode. +#define D5_HEAT_OUT_TX_I_COEFFICIENT 0.04F //0.08F //0.4F ///< I Term for AC primary heater outer loop control during treatment mode. #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. @@ -280,6 +283,10 @@ 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, TRUE, D45_HEAT_TX_INIT_FEED_FORWARD ); + // Initialize the trimmer heater PI controller for Higher dialysate flow rate + initializePIController( PI_CONTROLLER_ID_D45_HEAT_HIGHER_QD, HEATERS_MIN_DUTY_CYCLE, D45_HEAT_HIGHER_QD_P_COEFFICIENT, D45_HEAT_HIGHER_QD_I_COEFFICIENT, + HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE, TRUE, D45_HEAT_TX_INIT_FEED_FORWARD ); + #ifdef __HEATERS_DEBUG__ for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) { @@ -402,8 +409,11 @@ * @param heater: heater ID to update the heater control. * @return none *************************************************************************/ -void signalHeaterControlOnQDUpdate( void ) +void signalHeaterControlOnQDUpdate( F32 prevDialFlowrate ) { + F32 flowrate = getTDDialysateFlowrate(); + F32 dutyCycle = 0.0F; + // check heater state if ( HEATER_EXEC_STATE_CONTROL_TO_TARGET == heatersStatus[ D5_HEAT ].state ) { @@ -414,7 +424,24 @@ 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; + //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 + // as starting point. + if ( prevDuty > 0.0F ) + { + dutyCycle = prevDuty / ( prevDialFlowrate / flowrate ); + } + + if ( flowrate >= D45_HEAT_HIGH_DIAL_FLOW_RATE ) + { + resetPIController( PI_CONTROLLER_ID_D45_HEAT_HIGHER_QD, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + } + else + { + resetPIController( PI_CONTROLLER_ID_D45_HEAT, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + } } } @@ -475,9 +502,16 @@ F32 ctrl = 0.0F; F32 measuredTempAtDialyzer = 0.0F; F32 targetTempfromTD = 0.0F; + F32 diffTempC = 0.0F; if ( ++primaryTargetTempAdjCounter >= d5OuterLoopControlInterval ) { +#ifdef __USE_D1_TEMP_ + + // Use new RTD sensor placed closed to dialyzer, connected to D1 port + measuredTempAtDialyzer = getFilteredTemperatureValue( D1_TEMP ); + +#else if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) != TRUE ) { measuredTempAtDialyzer = getTeensyConductivityTemperatureValue( D27_COND ); @@ -486,17 +520,18 @@ { measuredTempAtDialyzer = getFilteredConductivitySensorTemperature( D27_COND ); } - +#endif calcTargetTemp = getHeaterTargetTemperature( D5_HEAT ); + diffTempC = fabs( calcTargetTemp - measuredTempAtDialyzer ); deltaTempC = targetTempfromTD - measuredTempAtDialyzer; - if ( FALSE == isTargetTempAdjusted ) + if ( ( FALSE == isTargetTempAdjusted ) && ( diffTempC <= HEATER_TEMP_CONTROL_TRANSFER ) ) { isTargetTempAdjusted = TRUE; adjustedPrimaryTargetTemp = calcTargetTemp; resetPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, calcTargetTemp, HEATERS_MIN_DUTY_CYCLE ); } - else if ( fabs(deltaTempC) >= D5_HEAT_OUT_DEADBAND_CONTROL ) + else if ( ( fabs(deltaTempC) >= D5_HEAT_OUT_DEADBAND_CONTROL ) && ( TRUE == isTargetTempAdjusted ) ) { ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT_OUTER_LOOP, getTDTargetDialysateTemperature(), measuredTempAtDialyzer ); adjustedPrimaryTargetTemp = ctrl; @@ -753,13 +788,22 @@ { F32 deltaTempC = targetTemperature - measuredTemperature; F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); - F32 flowrate = getTDDialysateFlowrate() / LITER_IN_ML ; - F32 dutyCycle = calculateDutyCycle( flowrate, capDeltaTempC, TRIMMER_HEATER_MAX_PWR_WATTS, DC_HEATER_EFFICIENCY, + F32 flowrate = getTDDialysateFlowrate(); + F32 flowrateInLtr = flowrate / LITER_IN_ML ; + F32 dutyCycle = calculateDutyCycle( flowrateInLtr, capDeltaTempC, TRIMMER_HEATER_MAX_PWR_WATTS, DC_HEATER_EFFICIENCY, HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE ); control[ heater ].data = dutyCycle; - resetPIController( PI_CONTROLLER_ID_D45_HEAT, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + if ( flowrate >= D45_HEAT_HIGH_DIAL_FLOW_RATE ) + { + resetPIController( PI_CONTROLLER_ID_D45_HEAT_HIGHER_QD, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + } + else + { + resetPIController( PI_CONTROLLER_ID_D45_HEAT, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + } + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; } else @@ -822,8 +866,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 >= 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. @@ -859,14 +903,30 @@ flowrate = getTDDialysateFlowrate() / LITER_IN_ML ; dutyCycle = calculateDutyCycle( flowrate, capDeltaTempC, TRIMMER_HEATER_MAX_PWR_WATTS, DC_HEATER_EFFICIENCY, HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE ); - //Update the calculated feed forward value - setPIControllerFeedForward( PI_CONTROLLER_ID_D45_HEAT, dutyCycle ); - if ( absDeltaTempC > D45_HEATER_DEADBAND_CONTROL ) + if ( flowrate >= D45_HEAT_HIGH_DIAL_FLOW_RATE ) { - ctrl = runPIController( PI_CONTROLLER_ID_D45_HEAT, targetTemperature, measuredTemperature ); - control[ heater ].data = ctrl; + //Update the calculated feed forward value + setPIControllerFeedForward( PI_CONTROLLER_ID_D45_HEAT_HIGHER_QD, dutyCycle ); + + if ( absDeltaTempC > D45_HEATER_DEADBAND_CONTROL ) + { + ctrl = runPIController( PI_CONTROLLER_ID_D45_HEAT_HIGHER_QD, targetTemperature, measuredTemperature ); + control[ heater ].data = ctrl; + } } + else + { + //Update the calculated feed forward value + setPIControllerFeedForward( PI_CONTROLLER_ID_D45_HEAT, dutyCycle ); + + if ( absDeltaTempC > D45_HEATER_DEADBAND_CONTROL ) + { + ctrl = runPIController( PI_CONTROLLER_ID_D45_HEAT, targetTemperature, measuredTemperature ); + control[ heater ].data = ctrl; + } + } + //#ifdef __HEATERS_DEBUG__ // U32 i; //