Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r1a6783245f983c48523e11abe4a2074677720f18 -rd74b98a3b101ec827cc7da59dd617df9435d79e3 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 1a6783245f983c48523e11abe4a2074677720f18) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision d74b98a3b101ec827cc7da59dd617df9435d79e3) @@ -69,8 +69,8 @@ #define HEATERS_MIN_RAMP_TIME_MS ( 6 * MS_PER_SECOND ) ///< Heaters minimum time that they have to stay in the ramp state in milliseconds. #define TEMPERATURES_MOVING_AVG_SIZE 3U ///< Heaters ramp state temperatures moving average size. -#define PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_SLOPE 0.31644 ///< Primary heaters thermal power to voltage slope. -#define PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_INTERCEPT 0.021 ///< Primary heaters thermal power to voltage intercept. +#define PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_SLOPE 0.395 ///< Primary heaters thermal power to voltage slope. +#define PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_INTERCEPT 0.21 ///< Primary heaters thermal power to voltage intercept. #define DELTA_DUTY_CYCLE_GAIN 0.1 ///< Delta duty cycle gain. #define DELTA_TEMPERATURE_GAIN 1.27 ///< Delta temperature gain. @@ -97,13 +97,13 @@ BOOL startHeaterSignal; ///< Heater start indication flag. BOOL isHeaterOn; ///< Heater on/off status flag. F32 dutycycle; ///< Heater duty cycle. - F32 fillDutyCycle; ///< Heater fill duty cycle. F32 targetROFlow; ///< Heater target flow. U32 rampStateStartTime; ///< Heater ramp state start time. U32 heaterOnWithNoFlowTimer; ///< Heater on with no flow timer. BOOL isFlowBelowMin; ///< Heater flow below minimum flag indicator. - F32 initialDutyCycle; ///< Heater initial duty cycle before a hand off. + F32 initialDutyCycle; // TODO do we need this? ///< Heater initial duty cycle before a hand off. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. + BOOL isThisFirstRamp; PI_CONTROLLER_ID_T controllerID; ///< Heater PI controller ID TODO remove this? @@ -134,6 +134,7 @@ static void checkPrimaryHeaterTempSensors( void ); static void checkTrimmerHeaterTempSensors( void ); static void monitorHeatersVoltage( void ); +static void checkHeaterOnStatus( DG_HEATERS_T heater ); /*********************************************************************//** * @brief @@ -163,7 +164,6 @@ heatersStatus[ heater ].targetTemp = 0.0; heatersStatus[ heater ].originalTargetTemp = 0.0; heatersStatus[ heater ].dutycycle = 0.0; - heatersStatus[ heater ].fillDutyCycle = 0.0; heatersStatus[ heater ].targetROFlow = 0.0; heatersStatus[ heater ].previousTempsIndex = 0; heatersStatus[ heater ].controllerID = ( DG_PRIMARY_HEATER == heater ? 4 : PI_CONTROLLER_ID_TRIMMER_HEATER ); // TODO remove or refactor? @@ -322,8 +322,8 @@ { DG_CMD_RESPONSE_T cmdResponse; - cmdResponse.commandID = DG_CMD_START_TRIMMER_HEATER; - cmdResponse.rejected = TRUE; + cmdResponse.commandID = DG_CMD_START_TRIMMER_HEATER; + cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; if ( TRUE == heaterCmdPtr->startHeater ) @@ -432,7 +432,14 @@ heatersStatus[ heater ].startHeaterSignal = FALSE; heatersStatus[ heater ].targetROFlow = getTargetROPumpFlowRate(); - if ( ( DG_MODE_DRAI == getCurrentOperationMode() ) || ( DG_MODE_GENE == getCurrentOperationMode() ) ) + // TODO for testing remove + heatersStatus[ heater ].targetTemp = heatersStatus[ heater ].originalTargetTemp; + F32 dutyCycle = calculateHeaterDutyCycle( 39.0, getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ), 0.8 ); + setHeaterDutyCycle( heater, dutyCycle ); + // TODo for testing remove + + // TODO uncomment + /* if ( ( DG_MODE_DRAI == getCurrentOperationMode() ) || ( DG_MODE_GENE == getCurrentOperationMode() ) ) { heatersStatus[ heater ].targetTemp = MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE; } @@ -457,7 +464,7 @@ setHeaterDutyCycle( heater, duty ); // Once the heater is staring for the first time so no minimum ramp time is needed - heatersStatus[ heater ].rampStateStartTime = getMSTimerCount(); + heatersStatus[ heater ].rampStateStartTime = getMSTimerCount(); */ // Turn on the heater state = HEATER_EXEC_STATE_RAMP_TO_TARGET; @@ -477,53 +484,30 @@ *************************************************************************/ static HEATERS_STATE_T handleHeaterStateRampToTarget( DG_HEATERS_T heater ) { - F32 dutyCycle; - HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; TEMPERATURE_SENSORS_T sensor = heatersStatus[ heater ].feedbackSensor; + F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); F32 feedbackTemperature = getTemperatureValue( (U32)sensor ); + F32 targetFlow = getTargetROPumpFlowRate(); // Continuously get the target temperature in case it was changed dynamically F32 targetTemperature = heatersStatus[ heater ].originalTargetTemp; - U32 currentIndex = heatersStatus[ heater ].previousTempsIndex; - F32 targetFlow = getTargetROPumpFlowRate(); BOOL hasFlowChanged = ( fabs( targetFlow - heatersStatus[ heater ].targetROFlow ) > NEARLY_ZERO ? TRUE : FALSE ); + F32 dutyCycle = heatersStatus[ heater ].dutycycle; // Set the hand off flag to false BOOL isItHandOffTime = FALSE; - F32 measuredFlow = getTargetROPumpFlowRate(); // TODO change this to measured flow?? This is target for testing for now - //haveHeaterControlConditionsChanged( heater ); - - if ( ( DG_MODE_FILL == getCurrentOperationMode() ) && ( heatersStatus[ heater ].fillDutyCycle - 0.0 > NEARLY_ZERO ) ) + // TODO remve this code + if ( DG_MODE_FILL == getCurrentOperationMode() ) { - dutyCycle = heatersStatus[ heater ].fillDutyCycle; - heatersStatus[ heater ].targetTemp = targetTemperature; - isItHandOffTime = TRUE; + dutyCycle = calculateHeaterDutyCycle( 39.0, inletTemperature, 0.8 ); + heatersStatus[ heater ].targetTemp = heatersStatus[ heater ].originalTargetTemp; } - else if ( ( ( DG_MODE_DRAI == getCurrentOperationMode() ) || ( DG_MODE_GENE == getCurrentOperationMode() ) ) && ( heatersStatus[ heater ].fillDutyCycle - 0.0 > NEARLY_ZERO ) ) - { - F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); - F32 highTempDutyCycle = calculateHeaterDutyCycle( MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE, inletTemperature, measuredFlow ); + isItHandOffTime = TRUE; + // TODO remove this code - if ( heatersStatus[ heater ].fillDutyCycle - 0.0 < NEARLY_ZERO ) - { - dutyCycle = calculateHeaterDutyCycle( targetTemperature, inletTemperature, 0.8 ); // TODO add the fill flow rate - } - else - { - dutyCycle = heatersStatus[ heater ].fillDutyCycle; - } - dutyCycle = ( dutyCycle < highTempDutyCycle ? dutyCycle : highTempDutyCycle ); - - targetTemperature = ( pow( ( dutyCycle + PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_INTERCEPT ) / PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_SLOPE, 2 ) / measuredFlow ) + feedbackTemperature; - - targetTemperature = ( targetTemperature > MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE ? MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE : targetTemperature ); - heatersStatus[ heater ].targetTemp = targetTemperature; - - isItHandOffTime = TRUE; - } - else if ( heatersStatus[ heater ].fillDutyCycle - 0.0 < NEARLY_ZERO ) + /*if ( heatersStatus[ heater ].initialDutyCycle - 0.0 < NEARLY_ZERO ) { if ( ++heatersStatus[ heater ].controlTimerCounter > HEATERS_RAMP_STATE_CHECK_INTERVAL_COUNT ) { @@ -532,9 +516,9 @@ F32 deltaTemperature; F32 deltaDutyCycle; F32 revDeltaDutyCycle; - F32 inletTemperature; // Update the temperature data array as well as the next index + U32 currentIndex = heatersStatus[ heater ].previousTempsIndex; heatersStatus[ heater ].previousTemps[ currentIndex ] = feedbackTemperature; heatersStatus[ heater ].previousTempsIndex = INC_WRAP( currentIndex, 0, TEMPERATURES_MOVING_AVG_SIZE - 1 ); @@ -551,32 +535,24 @@ slope += heatersStatus[ heater ].previousTemps[ i ]; } - // If the heater is the primary heater, - if ( DG_PRIMARY_HEATER == heater ) - { - inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); - } - else - { - // TODO figure out the trimmer strategy - } - // TODO add comments if ( ( ( DG_MODE_DRAI == getCurrentOperationMode() ) || ( DG_MODE_GENE == getCurrentOperationMode() ) ) ) { targetTemperature = MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE; } + else if ( ( DG_MODE_FILL == getCurrentOperationMode() ) ) + { + targetFlow = getTargetROPumpFlowRate(); // TODO change this to the moving average flow from fill + } slope = slope / (F32)TEMPERATURES_MOVING_AVG_SIZE; - //measuredFlow = getMeasuredROFlowRate(); TODO uncomment for testing only - measuredFlow = getTargetROPumpFlowRate(); // TODO is this right? - dutyCycle = calculateHeaterDutyCycle( targetTemperature, inletTemperature, measuredFlow ); + dutyCycle = calculateHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); deltaDutyCycle = ( feedbackTemperature <= targetTemperature ? HEATERS_MAX_DUTY_CYCLE - dutyCycle : dutyCycle ); revDeltaDutyCycle = ( deltaDutyCycle - 0.0 < NEARLY_ZERO ? 0.0 : 1.0 / deltaDutyCycle ); revDeltaDutyCycle = ( revDeltaDutyCycle * DELTA_DUTY_CYCLE_GAIN < HEATERS_MAX_DUTY_CYCLE ? revDeltaDutyCycle * DELTA_DUTY_CYCLE_GAIN : HEATERS_MAX_DUTY_CYCLE ); - deltaTemperature = ( ( atanf( slope ) * DELTA_TEMPERATURE_GAIN ) / measuredFlow ) + revDeltaDutyCycle; + deltaTemperature = ( ( atanf( slope ) * DELTA_TEMPERATURE_GAIN ) / targetFlow ) + revDeltaDutyCycle; if ( fabs( targetTemperature - feedbackTemperature ) < deltaTemperature ) { @@ -592,24 +568,45 @@ if ( ( TRUE == isItHandOffTime ) && ( DG_MODE_FILL == getCurrentOperationMode() ) ) { - heatersStatus[ heater ].fillDutyCycle = dutyCycle; heatersStatus[ heater ].targetTemp = heatersStatus[ heater ].originalTargetTemp; } heatersStatus[ heater ].controlTimerCounter = 0; } } + else + { + if ( ( DG_MODE_FILL == getCurrentOperationMode() ) ) + { + dutyCycle = calculateHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); + heatersStatus[ heater ].targetTemp = targetTemperature; + isItHandOffTime = TRUE; + } + else if ( ( ( DG_MODE_DRAI == getCurrentOperationMode() ) || ( DG_MODE_GENE == getCurrentOperationMode() ) ) ) + { + F32 highTempDutyCycle = calculateHeaterDutyCycle( MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE, inletTemperature, targetFlow ); + dutyCycle = ( dutyCycle < highTempDutyCycle ? dutyCycle : highTempDutyCycle ); + + targetTemperature = ( pow( ( dutyCycle + PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_INTERCEPT ) / PRIMARY_HEATERS_THERMAL_POWER_TO_VOLTAGE_SLOPE, 2 ) + / targetFlow ) + feedbackTemperature; + + targetTemperature = ( targetTemperature > MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE ? MAXIMUM_IDLE_DRAIN_TARGET_TEMPERATURE : targetTemperature ); + heatersStatus[ heater ].targetTemp = targetTemperature; + + isItHandOffTime = TRUE; + } + }*/ + if ( TRUE == isItHandOffTime ) { - setHeaterDutyCycle( heater, dutyCycle ); + //setHeaterDutyCycle( heater, dutyCycle ); - heatersStatus[ heater ].initialDutyCycle = dutyCycle; + //heatersStatus[ heater ].initialDutyCycle = dutyCycle; //TODO do we need this? state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; } - // Check if the heater is requested to be off if ( FALSE == heatersStatus[ heater ].isHeaterOn ) { setHeaterDutyCycle( heater, HEATERS_MIN_DUTY_CYCLE ); @@ -643,7 +640,7 @@ state = HEATER_EXEC_STATE_RAMP_TO_TARGET; } // Check if it is the control time - else if ( ++heatersStatus[ heater ].controlTimerCounter > HEATERS_CONTROL_STATE_CHECK_INTERVAL_COUNT ) + /*else if ( ++heatersStatus[ heater ].controlTimerCounter > HEATERS_CONTROL_STATE_CHECK_INTERVAL_COUNT ) { dutyCycle = heatersStatus[ heater ].dutycycle; @@ -667,7 +664,7 @@ setHeaterDutyCycle( heater, dutyCycle ); heatersStatus[ heater ].controlTimerCounter = 0; - } + }*/ // Check if the heater is requested to be off if ( FALSE == heatersStatus[ heater ].isHeaterOn ) @@ -758,10 +755,12 @@ heatersStatus[ heater ].hasTargetTempChanged = FALSE; // If the new target flow is less than the measured current flow, it means the new target flow is faster so it needs more heat power - dutyCycle = ( getMeasuredROFlowRate() < heatersStatus[ heater ].targetROFlow ? HEATERS_MAX_DUTY_CYCLE : HEATERS_MIN_DUTY_CYCLE ); + //dutyCycle = ( getMeasuredROFlowRate() < heatersStatus[ heater ].targetROFlow ? HEATERS_MAX_DUTY_CYCLE : HEATERS_MIN_DUTY_CYCLE ); // Go back to ramp state - setHeaterDutyCycle( heater, dutyCycle ); + //setHeaterDutyCycle( heater, dutyCycle ); + + //setHeaterDutyCycle( heater, 100.00 ); } /*if ( DG_PRIMARY_HEATER == heater ) @@ -993,7 +992,16 @@ } } +static void checkHeaterOnStatus( DG_HEATERS_T heater ) +{ + if ( FALSE == heatersStatus[ heater ].isHeaterOn ) + { + setHeaterDutyCycle( heater, HEATERS_MIN_DUTY_CYCLE ); + //state = HEATER_EXEC_STATE_NOT_RUNNING; + } +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/