Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r51c295e1dc413d3774dae303e7f98b2f4c86bae4 -re803f3e6d135641015dc78e2aeac0a5489c9492c --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 51c295e1dc413d3774dae303e7f98b2f4c86bae4) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e803f3e6d135641015dc78e2aeac0a5489c9492c) @@ -51,7 +51,8 @@ #define HEATERS_DUTY_CYCLE_CONVERSION_FACTOR 100.0F ///< Heaters duty cycle 0: OFF, 100: 100% duty cycle. #define HEATERS_ZERO_EFFICIENCY 0.0F ///< Zero heater efficiency #define HEATER_CNTL_TRANSFER_DELTA_TEMP_C 0.50F ///< AC heater delta temperature to transfer control from open to close loop -#define MAX_ADJ_DELTA_TEMP_C 3.0F ///< Maximum adjusted delta temperature to add/remove from calculated target temperature +#define ADJ_DELTA_TEMP_STEP 2.0F ///< Adjust target temperature based on D28 feedback per cycle. +#define MAX_ADJ_DELTA_TEMP_C 7.0F ///< Maximum adjusted delta temperature to add/remove from calculated target temperature #define D5_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control //#define D5_HEAT_TX_P_COEFFICIENT 0.050F ///< P Term for AC primary heater control during treatment mode. @@ -68,6 +69,7 @@ #define HEATER_TEMP_CONTROL_TRANSFER 1.0F ///< Primary Heater temperature difference to switch to 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. #define D5_HEAT_ON_NO_FLUID_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Primary heater on with no flow time out in milliseconds. #define D45_HEAT_ON_NO_FLUID_TIMEOUT_MS ( 12 * MS_PER_SECOND ) ///< Trimmer heater on with no flow time out in milliseconds. @@ -81,7 +83,7 @@ #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 ( 10 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature +#define D5_TARGET_TEMP_ADJUST_INTERVAL_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature #define PRIMARY_HEATER_MAX_PWR_WATTS 1400.0F ///< AC Primary Heater Max Power consumeption in Watts #define TX_PRIMARY_HEATER_MAX_PWR_WATTS 700.0F ///< Estimated power to be supplied to the primary heater during treatement mode #define HEAT_PRIMARY_HEATER_MAX_PWR_WATTS 980.0F ///< Estimated power to be supplied to the primary heater during heat disinfect mode @@ -126,7 +128,8 @@ static U32 dataPublicationTimerCounter; ///< Data publication timer counter. static U32 primaryTargetTempAdjCounter; ///< Primary target temperature adjustment counter. static BOOL isTargetTempAdjusted; ///< Flag indicating that target temperature is adjusted -static U32 adjustedPrimaryTargetTemp; ///< Adjusted primary target temperature +static U32 adjustedPrimaryTargetTemp; ///< Adjusted primary target temperature +static BOOL isDialyzerTempFeedbackEnabled; ///< Flag indicating enable/disable the dilayser temp ( D28) based feedback adjustment static const F32 WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES = 4184.0F / (F32)SEC_PER_MIN; ///< Water specific heat in J/KgC / 60. static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval. static F32 convertDC; ///< AC Heater converted duty cycle @@ -197,6 +200,7 @@ primaryTargetTempAdjCounter = 0; adjustedPrimaryTargetTemp = 0.0F; isTargetTempAdjusted = FALSE; + isDialyzerTempFeedbackEnabled = TRUE; for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { @@ -335,6 +339,19 @@ /*********************************************************************//** * @brief + * The setD28TempFeedbackControl function enables/disables the D28 based + * heater control (outer control loop ). + * @details \b Inputs: none + * @details \b Outputs: setD28TempFeedbackControl + * @param enable: Enables/disables the D28 based heater control. + *************************************************************************/ +void setD28TempFeedbackControl( BOOL enable ) +{ + isDialyzerTempFeedbackEnabled = enable; +} + +/*********************************************************************//** + * @brief * The signalHeaterControlOnQDUpdate function updates heater control based on * the latest treatment paratmeter (Dialysate Flow rate) change * @details \b Inputs: heatersStatus @@ -385,21 +402,40 @@ F32 targetTempfromTD = getTDTargetDialysateTemperature(); F32 measuredTempAtDialyzer = getConductivityTemperatureValue( D27_COND ); F32 calcTargetTemp = getHeaterTargetTemperature( D5_HEAT ); + F32 dialysateFlowrate = getTDDialysateFlowrate(); F32 deltaTempC = targetTempfromTD - measuredTempAtDialyzer; - F32 capDeltaTempC = MIN( fabs(deltaTempC), MAX_ADJ_DELTA_TEMP_C ); + F32 capDeltaTempC = MIN( fabs(deltaTempC), ADJ_DELTA_TEMP_STEP ); + //Assign the initial calcualted temp for adjsutment + if ( FALSE == isTargetTempAdjusted ) + { + adjustedPrimaryTargetTemp = calcTargetTemp; + } + + //Keep adjusting the temperature based on D28 feedback if ( deltaTempC > HEATERS_ZERO_DELTA_TEMP_C ) { - adjustedPrimaryTargetTemp = calcTargetTemp + capDeltaTempC; + adjustedPrimaryTargetTemp = adjustedPrimaryTargetTemp + capDeltaTempC; } else { - adjustedPrimaryTargetTemp = calcTargetTemp - capDeltaTempC; + adjustedPrimaryTargetTemp = adjustedPrimaryTargetTemp - capDeltaTempC; } - adjustedPrimaryTargetTemp = MIN(adjustedPrimaryTargetTemp, ( calcTargetTemp + MAX_ADJ_DELTA_TEMP_C ) ); - adjustedPrimaryTargetTemp = MAX(adjustedPrimaryTargetTemp, ( calcTargetTemp - MAX_ADJ_DELTA_TEMP_C ) ); + //Make sure the adjusted temp not crossing the max and min limits. + adjustedPrimaryTargetTemp = MIN( adjustedPrimaryTargetTemp, ( calcTargetTemp + MAX_ADJ_DELTA_TEMP_C ) ); + // For Qd <= 150, The bottom range of second level temperature correction not to go below the initial + // Delta temperature adjustment. + if ( dialysateFlowrate > DELTA_TEMP_ADJ_FLOW_RATE ) + { + adjustedPrimaryTargetTemp = MAX( adjustedPrimaryTargetTemp, ( calcTargetTemp - MAX_ADJ_DELTA_TEMP_C ) ); + } + else + { + adjustedPrimaryTargetTemp = MAX( adjustedPrimaryTargetTemp, calcTargetTemp ); + } + isTargetTempAdjusted = TRUE; primaryTargetTempAdjCounter = 0; } @@ -719,7 +755,9 @@ { F32 deltaTempC = 0.0F; - if ( TRUE == isTargetTempAdjusted ) + // If D28 feedback control is enabled and adjusted temp calculation is done + // then update the target temperature. + if ( ( TRUE == isTargetTempAdjusted ) && ( TRUE == isDialyzerTempFeedbackEnabled ) ) { targetTemperature = adjustedPrimaryTargetTemp; }