Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -rbbd5ac2589c8093f681f2284367975ddd220b553 -rebbb1f85550a1f9b8f946655f7b2b63f76fbf67d --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision bbd5ac2589c8093f681f2284367975ddd220b553) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision ebbb1f85550a1f9b8f946655f7b2b63f76fbf67d) @@ -17,54 +17,57 @@ #include +// TI PWM driver #include "etpwm.h" #include "AlarmMgmt.h" #include "DGDefs.h" #include "Heaters.h" -#include "ROPump.h" +#include "OperationModes.h" #include "PIControllers.h" +#include "ROPump.h" +#include "SafetyShutdown.h" #include "SystemCommMessages.h" -#include "TaskGeneral.h" +#include "TaskPriority.h" #include "TemperatureSensors.h" #include "Timers.h" -#ifdef ENABLE_DIP_SWITCHES -#include "mibspi.h" -#include "FPGA.h" -#endif - /** * @addtogroup Heaters * @{ */ // ********** private definitions ********** -#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%). -#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters minimum duty cycle (0.00%). +#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%). +#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters minimum duty cycle (0.00%). -#define PRIMARY_HEATERS_P_COEFFICIENT 0.02 ///< Primary heaters proportional coefficient. -#define PRIMARY_HEATERS_I_COEFFICIENT 0.001 ///< Primary heaters integral coefficient. +#define PRIMARY_HEATERS_P_COEFFICIENT 0.02 ///< 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. -#define TRIMMER_HEATER_I_COEFFICIENT 0.001 ///< Trimmer heater integral coefficient. +#define TRIMMER_HEATER_P_COEFFICIENT 0.02 ///< Trimmer heater proportional coefficient. +#define TRIMMER_HEATER_I_COEFFICIENT 0.001 ///< Trimmer heater integral coefficient. -#define CONTROLLER_CHECK_INTERVAL_COUNT 10U ///< Time interval count to check the PI controller. -#define TEMP_SENSORS_INTERVAL_COUNT 10U ///< Temperature sensors interval count. +#define CONTROLLER_CHECK_INTERVAL_COUNT 10U ///< Time interval count to check the PI controller. +#define TEMP_SENSORS_INTERVAL_COUNT 10U ///< Temperature sensors interval count. -#define HEATERS_DATA_PUBLISH_INTERVAL (500 / TASK_GENERAL_INTERVAL ) ///< Heaters data publish interval. +#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 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 10U ///< Minimum allowed target temperature for the heaters. -#define MAXIMUM_TARGET_TEMPERATURE 90U ///< 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_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 { @@ -101,28 +104,36 @@ // ********** 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. +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. -static F32 primaryHeaterTargetTemperature; ///< Primary heaters target temperature. -static F32 trimmerHeaterTargetTemperature; ///< Trimmer heater target temperature. +static F32 primaryHeaterTargetTemperature; ///< Primary heaters target temperature. +static F32 trimmerHeaterTargetTemperature; ///< Trimmer heater target temperature. -static F32 mainPrimaryHeaterDutyCycle; ///< Main primary heater duty cycle. -static F32 smallPrimaryHeaterDutyCycle; ///< Small primary heater duty cycle. -static F32 trimmerHeaterDutyCycle; ///< Trimmer heater duty cycle. -static U32 primaryHeaterTimerCounter; ///< Primary heater timer counter. -static U32 trimmerHeaterTimerCounter; ///< Trimmer heater timer counter. -static U32 dataPublicationTimerCounter; ///< Data publication timer counter. -static BOOL isPrimaryHeaterOn; ///< Flag to show if the primary heater is on. -static BOOL isTrimmerHeaterOn; ///< Flag to show if the trimmer heater is on. +static F32 mainPrimaryHeaterDutyCycle; ///< Main primary heater duty cycle. +static F32 smallPrimaryHeaterDutyCycle; ///< Small primary heater duty cycle. +static F32 trimmerHeaterDutyCycle; ///< Trimmer heater duty cycle. +static U32 primaryHeaterTimerCounter; ///< Primary heater timer counter. +static U32 trimmerHeaterTimerCounter; ///< Trimmer heater timer counter. +static U32 dataPublicationTimerCounter; ///< Data publication timer counter. +static BOOL isPrimaryHeaterOn; ///< Flag to show if the primary heater is on. +static BOOL isTrimmerHeaterOn; ///< Flag to show if the trimmer heater is on. 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. + 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 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 ********** @@ -141,13 +152,8 @@ static void setTrimmerHeaterPWM( F32 pwm ); static void resetHeaterState( NAME_OF_HEATER_T heater ); static void publishHeatersData( void ); -static U32 getPublishHeatersDataInterval( void ); +static U32 getPublishHeatersDataInterval( void ); -// TODO: Remove the below code. FOR TESTING ONLY -#define PRIMARY_HEATER_MIBSPI1_PORT_MASK 0x00000002 // (CS1 - re-purposed as input GPIO) -#define TOGGLEPRIMAYHEATER() ( ( mibspiREG1->PC2 & PRIMARY_HEATER_MIBSPI1_PORT_MASK ) != 0 ) -//TODO: Remove the above code. FOR TESTING ONLY - /*********************************************************************//** * @brief * The initHeaters function initializes the variables and the PI controllers @@ -158,17 +164,24 @@ *************************************************************************/ void initHeaters( void ) { - heatersSelfTestState = HEATERS_SELF_TEST_START; - primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; - trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; - primaryHeaterTargetTemperature = 0.0; - trimmerHeaterTargetTemperature = 0.0; - primaryHeaterTimerCounter = 0; - trimmerHeaterTimerCounter = 5; - dataPublicationTimerCounter = 0; - isPrimaryHeaterOn = FALSE; - isTrimmerHeaterOn = FALSE; - selfTestElapsedTime = 0; + heatersSelfTestState = HEATERS_SELF_TEST_START; + primaryHeatersExecState = PRIMARY_HEATERS_EXEC_STATE_OFF; + trimmerHeaterExecState = TRIMMER_HEATER_EXEC_STATE_OFF; + primaryHeaterTargetTemperature = 0.0; + trimmerHeaterTargetTemperature = 0.0; + primaryHeaterTimerCounter = 0; + trimmerHeaterTimerCounter = 5; + dataPublicationTimerCounter = 0; + isPrimaryHeaterOn = FALSE; + isTrimmerHeaterOn = FALSE; + selfTestElapsedTime = 0; + primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_PRIMARY_HEATER; + trimmerHeaterFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; + 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, @@ -221,9 +234,9 @@ if ( ( primaryHeaterTargetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( primaryHeaterTargetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { -#ifndef DISABLE_HEATERS_AND_TEMPS +//#ifndef DISABLE_HEATERS_AND_TEMPS hasStartPrimaryHeaterRequested = TRUE; -#endif +//#endif status = TRUE; } @@ -262,10 +275,8 @@ *************************************************************************/ void stopPrimaryHeater( void ) { - mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); - setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + setMainPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); + setSmallPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); isPrimaryHeaterOn = FALSE; } @@ -278,8 +289,7 @@ *************************************************************************/ void stopTrimmerHeater( void ) { - trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setTrimmerHeaterPWM( trimmerHeaterDutyCycle ); + setTrimmerHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); isTrimmerHeaterOn = FALSE; } @@ -326,23 +336,93 @@ /*********************************************************************//** * @brief - * The execHeatersMonitor function turns off the heaters when RO pump is not on. + * The execHeatersMonitor function turns off the heaters when RO pump is + * not on. * @details Inputs: none * @details Outputs: Turns off the heaters when RO pump is not on * @return none *************************************************************************/ void execHeatersMonitor( void ) { - // If the RO pump is not on, turn off the heaters - if ( ! isReverseOsmosisPumpOn() ) +#ifndef IGNORE_HEATERS_MONITOR + F32 primaryHeatersInternalTemp = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_INTERNAL ); + F32 trimmerHeaterInternalTemp = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_INTERNAL ); + + // Check if the primary heaters' internal temperature is above the limit + if ( primaryHeatersInternalTemp > HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C ) { -#ifndef ENABLE_DIP_SWITCHES -#ifndef EMC_TEST_BUILD - stopPrimaryHeater(); // TODO - this is so immediate - if other module requests RO pump on and start heater, this monitor may stop the heater request before RO pump has a chance to start - stopTrimmerHeater(); -#endif -#endif + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_PRIMARY_HEATERS_INTERNAL_TEMP_OUT_OF_RANGE, primaryHeatersInternalTemp ); + + // If it is above the range for the first time, stop the primary heaters + // and set the variables + if ( FALSE == isPrimaryHeatersTempOutOfRange ) + { + stopPrimaryHeater(); + isPrimaryHeatersTempOutOfRange = TRUE; + primaryHeatersInternalTempOutTimer = getMSTimerCount(); + } + // If the primary heaters internal temperature was out for more than the define period, activate the safety shutdown + else if ( TRUE == didTimeout( primaryHeatersInternalTempOutTimer, HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_TIMEOUT_MS ) ) + { + activateSafetyShutdown(); + } } + + // Check if the trimmer heater internal temperature is above the limit + if ( trimmerHeaterInternalTemp > HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_INTERNAL_TEMP_OUT_OF_RANGE, trimmerHeaterInternalTemp ); + + // If it is above the range for the first time, stop the trimmer heater + // and set the variables + if ( FALSE == isTrimmerHeaterTempOutOfRange ) + { + stopTrimmerHeater(); + isTrimmerHeaterTempOutOfRange = TRUE; + trimmerHeaterInternalTempOutTimer = getMSTimerCount(); + } + // If the trimmer heater internal temperature was out for more than the define period, activate the safety shutdown + else if ( TRUE == didTimeout( trimmerHeaterInternalTempOutTimer, HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_TIMEOUT_MS ) ) + { + activateSafetyShutdown(); + } + } + + /* + * If any of the heaters are on, 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 + */ + if ( ( TRUE == isPrimaryHeaterOn ) || ( TRUE == isTrimmerHeaterOn ) ) + { + F32 measuredFlow = getMeasuredROFlowRate(); + + if ( measuredFlow < MIN_RO_FLOWRATE_LPM ) + { + if ( FALSE == isFlowBelowMin ) + { + isFlowBelowMin = TRUE; + heatersOnWithNoFlowTimer = getMSTimerCount(); + } + else if ( TRUE == didTimeout( heatersOnWithNoFlowTimer, HEATERS_ON_NO_FLOW_TIMEOUT_MS ) ) + { + stopPrimaryHeater(); + stopTrimmerHeater(); + + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_HEATERS_ON_WITH_NO_FLOW_TIMEOUT, measuredFlow ); + } + } + else + { + isFlowBelowMin = FALSE; + heatersOnWithNoFlowTimer = getMSTimerCount(); + } + } +#endif + + // Check for data publication + publishHeatersData(); } /*********************************************************************//** @@ -547,37 +627,24 @@ { PRIMARY_HEATERS_EXEC_STATES_T state = PRIMARY_HEATERS_EXEC_STATE_OFF; - // TODO for testing only. remove -#ifdef DEBUG_ENABLED -#ifdef ENABLE_DIP_SWITCHES -#ifndef EMC_TEST_BUILD - if ( TOGGLEPRIMAYHEATER() ) - { - setPrimaryHeaterTargetTemperature( 37 ); - startPrimaryHeater(); - F32 pumpPWM = 1; - etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - F32 fanPWM = 0.25; - etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - hasStartPrimaryHeaterRequested = TRUE; - } -#endif -#endif -#endif - // TODO remove this code for testing - if ( hasStartPrimaryHeaterRequested ) { resetHeaterState( PRIMARY_HEATER ); setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); 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() ) + { + // Set the feedback temperature sensor + primaryHeatersFeedbackTempSensor = TEMPSENSORS_OUTLET_REDUNDANT; //TODO change this to Thd sensors once it is installed + } + state = PRIMARY_HEATERS_EXEC_STATE_CONTROL_TO_TARGET; } - publishHeatersData(); - return state; } @@ -597,50 +664,46 @@ if ( ++primaryHeaterTimerCounter >= CONTROLLER_CHECK_INTERVAL_COUNT ) { - F32 outletTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - mainPrimaryHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, primaryHeaterTargetTemperature, outletTemp ); - - if ( mainPrimaryHeaterDutyCycle >= MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ) + // Check if the flow is not below minimum required first + // If the flow is below minimum, send 0.00 to the PWM until the flow comes back to range + // If the flow is within range, run the PI controller to control the heaters normally + if ( FALSE == isFlowBelowMin ) { - // 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 ); + F32 outletTemp = getTemperatureValue( primaryHeatersFeedbackTempSensor ); + mainPrimaryHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, primaryHeaterTargetTemperature, outletTemp ); + + if ( mainPrimaryHeaterDutyCycle >= MAIN_PRIMARY_HEATER_MAX_DUTY_CYCLE ) + { + // 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 ); + } + else + { + setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); + smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + } } + // Flow is below the minimum required flow to run the primary heaters else { - setMainPrimaryHeaterPWM( mainPrimaryHeaterDutyCycle ); - smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; - setSmallPrimaryHeaterPWM( smallPrimaryHeaterDutyCycle ); + setMainPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); + setSmallPrimaryHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); } + primaryHeaterTimerCounter = 0; } - publishHeatersData(); - - // TODO remove this code -#ifdef DEBUG_ENABLED -#ifdef ENABLE_DIP_SWITCHES -#ifndef EMC_TEST_BUILD - if ( !TOGGLEPRIMAYHEATER() ) + if ( isPrimaryHeaterOn != TRUE ) { - stopPrimaryHeater(); - F32 pumpPWM = 0; - etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - F32 fanPWM = 0; - etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - } -#endif -#endif -#endif - // TODO Remove this code - - if ( ! isPrimaryHeaterOn ) - { + // Switch to off state. Set the duty cycles to 0 + mainPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; + smallPrimaryHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; state = PRIMARY_HEATERS_EXEC_STATE_OFF; } @@ -659,40 +722,24 @@ { TRIMMER_HEATER_EXEC_STATES_T state = TRIMMER_HEATER_EXEC_STATE_OFF; - // TODO for testing only. remove -#ifdef DEBUG_ENABLED -#ifdef ENABLE_DIP_SWITCHES -#ifndef EMC_TEST_BUILD -// if ( TOGGLEPRIMAYHEATER() ) -// { - //setTrimmerHeaterTargetTemperature( 38 ); - //startTrimmerHeater(); - //F32 pumpPWM = 1; - //etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //temporaryStartROPump(); - //temporaryStartFan(); - //F32 fanPWM = 0.25; - //etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //temporaryStartROPump(); - //temporaryStartFan(); -// } -#endif -#endif -#endif - // TODO remove this code for testing - if ( 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; } - publishHeatersData(); - return state; } @@ -701,7 +748,8 @@ * The handleTrimmerHeaterControlToTarget function handles the trimmer * heater at control state when the heater is active. * @details Inputs: trimmerHeaterTimerCounter, trimmerHeaterDutyCycle - * @details Outputs: trimmerHeaterTimerCounter, trimmerHeaterDutyCycle, isTrimmerHeaterOn + * @details Outputs: trimmerHeaterTimerCounter, trimmerHeaterDutyCycle, + * isTrimmerHeaterOn * @return state (TRIMMER_HEATER_EXEC_STATES_T) *************************************************************************/ static TRIMMER_HEATER_EXEC_STATES_T handleTrimmerHeaterControlToTarget( void ) @@ -710,38 +758,27 @@ if ( ++trimmerHeaterTimerCounter >= CONTROLLER_CHECK_INTERVAL_COUNT ) { - F32 outletTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); - trimmerHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, trimmerHeaterTargetTemperature, outletTemp ); - setTrimmerHeaterPWM( trimmerHeaterDutyCycle ); + // Check if the flow is not below minimum required first + // If the flow is below minimum, send 0.00 to the PWM until the flow comes back to range + // If the flow is within range, run the PI controller to control the heaters normally + if ( FALSE == isFlowBelowMin ) + { + F32 outletTemp = getTemperatureValue( trimmerHeaterFeedbackTempSensor ); + trimmerHeaterDutyCycle = runPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, trimmerHeaterTargetTemperature, outletTemp ); + setTrimmerHeaterPWM( trimmerHeaterDutyCycle ); + } + else + { + setTrimmerHeaterPWM( HEATERS_MIN_DUTY_CYCLE ); + } + trimmerHeaterTimerCounter = 0; } - publishHeatersData(); - - // TODO remove this code -#ifdef DEBUG_ENABLED -#ifdef ENABLE_DIP_SWITCHES -#ifndef EMC_TEST_BUILD -// if ( !TOGGLEPRIMAYHEATER() ) -// { - //stopTrimmerHeater(); - //F32 pumpPWM = 0; - //etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( pumpPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //temporaryStartROPump(); - //temporaryStartFan(); - //F32 fanPWM = 0; - //etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( fanPWM * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); - //temporaryStopROPump(); - //temporaryStopFan(); -// } -#endif -#endif -#endif - // TODO Remove this code - if ( ! isTrimmerHeaterOn ) { + // Set the duty cycle to 0 and switch to off state + trimmerHeaterDutyCycle = HEATERS_MIN_DUTY_CYCLE; state = TRIMMER_HEATER_EXEC_STATE_OFF; } @@ -830,23 +867,28 @@ /*********************************************************************//** * @brief - * The publishTemperatureData function publishes the temperature sensors - * data into the USB debug port at the defined time interval. + * The publishTemperatureData function publishes the heaters data into + * at the defined time interval. * @details Inputs: dataPublicationTimerCounter - * @details Outputs: Broadcast temperature sensors' data + * @details Outputs: dataPublicationTimerCounter * @return none *************************************************************************/ static void publishHeatersData( void ) { if ( ++dataPublicationTimerCounter >= getPublishHeatersDataInterval() ) { - broadcastHeatersData( (U32)(mainPrimaryHeaterDutyCycle*100), (U32)(smallPrimaryHeaterDutyCycle*100), (U32)(trimmerHeaterDutyCycle*100) ); + HEATERS_DATA_T data; + data.mainPrimayHeaterDC = mainPrimaryHeaterDutyCycle * 100.0; + data.smallPrimaryHeaterDC = smallPrimaryHeaterDutyCycle * 100.0; + data.trimmerHeaterDC = trimmerHeaterDutyCycle * 100.0; + + broadcastHeatersData( &data ); + dataPublicationTimerCounter = 0; } } - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -866,7 +908,7 @@ if ( isTestingActivated() ) { - U32 interval = value / TASK_GENERAL_INTERVAL; + U32 interval = value / TASK_PRIORITY_INTERVAL; result = TRUE; heatersDataPublishInterval.ovData = interval;