Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -ra06e2c94a2c49609972b28f7ccd0647baabdb9b1 -r037f0edb0b880130563058c809ba50308f2a63e9 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision a06e2c94a2c49609972b28f7ccd0647baabdb9b1) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 037f0edb0b880130563058c809ba50308f2a63e9) @@ -39,12 +39,22 @@ // ********** private definitions ********** +#ifndef V_2_SYSTEM +#define MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE 1.00 ///< Main primary heater (heater A) max duty cycle (100%). +#define SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE 1.00 ///< Small Primary heater (heater B) max duty cycle (100%). +#define TRIMMER_HEATER_MAX_DUTY_CYCLE 1.00 ///< Trimmer heater max duty cycle (100%). +#else #define MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE 0.89 ///< Main primary heater (heater A) max duty cycle (89%). #define SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE 0.50 ///< Small Primary heater (heater B) max duty cycle (50%). #define TRIMMER_HEATER_MAX_DUTY_CYCLE 0.50 ///< Trimmer heater max duty cycle (50%). +#endif #define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters minimum duty cycle (0.00%). +#define PRIMARY_HEATERS_CUMULATIVE_DUTY_CYCLE ( MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE + \ + SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE ) ///< Primary heaters cumulative duty cycle. +#define PRIMARY_HEATER_INITIAL_DUTY_CYCLE_ESTIMATE_DIVISOR 2.0 ///< Primary heaters initial duty cycle estimation divisor. +#define MAIN_AND_SMALL_PRIMARY_HEATER_DUTY_CYCLE_DIVISOR 2.0 ///< Main and small primary heater duty cycle divisor -#define PRIMARY_HEATERS_P_COEFFICIENT 0.02 ///< Primary heaters proportional coefficient. +#define PRIMARY_HEATERS_P_COEFFICIENT 0.15 ///< Primary heaters proportional coefficient. #define PRIMARY_HEATERS_I_COEFFICIENT 0.001 ///< Primary heaters integral coefficient. #define TRIMMER_HEATER_P_COEFFICIENT 0.02 ///< Trimmer heater proportional coefficient. @@ -55,29 +65,14 @@ #define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. -#define SMALL_PRIMARY_AND_TRIMMER_HEATERS_POST_TARGET_TEMPERATURE 40U ///< Small primary and trimmer heaters target temperature during POST. -#define MAIN_PRIMARY_HEATER_POST_TARGET_TEMPERATURE 35U ///< Main primary heater target temperature during POST. -#define HEATERS_POST_HEAT_UP_TIME_SECONDS 50U ///< The time that the heaters are heated up to reach to the target temperature during POST. -#define HEATERS_POST_TEMPERATURE_TOLERANCE 1U ///< Tolerance of the sensors to the target temperature during POST. +#define MINIMUM_TARGET_TEMPERATURE 10.0 ///< Minimum allowed target temperature for the heaters. +#define MAXIMUM_TARGET_TEMPERATURE 90.0 ///< Maximum allowed target temperature for the heaters. -#define MINIMUM_TARGET_TEMPERATURE 10U ///< Minimum allowed target temperature for the heaters. -#define MAXIMUM_TARGET_TEMPERATURE 90U ///< Maximum allowed target temperature for the heaters. - #define HEATERS_ON_WITH_NO_FLOW_TIMEOUT_COUNT ( ( 3 * MS_PER_SECOND ) / TASK_PRIORITY_INTERVAL ) ///< Heaters are on but there is no sufficient flow timeout in counts. -#define HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C 120.0 ///< Heaters max allowed internal temperature in degrees C. TODO figure out the max temperature value +#define HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C 190.0 ///< Heaters max allowed internal temperature in degrees C. TODO figure out the max temperature value #define HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heaters max allowed internal temperature timeout in milliseconds. #define HEATERS_ON_NO_FLOW_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heaters on with no flow time out in milliseconds. -/// Heaters self-test enums -typedef enum heaters_self_test_states -{ - HEATERS_SELF_TEST_START = 0, ///< Heaters self-test start state - HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS, ///< Heaters self-test small primary and trimmer heaters state - HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER, ///< Heaters self-test start main primary state - HEATERS_SELF_TEST_COMPLETE, ///< Heaters self-test complete state - NUM_OF_HEATERS_SELF_TEST_STATES ///< Number of heaters self-test states -} HEATERS_SELF_TEST_STATES_T ; - /// Primary heaters exec states typedef enum primary_heaters_exec_states { @@ -104,8 +99,6 @@ // ********** private data ********** -static SELF_TEST_STATUS_T heatersSelfTestResult; ///< Heaters self-test results. -static HEATERS_SELF_TEST_STATES_T heatersSelfTestState; ///< Heaters self-test state. static PRIMARY_HEATERS_EXEC_STATES_T primaryHeatersExecState; ///< Primary heaters exec state. static TRIMMER_HEATER_EXEC_STATES_T trimmerHeaterExecState; ///< Trimmer heater exec state. @@ -123,27 +116,19 @@ static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval. -static U32 selfTestElapsedTime; ///< Self-test elapsed time variable. static BOOL hasStartPrimaryHeaterRequested; ///< Start primary heater request flag. static BOOL hasStartTrimmerHeaterRequested; ///< Start trimmer heater request flag. static U32 heatersOnWithNoFlowTimer; ///< Heaters are on but there is no sufficient flow. static TEMPERATURE_SENSORS_T primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_PRIMARY_HEATER; ///< Primary heaters feedback temperature sensors. -static TEMPERATURE_SENSORS_T trimmerHeaterFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; ///< Trimmer heater feedback temperature sensors. - -#ifndef IGNORE_HEATERS_MONITOR +static TEMPERATURE_SENSORS_T trimmerHeaterFeedbackTempSensor = TEMPSENSORS_INLET_DIALYSATE; ///< Trimmer heater feedback temperature sensors. static U32 primaryHeatersInternalTempOutTimer = 0; ///< Primary heaters internal temperature out of range timer. static U32 trimmerHeaterInternalTempOutTimer = 0; ///< Trimmer heater internal temperature out of range timer. static BOOL isPrimaryHeatersTempOutOfRange = FALSE; ///< Boolean flag to indicate if the primary heaters internal temperature out of range. static BOOL isTrimmerHeaterTempOutOfRange = FALSE; ///< Boolean flag to indicate if the trimmer heater internal temperature out of range. -#endif static BOOL isFlowBelowMin = FALSE; ///< Boolean flag to indicate if the flow is below the minimum. // ********** private function prototypes ********** -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestStart( void ); -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters( void ); -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestMainPrimaryHeater( void ); - static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateOff( void ); static PRIMARY_HEATERS_EXEC_STATES_T handlePrimaryHeaterStateControlToTarget( void ); @@ -167,7 +152,6 @@ *************************************************************************/ void initHeaters( void ) { - heatersSelfTestState = HEATERS_SELF_TEST_START; primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; primaryHeaterTargetTemperature = 0.0; @@ -177,21 +161,17 @@ dataPublicationTimerCounter = 0; isPrimaryHeaterOn = FALSE; isTrimmerHeaterOn = FALSE; - selfTestElapsedTime = 0; primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_PRIMARY_HEATER; - trimmerHeaterFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; - -#ifndef IGNORE_HEATERS_MONITOR + trimmerHeaterFeedbackTempSensor = TEMPSENSORS_INLET_DIALYSATE; primaryHeatersInternalTempOutTimer = 0; trimmerHeaterInternalTempOutTimer = 0; isPrimaryHeatersTempOutOfRange = FALSE; isTrimmerHeaterTempOutOfRange = FALSE; -#endif isFlowBelowMin = FALSE; // Initialize the PI controller for the primary heaters initializePIController( PI_CONTROLLER_ID_PRIMARY_HEATER, HEATERS_MIN_DUTY_CYCLE, PRIMARY_HEATERS_P_COEFFICIENT, PRIMARY_HEATERS_I_COEFFICIENT, - HEATERS_MIN_DUTY_CYCLE, MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE + SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE ); + HEATERS_MIN_DUTY_CYCLE, PRIMARY_HEATERS_CUMULATIVE_DUTY_CYCLE ); // Initialize the PI controller for the trimmer heater initializePIController( PI_CONTROLLER_ID_TRIMMER_HEATER, HEATERS_MIN_DUTY_CYCLE, TRIMMER_HEATER_P_COEFFICIENT, @@ -253,9 +233,7 @@ if ( ( primaryHeaterTargetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( primaryHeaterTargetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { -//#ifndef DISABLE_HEATERS_AND_TEMPS hasStartPrimaryHeaterRequested = TRUE; -//#endif status = TRUE; } @@ -276,9 +254,7 @@ if ( ( trimmerHeaterTargetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( trimmerHeaterTargetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { -#ifndef DISABLE_HEATERS_AND_TEMPS hasStartTrimmerHeaterRequested = TRUE; -#endif status = TRUE; } @@ -406,22 +382,32 @@ #endif /* - * If any of the heaters are on, check if the flow is below than the minimum value + * If any of the heaters are on or any of the heaters' PWMs are not zero, check if the flow is below than the minimum value * If the flow is below minimum for the first time, set the variables * If the flow is below minimum for more than the defined time, stop the heaters and raise the alarm * If the flow is in range, reset the variables + * This is to make sure that any of the heaters do not stay on while there is no flow + * In the monitor, trimmer heater is only monitored if heat disinfect mode is active. Trimmer heater is usually + * controlled by HD so checking the DG flow rate to decide whether it should be on or off is not appropriate */ - if ( ( TRUE == isPrimaryHeaterOn ) || ( TRUE == isTrimmerHeaterOn ) ) + BOOL isModeHeat = ( DG_MODE_HEAT == getCurrentOperationMode() ) && ( TRUE == isTrimmerHeaterOn ); + BOOL isHeaterOn = ( TRUE == isPrimaryHeaterOn ) || ( TRUE == isModeHeat ); + BOOL isPWMNonZero = ( mainPrimaryHeaterDutyCycle > HEATERS_MIN_DUTY_CYCLE ) || ( smallPrimaryHeaterDutyCycle > HEATERS_MIN_DUTY_CYCLE ) || + ( trimmerHeaterDutyCycle > HEATERS_MIN_DUTY_CYCLE ); + + if ( ( TRUE == isHeaterOn ) || ( TRUE == isPWMNonZero ) ) { F32 measuredFlow = getMeasuredROFlowRate(); if ( measuredFlow < MIN_RO_FLOWRATE_LPM ) { + // Flow is below minimum for the first time if ( FALSE == isFlowBelowMin ) { isFlowBelowMin = TRUE; heatersOnWithNoFlowTimer = getMSTimerCount(); } + // Flow is below minimum for a long time so raise the alarm else if ( TRUE == didTimeout( heatersOnWithNoFlowTimer, HEATERS_ON_NO_FLOW_TIMEOUT_MS ) ) { stopPrimaryHeater(); @@ -443,42 +429,6 @@ /*********************************************************************//** * @brief - * The execHeatersSelfTest function executes the heaters' self-test state machine. - * @details Inputs: heatersSelfTestState - * @details Outputs: heatersSelfTestState - * @return heatersSelfTestState - *************************************************************************/ -SELF_TEST_STATUS_T execHeatersSelfTest( void ) -{ - switch ( heatersSelfTestState ) - { - case HEATERS_SELF_TEST_START: - heatersSelfTestState = handleHeatersSelfTestStart(); - break; - - case HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS: - heatersSelfTestState = handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters(); - break; - - case HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER: - heatersSelfTestState = handleHeatersSelfTestMainPrimaryHeater(); - break; - - case HEATERS_SELF_TEST_COMPLETE: - // POST is done. Do nothing - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_SELF_TEST_INVALID_STATE, heatersSelfTestState ); - heatersSelfTestState = HEATERS_SELF_TEST_COMPLETE; - break; - } - - return heatersSelfTestResult; -} - -/*********************************************************************//** - * @brief * The execPrimaryHeaters function executes the primary heaters' state machine. * @details Inputs: primaryHeatersExecState * @details Outputs: primaryHeatersExecState @@ -531,108 +481,6 @@ /*********************************************************************//** * @brief - * The handleHeatersSelfTestStart function starts the small primary and - * the trimmer heaters for self-test. - * @details Inputs: heatersSelfTestResult, selfTestElapsedTime - * @details Outputs: heatersSelfTestResult, selfTestElapsedTime - * @return state (HEATERS_SELF_TEST_STATES_T) - *************************************************************************/ -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestStart( void ) -{ - // Code temporarily disabled since POST is not tested yet - // TODO once POST is tested and implemented, remove #ifndef -#ifndef _VECTORCAST_ - heatersSelfTestResult = SELF_TEST_STATUS_PASSED; - return HEATERS_SELF_TEST_COMPLETE; -#else - heatersSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - setSmallPrimaryHeaterPWM( SMALL_PRIMAY_HEATER_MAX_DUTY_CYCLE ); - setTrimmerHeaterPWM( TRIMMER_HEATER_MAX_DUTY_CYCLE ); - selfTestElapsedTime = getMSTimerCount(); - - return HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS; -#endif -} - -/*********************************************************************//** - * @brief - * The handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters function checks if - * the time on the small primary and trimmer heaters has elapsed. If time has - * elapsed, it checks the thermocouple temperature shared among the two - * heaters. If they are in range, it sets the main primary heater and transitions - * to the next state. If it fails, it sets an alarm and fails the test. - * @details Inputs: heatersSelfTestResult, selfTestElapsedTime - * @details Outputs: heatersSelfTestResult, selfTestElapsedTime - * @return state (HEATERS_SELF_TEST_STATES_T) - *************************************************************************/ -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestSmallPrimaryAndTrimmerHeaters( void ) -{ - HEATERS_SELF_TEST_STATES_T state = HEATERS_SELF_TEST_SMALL_PRIMARY_AND_TRIMMER_HEATERS; - - if ( didTimeout( selfTestElapsedTime, HEATERS_POST_HEAT_UP_TIME_SECONDS ) ) - { - setSmallPrimaryHeaterPWM( 0 ); - setTrimmerHeaterPWM( 0 ); - - F32 convertedTemperature = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_INTERNAL ); - - if ( fabs( convertedTemperature - SMALL_PRIMARY_AND_TRIMMER_HEATERS_POST_TARGET_TEMPERATURE ) > HEATERS_POST_TEMPERATURE_TOLERANCE ) - { - //TODO alarm - // TODO POST failed - heatersSelfTestResult = SELF_TEST_STATUS_FAILED; - state = HEATERS_SELF_TEST_COMPLETE; - } - else - { - setMainPrimaryHeaterPWM( MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ); - selfTestElapsedTime = getMSTimerCount(); - state = HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER; - } - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleHeatersSelfTestMainPrimaryHeater function checks if the time - * on the main primary heater has elapsed. When the time has elapsed, it - * checks to ensure the thermocouple temperature is within the tolerance - * of the target temperature. It then transitions to the complete state. - * @details Inputs: heatersSelfTestResult - * @details Outputs: heatersSelfTestResult - * @return state (HEATERS_SELF_TEST_STATES_T) - *************************************************************************/ -static HEATERS_SELF_TEST_STATES_T handleHeatersSelfTestMainPrimaryHeater( void ) -{ - HEATERS_SELF_TEST_STATES_T state = HEATERS_SELF_TEST_MAIN_PRIMARY_HEATER; - - if ( didTimeout( selfTestElapsedTime, HEATERS_POST_HEAT_UP_TIME_SECONDS ) ) - { - setMainPrimaryHeaterPWM( 0 ); - - F32 convertedTemperature = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_INTERNAL ); - - if ( fabs( convertedTemperature - MAIN_PRIMARY_HEATER_POST_TARGET_TEMPERATURE ) > HEATERS_POST_TEMPERATURE_TOLERANCE ) - { - //TODO alarm - // TODO POST failed - heatersSelfTestResult = SELF_TEST_STATUS_FAILED; - } - else - { - heatersSelfTestResult = SELF_TEST_STATUS_PASSED; - } - - state = HEATERS_SELF_TEST_COMPLETE; - } - - return state; -} - -/*********************************************************************//** - * @brief * The handlePrimaryHeaterStateOff function handles the primary heaters at * off state. * @details Inputs: hasStartPrimaryHeaterRequested, isPrimaryHeaterOn @@ -643,19 +491,27 @@ { PRIMARY_HEATERS_EXEC_STATES_T state = PRIMARY_HEATERS_EXEC_STATE_OFF; - if ( hasStartPrimaryHeaterRequested ) + if ( TRUE == hasStartPrimaryHeaterRequested ) { resetHeaterState( PRIMARY_HEATER ); + // Once the primary heaters duty cycle is set, it is divided into 2 + // so both heaters will start and both elements are heated up setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); + setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); isPrimaryHeaterOn = TRUE; hasStartPrimaryHeaterRequested = FALSE; // Check if the operation mode is heat disinfect. If the mode is // heat disinfect, the feedback sensor will be Thd if ( DG_MODE_HEAT == getCurrentOperationMode() ) { +#ifdef THD_USING_TRO_CONNECTOR // Set the feedback temperature sensor - primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; //TODO change this to Thd sensors once it is installed + // THd uses TRo in V3 + primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; +#else + primaryHeatersFeedbackTempSensor = TEMPSENSORS_HEAT_DISINFECT; +#endif } state = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; @@ -685,25 +541,25 @@ // If the flow is within range, run the PI controller to control the heaters normally if ( FALSE == isFlowBelowMin ) { - F32 outletTemp = getTemperatureValue( primaryHeatersFeedbackTempSensor ); - mainPrimaryHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, primaryHeaterTargetTemperature, outletTemp ); - - if ( mainPrimaryHeaterDutyCycle >= MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ) + // If the primary heater is running and another start primary heater request + // is set, reset the primary heater again + if ( TRUE == hasStartPrimaryHeaterRequested ) { - // The duty cycle from the PI controller was greater than max duty cycle of the main primary - // heater. So subtract the remaining from the max main primary heater duty cycle and set - // the rest to the small primary heater - smallPrimaryHeaterDutyCycle = mainPrimaryHeaterDutyCycle - MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; - mainPrimaryHeaterDutyCycle = MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; - setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); - setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + resetHeaterState( PRIMARY_HEATER ); + hasStartPrimaryHeaterRequested = FALSE; } else { - setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); - smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + F32 outletTemp = getTemperatureValue( primaryHeatersFeedbackTempSensor ); + mainPrimaryHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, primaryHeaterTargetTemperature, outletTemp ); + + // Once the primary heaters duty cycle is set, it is divided into 2 so both heaters will start and both elements are heated up + smallPrimaryHeaterDutyCycle = mainPrimaryHeaterDutyCycle / MAIN_AND_SMALL_PRIMARY_HEATER_DUTY_CYCLE_DIVISOR; + mainPrimaryHeaterDutyCycle = mainPrimaryHeaterDutyCycle / MAIN_AND_SMALL_PRIMARY_HEATER_DUTY_CYCLE_DIVISOR; } + + setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); + setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); } // Flow is below the minimum required flow to run the primary heaters else @@ -715,7 +571,7 @@ primaryHeaterTimerCounter = 0; } - if ( isPrimaryHeaterOn != TRUE ) + if ( FALSE == isPrimaryHeaterOn ) { // Switch to off state. Set the duty cycles to 0 mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; @@ -740,21 +596,12 @@ { TRIMMER_HEATER_EXEC_STATES_T state = TRIMMER_HEATER_EXEC_STATE_OFF; - if ( hasStartTrimmerHeaterRequested ) + if ( TRUE == hasStartTrimmerHeaterRequested ) { resetHeaterState( TRIMMER_HEATER ); isTrimmerHeaterOn = TRUE; hasStartTrimmerHeaterRequested = FALSE; setTrimmerHeaterPWM( trimmerHeaterDutyCycle ); - - // Check if the operation mode is heat disinfect. If the mode is - // heat disinfect, the feedback sensor will be Thd - if ( DG_MODE_HEAT == getCurrentOperationMode() ) - { - // Set the feedback temperature sensor - trimmerHeaterFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; //TODO change this to Thd sensors once it is installed - } - state = TRIMMER_HEATER_EXEC_STATE_CONTROL_TO_TARGET; } @@ -793,7 +640,7 @@ trimmerHeaterTimerCounter = 0; } - if ( ! isTrimmerHeaterOn ) + if ( FALSE == isTrimmerHeaterOn ) { // Set the duty cycle to 0 and switch to off state trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; @@ -853,12 +700,35 @@ *************************************************************************/ static void resetHeaterState( NAME_OF_HEATER_T heater ) { - if ( heater == PRIMARY_HEATER ) + if ( PRIMARY_HEATER == heater ) { - mainPrimaryHeaterDutyCycle = MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE; - resetPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ); + // Calculate the delta temperature from the inlet primary heater to target temperature + F32 inletPrimaryHeaterTemp = getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ); + F32 deltaTemp = primaryHeaterTargetTemperature - inletPrimaryHeaterTemp; + + // If the delta temperature (target temperature - inlet primary heater temperature) + // Is 0 or negative, the duty cycle is 0.0 + if ( deltaTemp <= 0.0 ) + { + mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + } + else + { + // The formula for the initial guess is: (delta temperature * target flow) / 2.0 + F32 targetFlow = getTargetROPumpFlowRate(); + F32 duty = ( targetFlow * deltaTemp ) / PRIMARY_HEATER_INITIAL_DUTY_CYCLE_ESTIMATE_DIVISOR; + // If the duty cycle is greater 200% on the primary and small primary heaters, set it to 200%, otherwise set it to the + // estimated duty cycles + duty = ( duty > PRIMARY_HEATERS_CUMULATIVE_DUTY_CYCLE ? PRIMARY_HEATERS_CUMULATIVE_DUTY_CYCLE : duty ); + mainPrimaryHeaterDutyCycle = duty / MAIN_AND_SMALL_PRIMARY_HEATER_DUTY_CYCLE_DIVISOR; + smallPrimaryHeaterDutyCycle = duty / MAIN_AND_SMALL_PRIMARY_HEATER_DUTY_CYCLE_DIVISOR; + } + + // The PI controller of the primary heater consists of main and small primary heaters duty cycles + resetPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, mainPrimaryHeaterDutyCycle + smallPrimaryHeaterDutyCycle ); } - else if ( heater == TRIMMER_HEATER ) + else if ( TRIMMER_HEATER == heater ) { trimmerHeaterDutyCycle = TRIMMER_HEATER_MAX_DUTY_CYCLE; resetPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, TRIMMER_HEATER_MAX_DUTY_CYCLE ); @@ -901,6 +771,8 @@ data.mainPrimayHeaterDC = mainPrimaryHeaterDutyCycle * 100.0; data.smallPrimaryHeaterDC = smallPrimaryHeaterDutyCycle * 100.0; data.trimmerHeaterDC = trimmerHeaterDutyCycle * 100.0; + data.primaryTargetTemp = primaryHeaterTargetTemperature; + data.trimmerTargetTemp = trimmerHeaterTargetTemperature; broadcastHeatersData( &data ); @@ -925,7 +797,7 @@ { BOOL result = FALSE; - if ( isTestingActivated() ) + if ( TRUE == isTestingActivated() ) { U32 interval = value / TASK_PRIORITY_INTERVAL; @@ -949,7 +821,7 @@ { BOOL result = FALSE; - if ( isTestingActivated() ) + if ( TRUE == isTestingActivated() ) { result = TRUE; heatersDataPublishInterval.override = OVERRIDE_RESET;