Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r8467f8ff09e382e0991f14d02683080dc811e24e -r2fff37fa585181917705645494549b5fd4a4d522 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 8467f8ff09e382e0991f14d02683080dc811e24e) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 2fff37fa585181917705645494549b5fd4a4d522) @@ -40,12 +40,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. @@ -56,29 +66,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 { @@ -105,8 +100,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. @@ -124,20 +117,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. +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. 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 ); @@ -161,7 +153,6 @@ *************************************************************************/ void initHeaters( void ) { - heatersSelfTestState = HEATERS_SELF_TEST_START; primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; primaryHeaterTargetTemperature = 0.0; @@ -171,14 +162,17 @@ dataPublicationTimerCounter = 0; isPrimaryHeaterOn = FALSE; isTrimmerHeaterOn = FALSE; - selfTestElapsedTime = 0; primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_PRIMARY_HEATER; - trimmerHeaterFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; + trimmerHeaterFeedbackTempSensor = TEMPSENSORS_INLET_DIALYSATE; + primaryHeatersInternalTempOutTimer = 0; + trimmerHeaterInternalTempOutTimer = 0; + isPrimaryHeatersTempOutOfRange = FALSE; + isTrimmerHeaterTempOutOfRange = FALSE; 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, @@ -231,9 +225,7 @@ if ( ( primaryHeaterTargetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( primaryHeaterTargetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { -//#ifndef DISABLE_HEATERS_AND_TEMPS hasStartPrimaryHeaterRequested = TRUE; -//#endif status = TRUE; } @@ -254,9 +246,7 @@ if ( ( trimmerHeaterTargetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( trimmerHeaterTargetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { -#ifndef DISABLE_HEATERS_AND_TEMPS hasStartTrimmerHeaterRequested = TRUE; -#endif status = TRUE; } @@ -341,7 +331,6 @@ *************************************************************************/ void execHeatersMonitor( void ) { - // TODO check for the heaters' fault flags and fault if any of them are at fault it should alarm #ifndef IGNORE_HEATERS_MONITOR F32 primaryHeatersInternalTemp = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_INTERNAL ); F32 trimmerHeaterInternalTemp = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_INTERNAL ); @@ -370,8 +359,11 @@ * 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 */ - BOOL isHeaterOn = ( 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 ); @@ -409,42 +401,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 @@ -497,106 +453,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 ( TRUE == 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 ) - { - heatersSelfTestResult = SELF_TEST_STATUS_FAILED; - state = HEATERS_SELF_TEST_COMPLETE; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_HEATERS_SELF_TEST_FAILURE, TEMPSENSORS_TRIMMER_HEATER_INTERNAL, convertedTemperature ) - } - 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 ( TRUE == 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 ) - { - heatersSelfTestResult = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_HEATERS_SELF_TEST_FAILURE, TEMPSENSORS_PRIMARY_HEATER_INTERNAL, convertedTemperature ) - } - 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 @@ -610,16 +466,24 @@ 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; @@ -649,25 +513,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 @@ -679,7 +543,7 @@ primaryHeaterTimerCounter = 0; } - if ( isPrimaryHeaterOn != TRUE ) + if ( FALSE == isPrimaryHeaterOn ) { // Switch to off state. Set the duty cycles to 0 mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; @@ -708,15 +572,6 @@ 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; } @@ -755,7 +610,7 @@ trimmerHeaterTimerCounter = 0; } - if ( isTrimmerHeaterOn != TRUE ) + if ( FALSE == isTrimmerHeaterOn ) { // Set the duty cycle to 0 and switch to off state trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; @@ -816,8 +671,31 @@ { 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 ( TRIMMER_HEATER == heater ) {