Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r3dd12fb9d032f85126db82ca48812a4652a5b75f -r5c53288436774f0cf6a24132ace29a64a66d619d --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 3dd12fb9d032f85126db82ca48812a4652a5b75f) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 5c53288436774f0cf6a24132ace29a64a66d619d) @@ -22,6 +22,7 @@ #include "AlarmMgmt.h" #include "DGDefs.h" +#include "FlowSensors.h" #include "Heaters.h" #include "MessageSupport.h" #include "ModeFill.h" @@ -48,8 +49,9 @@ #define HEATERS_MAX_DUTY_CYCLE 1.00F ///< Heaters max duty cycle (100%). #define HEATERS_MIN_DUTY_CYCLE 0.00F ///< Heaters minimum duty cycle (0.00%). #define HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE 0.6F ///< Heaters minimum duty cycle during heat disinfect. -#define HEATERS_MAX_EFFICIENCY 0.0F ///< Heaters minimum efficiency. -#define HEATERS_MIN_EFFICIENCY 1.0F ///< Heaters maximum efficiency. +#define HEATERS_MIN_EST_GAIN 0.2F ///< Heaters minimum estimation gain. +#define HEATERS_MAX_EST_GAIN 5.0F ///< Heaters maximum estimation gain. +#define HEATERS_NEUTRAL_EST_GAIN 1.0F ///< Heaters neutral estimation gain. #define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. @@ -93,7 +95,7 @@ F32 dutycycle; ///< Heater duty cycle. F32 targetFlow; ///< Heater target flow. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. - F32 heaterEfficiency; ///< Heater efficiency during the run. + F32 heaterEstGain; ///< Heater estimation gain during the run. BOOL hasTargetBeenReached; ///< Heater flag to indicate whether the target temperature has been reached. F32 calculatedTemperature; ///< Heater calculated temperature. DG_RESERVOIR_ID_T inactiveRsrvr; ///< Heater inactive reservoir. @@ -148,7 +150,7 @@ heatersStatus[ heater ].dutycycle = 0.0; heatersStatus[ heater ].targetFlow = 0.0; heatersStatus[ heater ].hasTargetTempChanged = FALSE; - heatersStatus[ heater ].heaterEfficiency = 1.0; // Assuming 100% efficiency during initialization until it is updated + heatersStatus[ heater ].heaterEstGain = HEATERS_NEUTRAL_EST_GAIN; heatersStatus[ heater ].hasTargetBeenReached = FALSE; } @@ -333,7 +335,7 @@ { // TODO add the function that gets the flow of the new flow sensor for DG. For now it is assumed that trimmer heater flow sensor // is not 0 so the heater can run if needed - F32 measFlow = ( DG_PRIMARY_HEATER == heater ? getMeasuredROFlowRateLPM() : 50.0 ); + F32 measFlow = ( DG_PRIMARY_HEATER == heater ? getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) /*getMeasuredROFlowRateLPM()*/ : 50.0 ); F32 minFlow = ( DG_PRIMARY_HEATER == heater ? MIN_RO_FLOWRATE_LPM : MIN_RO_FLOWRATE_LPM ); BOOL isFlowLow = ( measFlow < minFlow ? TRUE : FALSE ); @@ -366,8 +368,8 @@ *************************************************************************/ void resetHeatersEfficiency( void ) { - heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = 1.0; - heatersStatus[ DG_TRIMMER_HEATER ].heaterEfficiency = 1.0; + heatersStatus[ DG_PRIMARY_HEATER ].heaterEstGain = HEATERS_NEUTRAL_EST_GAIN; + heatersStatus[ DG_TRIMMER_HEATER ].heaterEstGain = HEATERS_NEUTRAL_EST_GAIN; } /*********************************************************************//** @@ -630,44 +632,47 @@ static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow, BOOL checkEfficiency ) { // Get the primary heater's efficiency and the last fill temperature from the ModeFill - F32 heaterEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency; + F32 heaterEstGain = heatersStatus[ DG_PRIMARY_HEATER ].heaterEstGain; + // Duty cycle = ( 69.73 * flow rate * deltaT / primary heater maximum power ) ^ 1/2 + // Multiply the duty cycle to the heater efficiency + F32 dutyCycle = sqrt( ( WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * fabs( targetTemperature - currentTemperature ) * flow ) / + PRIMARY_HEATERS_MAXIMUM_POWER_WATTS ); #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_HEATERS_EFFICIENCY ) != SW_CONFIG_ENABLE_VALUE ) #endif { if ( TRUE == checkEfficiency ) { + F32 heaterDutyCycle = heatersStatus[ DG_PRIMARY_HEATER ].dutycycle; F32 lastFillTemperature = getLastFillTemperature(); F32 primaryTargetTemperature = heatersStatus[ DG_PRIMARY_HEATER ].targetTemp; + BOOL isTempUnderTarget = ( lastFillTemperature < primaryTargetTemperature ? TRUE : FALSE ); - // If the last fill temperature > target temperature, it means the primary heater overshot the duty cycle - // so with its efficiency is toned down for the next fill cycle - // If the heater under-shoots the duty cycle, the efficiency increases the duty cycle for the next fill cycle - if ( lastFillTemperature - primaryTargetTemperature < NEARLY_ZERO ) + if ( TRUE == isTempUnderTarget ) { - heaterEfficiency -= ( lastFillTemperature - primaryTargetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + if ( heaterDutyCycle < HEATERS_MAX_DUTY_CYCLE ) + { + heaterEstGain += ( primaryTargetTemperature - lastFillTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } } else { - heaterEfficiency += ( primaryTargetTemperature - lastFillTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + if ( heaterDutyCycle > HEATERS_MIN_DUTY_CYCLE ) + { + heaterEstGain -= ( lastFillTemperature - primaryTargetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } } - // Check the heater's efficiency to make sure it is in between 0 and 1 (0 to 100%) - heaterEfficiency = MIN( heaterEfficiency, HEATERS_MAX_EFFICIENCY ); - heaterEfficiency = MAX( heaterEfficiency, HEATERS_MIN_EFFICIENCY ); - - // Update the heaters efficiency - heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = heaterEfficiency; + heaterEstGain = MAX( heaterEstGain, HEATERS_MIN_EST_GAIN ); + heaterEstGain = MIN( heaterEstGain, HEATERS_MAX_EST_GAIN ); + heatersStatus[ DG_PRIMARY_HEATER ].heaterEstGain = heaterEstGain; } } - // Duty cycle = ( 69.73 * flow rate * deltaT / primary heater maximum power ) ^ 1/2 - // Multiply the duty cycle to the heater efficiency - F32 dutyCycle = sqrt( ( WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * fabs( targetTemperature - currentTemperature ) * flow ) / PRIMARY_HEATERS_MAXIMUM_POWER_WATTS ); - dutyCycle = ( heaterEfficiency > NEARLY_ZERO ? dutyCycle * heaterEfficiency : dutyCycle ); - dutyCycle = MIN( dutyCycle, HEATERS_MAX_DUTY_CYCLE ); - dutyCycle = MAX( dutyCycle, HEATERS_MIN_DUTY_CYCLE ); + dutyCycle *= heatersStatus[ DG_PRIMARY_HEATER ].heaterEstGain; + dutyCycle = MIN( dutyCycle, HEATERS_MAX_DUTY_CYCLE ); + dutyCycle = MAX( dutyCycle, HEATERS_MIN_DUTY_CYCLE ); return dutyCycle; } @@ -688,7 +693,7 @@ static F32 calculateTrimmerHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow, BOOL checkEfficiency ) { // Get the primary heater's efficiency and the last fill temperature from the ModeFill - F32 heaterEfficiency = heatersStatus[ DG_TRIMMER_HEATER ].heaterEfficiency; + F32 heaterEfficiency = heatersStatus[ DG_TRIMMER_HEATER ].heaterEstGain; F32 dutyCycle = 0.0; #ifndef _RELEASE_ @@ -800,7 +805,7 @@ data.trimmerTargetTemp = heatersStatus[ DG_TRIMMER_HEATER ].targetTemp; data.primaryHeaterState = heatersStatus[ DG_PRIMARY_HEATER ].state; data.trimmerHeaterState = heatersStatus[ DG_TRIMMER_HEATER ].state; - data.primaryEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency * 100; + data.primaryEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEstGain * 100; data.primaryCalcTargetTemp = heatersStatus[ DG_PRIMARY_HEATER ].calculatedTemperature; data.trimmerCalcCurrentTemp = heatersStatus[ DG_TRIMMER_HEATER ].calculatedTemperature; broadcastData( MSG_ID_DG_HEATERS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( HEATERS_DATA_T ) );