Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r2610908e6147de229a37df3ec7d000e2ea5917e0 -r4541d91cb4324d3d5e1aa4104ebcd9eb14c904f6 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 2610908e6147de229a37df3ec7d000e2ea5917e0) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 4541d91cb4324d3d5e1aa4104ebcd9eb14c904f6) @@ -82,9 +82,10 @@ #define D5_HEAT_CONTROL_INTERVAL_COUNT ( D5_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Primary heater control interval count. #define D45_HEAT_CONTROL_INTERVAL_MS ( 1 * MS_PER_SECOND ) ///< Trimmer heater control interval in milli seconds #define D45_HEAT_CONTROL_INTERVAL_COUNT ( D45_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Trimmer heater control interval count. -#define D5_TARGET_TEMP_ADJUST_INTERVAL_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature +#define D5_TARGET_TEMP_ADJUST_LOW_QD_INTERVAL ( 3 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature - outer loop control interval for low Qd. +#define D5_TARGET_TEMP_ADJUST_HIGH_QD_INTERVAL ( 1 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature - outer loop control interval for high Qd. #define PRIMARY_HEATER_MAX_PWR_WATTS 1400.0F ///< AC Primary Heater Max Power consumption in Watts -#define TX_PRIMARY_HEATER_MAX_PWR_WATTS 700.0F ///< Estimated power to be supplied to the primary heater during treatement mode +#define TX_PRIMARY_HEATER_MAX_PWR_WATTS 700.0F ///< Estimated power to be supplied to the primary heater during treatment mode #define HEAT_PRIMARY_HEATER_MAX_PWR_WATTS 980.0F ///< Estimated power to be supplied to the primary heater during heat disinfect mode #define MAX_INLET_FLOW_LPM ( 600.0F / 1000.0F ) ///< Maximum inlet flow to hydraulics chamber from FP #define LITER_IN_ML 1000.0F ///< Liter in milliliter units @@ -107,6 +108,7 @@ #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. +#define HIGH_DIAL_FLOW_RATE 300.0F ///< Decide outer loop heater control based on the dialysate flow rate //static const F32 HEATERS_VOLTAGE_TOLERANCE_V = HEATERS_MAX_OPERATING_VOLTAGE_V * HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL; ///< Heaters voltage tolerance in volts. @@ -153,6 +155,7 @@ static F32 capAdjustD5PWM; ///< AC heater PWM adjustment after range check static F32 lastDialTargetTemperatureSet[ NUM_OF_DD_HEATERS ]; ///< last dialysate target temperature set for heater control static F32 d5FeedForward; ///< AC heater feed forward calculated value +static U32 d5OuterLoopControlInterval; ///< AC heater outer loop control valve //For testing #ifdef __HEATERS_DEBUG__ @@ -210,6 +213,7 @@ convertDC = 0.0F; controlInterval[ D5_HEAT ] = D5_HEAT_CONTROL_INTERVAL_COUNT; controlInterval[ D45_HEAT ] = D45_HEAT_CONTROL_INTERVAL_COUNT; + d5OuterLoopControlInterval = D5_TARGET_TEMP_ADJUST_HIGH_QD_INTERVAL; // Assign counter close to the target period heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; @@ -419,7 +423,7 @@ *************************************************************************/ static void updatePrimaryHeaterTargetTemp( void ) { - if ( ++primaryTargetTempAdjCounter >= D5_TARGET_TEMP_ADJUST_INTERVAL_MS ) + if ( ++primaryTargetTempAdjCounter >= d5OuterLoopControlInterval ) { F32 targetTempfromTD = getTDTargetDialysateTemperature(); #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ @@ -794,12 +798,14 @@ F32 flowrate = ( getTDDialysateFlowrate() + RINSE_PUMP_EST_FLOWRATE ) / LITER_IN_ML ; d5FeedForward = calculateDutyCycle( flowrate, capDeltaTempC, PRIMARY_HEATER_MAX_PWR_WATTS, d5Efficiency, HEATERS_MIN_DUTY_CYCLE, AC_HEATER_TX_MAX_DUTY_CYCLE ); -#if 1 + //Update the calculated feed forward value setPIControllerFeedForward( PI_CONTROLLER_ID_D5_HEAT, d5FeedForward ); -#else - d5_p_gain = ( D5_HEATER_PWM_ADJ_SLOPE_FACTOR * getTDDialysateFlowrate() ) + D5_HEATER_PWM_INTERCEPT_FACTOR; -#endif + + // 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 ); + // If D28 feedback control is enabled and adjusted temp calculation is done // then update the target temperature. if ( ( TRUE == isTargetTempAdjusted ) && ( TRUE == isDialyzerTempFeedbackEnabled ) ) @@ -819,21 +825,8 @@ measuredTemperature = getD4AverageTemperature(); deltaTempC = targetTemperature - measuredTemperature; capDeltaTempC = fabs(deltaTempC); + d5_p_gain = ( D5_HEATER_PWM_ADJ_SLOPE_FACTOR * getTDDialysateFlowrate() ) + D5_HEATER_PWM_INTERCEPT_FACTOR; -// // Adjusted efficiency used for next feed forward control -// if ( capDeltaTempC >= D5_HEATER_DEADBAND_CONTROL ) -// { -// if ( deltaTempC > NEARLY_ZERO ) -// { -// d5_eff = d5Efficiency - ( capDeltaTempC * AC_HEATER_EFFICIENCY_ADJ ); -// } -// else -// { -// d5_eff = d5Efficiency + ( capDeltaTempC * AC_HEATER_EFFICIENCY_ADJ ); -// } -// //Range check -// d5Efficiency = RANGE( d5_eff, AC_HEAT_EFFICIENCY_LOW, AC_HEAT_EFFICIENCY_HIGH ); -// } if ( d5FeedForward > NEARLY_ZERO ) { if ( capDeltaTempC >= D5_HEATER_DEADBAND_CONTROL ) @@ -1061,13 +1054,10 @@ data.d45_HeaterTargetTemp = getHeaterTargetTemperature( D45_HEAT ); data.d5_HeaterState = heatersStatus[ D5_HEAT ].state; data.d45_HeaterState = heatersStatus[ D45_HEAT ].state; - //data.d5_dutyCycleCnt = convertDC; + data.d5_feedforward = d5FeedForward * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR; data.d5_PWMPeriod = getHeaterPWMPeriod( D5_HEAT ); - data.d5_dutyCycleCnt = d5FeedForward * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR; - //data.d5_PWMPeriod = capAdjustD5PWM * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR; data.d5_adjsutedTargetTemp = adjustedPrimaryTargetTemp; data.d5_targetTempFromTD = getTDTargetDialysateTemperature(); - data.d5_efficiency = d5Efficiency; #ifdef __HEATERS_DEBUG__ data.dbg1 = pIControlSignal[ 0 ]; data.dbg2 = pIControlSignal[ 1 ]; Index: firmware/App/Controllers/Heaters.h =================================================================== diff -u -r3ebcff44116a7853d2011c7b2f1eb38c1f37ba2a -r4541d91cb4324d3d5e1aa4104ebcd9eb14c904f6 --- firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision 3ebcff44116a7853d2011c7b2f1eb38c1f37ba2a) +++ firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision 4541d91cb4324d3d5e1aa4104ebcd9eb14c904f6) @@ -52,11 +52,10 @@ F32 d45_HeaterTargetTemp; ///< Trimmer heater target temperature U32 d5_HeaterState; ///< Primary heater state U32 d45_HeaterState; ///< Trimmer heater state - F32 d5_dutyCycleCnt; ///< Primary heater duty cycle in counts + F32 d5_feedforward; ///< Primary heater duty cycle in counts F32 d5_PWMPeriod; ///< Primary heater PWM period F32 d5_adjsutedTargetTemp; ///< Primary heater adjsuted target temperature F32 d5_targetTempFromTD; ///< User set target temperature - F32 d5_efficiency; ///< AC Heater efficiency #ifdef __HEATERS_DEBUG__ F32 dbg1; F32 dbg2;