Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r8c5ca1982c53f4702c6f019ce9bcfedb9e513548 -r78842b478a83315eda5d877a99b16f3b899b7727 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 8c5ca1982c53f4702c6f019ce9bcfedb9e513548) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 78842b478a83315eda5d877a99b16f3b899b7727) @@ -40,8 +40,9 @@ // ********** private definitions ********** -#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_MAX_DUTY_CYCLE 1.00F ///< Heaters max duty cycle (100%) or ON state +#define HEATERS_MIN_DUTY_CYCLE 0.00F ///< Heaters minimum duty cycle (0.00%) or OFF state +#define PRIMARY_HEATER_ON 1.00F ///< Primary heater ON control #define HEATERS_DISINFECT_DUTY_CYCLE 0.80F ///< Heaters disinfect cycle. #define HEATERS_DISINFECT_TRANSFER_DUTY_CYCLE 0.60F ///< Heaters disinfect transfer duty cycle. #define HEATERS_DISINFECT_TEMPERATURE_DRIFT_C 3.0F ///< Heaters disinfect temperature drift in C. @@ -55,6 +56,7 @@ #define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. +#define HEATER_TEMP_CONTROL_TOLERANCE 2.0F ///< Primary Heater temp tolerance for ON/Off control #define HEATER_TARGET_TEMPERATURE_MIN 10.0F ///< Minimum allowed target temperature for the heaters. #define HEATER_TARGET_TEMPERATURE_MAX 90.0F ///< Maximum allowed target temperature for the heaters. @@ -78,7 +80,7 @@ HEATERS_STATE_T state; ///< Heater state. BOOL startHeaterSignal; ///< Heater start indication flag. BOOL heaterOnState; ///< Heater on/off status flag. - OVERRIDE_F32_T dutyCycle; ///< Heater duty cycle. + OVERRIDE_F32_T control; ///< Heater control ( Primary : On/Off, Trimmer : Dutycycle). F32 targetFlowLPM; ///< Heater target flow in L/min to calculate the duty cycle. F32 nomTargetFlowLPM; ///< Heater nominal target flow in L/min. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. @@ -106,8 +108,8 @@ static HEATERS_STATE_T handleHeaterStateControlToTarget( DD_HEATERS_T heater ); static HEATERS_STATE_T handleHeaterStateControlToDisinfectTarget( DD_HEATERS_T heater ); -static void setHeaterDutyCycle( DD_HEATERS_T heater ); -static F32 getHeaterDutyCycle( DD_HEATERS_T heater ); +static void setHeaterControl( DD_HEATERS_T heater ); +static F32 getHeaterControl( DD_HEATERS_T heater ); static void publishHeatersData( void ); //static void monitorHeatersVoltage( void ); @@ -130,10 +132,10 @@ heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; heatersStatus[ heater ].startHeaterSignal = FALSE; heatersStatus[ heater ].heaterOnState = FALSE; - heatersStatus[ heater ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; - heatersStatus[ heater ].dutyCycle.ovData = HEATERS_MIN_DUTY_CYCLE; - heatersStatus[ heater ].dutyCycle.ovInitData = HEATERS_MIN_DUTY_CYCLE; - heatersStatus[ heater ].dutyCycle.override = OVERRIDE_RESET; + heatersStatus[ heater ].control.data = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].control.ovData = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].control.ovInitData = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].control.override = OVERRIDE_RESET; heatersStatus[ heater ].targetFlowLPM = 0.0F; heatersStatus[ heater ].nomTargetFlowLPM = 0.0F; heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -268,11 +270,11 @@ { heatersStatus[ heater ].startHeaterSignal = FALSE; heatersStatus[ heater ].heaterOnState = FALSE; - heatersStatus[ heater ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].control.data = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; // update duty cycle - setHeaterDutyCycle( heater ); + setHeaterControl( heater ); } else { @@ -422,23 +424,40 @@ static HEATERS_STATE_T handleHeaterStateRampToTarget( DD_HEATERS_T heater ) { HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; - F32 dutyCycle = 0.0F; + F32 control = 0.0F; DD_OP_MODE_T opMode = getCurrentOperationMode(); - if ( DD_MODE_HEAT != opMode ) + if ( DD_PRIMARY_HEATER == heater ) { - dutyCycle = ( ( heatersStatus[ heater ].targetTempC / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; - state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + if ( DD_MODE_HEAT != opMode ) + { + heatersStatus[ heater ].control.data = PRIMARY_HEATER_ON; + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + } + else + { + // TODO : Calculate required duty cycle + state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; + } } else { - // TODO : Calculate required duty cycle - state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; + if ( DD_MODE_HEAT != opMode ) + { + control = ( ( heatersStatus[ heater ].targetTempC / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + } + else + { + // TODO : Calculate required duty cycle + state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; + } + + // Update the duty cycle + heatersStatus[ heater ].control.data = control; } - // Update the duty cycle - heatersStatus[ heater ].dutyCycle.data = dutyCycle; - setHeaterDutyCycle( heater ); + setHeaterControl( heater ); return state; } @@ -458,20 +477,39 @@ HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; F32 targetTemperature = heatersStatus[ heater ].targetTempC; F32 measuredTemperature = 0.0F; - F32 dutyCycle = 0.0F; + F32 control = 0.0F; if( ++heatersStatus[ heater ].controlIntervalCounter > PRIMARY_HEATER_CONTROL_INTERVAL_COUNT ) { switch ( heater ) { case DD_PRIMARY_HEATER: measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_HYDRAULICS_PRIMARY_HEATER ); - dutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, targetTemperature, measuredTemperature ); + if ( ( measuredTemperature >= ( targetTemperature - HEATER_TEMP_CONTROL_TOLERANCE ) ) && + ( measuredTemperature <= ( targetTemperature + HEATER_TEMP_CONTROL_TOLERANCE ) ) ) + { + // Turn off heater + heatersStatus[ heater ].control.data = HEATERS_MIN_DUTY_CYCLE; + } + else + { + // Turn On heater + heatersStatus[ heater ].control.data = PRIMARY_HEATER_ON; + } + + //control = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, targetTemperature, measuredTemperature ); break; case DD_TRIMMER_HEATER: measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_TRIMMER_HEATER ); - dutyCycle = runPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, targetTemperature, measuredTemperature ); + //control = runPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, targetTemperature, measuredTemperature ); + if ( targetTemperature > 0.0F ) + { + control = HEATERS_MAX_DUTY_CYCLE - ( measuredTemperature / targetTemperature ); + control = control < 0.0 ? HEATERS_MIN_DUTY_CYCLE: control; + } + + heatersStatus[ heater ].control.data = ( control * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; break; default: @@ -480,10 +518,9 @@ } heatersStatus[ heater ].hasTargetTempChanged = FALSE; - heatersStatus[ heater ].dutyCycle.data = ( dutyCycle * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; heatersStatus[ heater ].controlIntervalCounter = 0; - setHeaterDutyCycle( heater ); + setHeaterControl( heater ); } return state; @@ -505,37 +542,37 @@ //TODO : update dutycycle for the heat disinfect state - setHeaterDutyCycle( DD_TRIMMER_HEATER ); - setHeaterDutyCycle( DD_PRIMARY_HEATER ); + setHeaterControl( DD_TRIMMER_HEATER ); + setHeaterControl( DD_PRIMARY_HEATER ); return state; } /*********************************************************************//** * @brief - * The setHeaterDutyCycle function sets the duty cycle of a heater. - * @details \b Inputs: dutyCycle + * The setHeaterControl function sets the duty cycle of a heater. + * @details \b Inputs: control * @details \b Outputs: FPGA heater control * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid heater ID * is selected. * @param heater: The heater Id that its duty cycle is set * @return none *************************************************************************/ -static void setHeaterDutyCycle( DD_HEATERS_T heater ) +static void setHeaterControl( DD_HEATERS_T heater ) { if ( heater < NUM_OF_DD_HEATERS ) { - F32 duty; + F32 control; - duty = getHeaterDutyCycle( heater ); + control = getHeaterControl( heater ); if ( DD_PRIMARY_HEATER == heater ) { - setFPGAPrimaryHeaterPWMControl( (U08)duty ); + setFPGACPrimaryHeaterOnOffControl( (BOOL)control ); } else { - setFPGATrimmerHeaterPWMControl( (U08)duty ); + setFPGATrimmerHeaterPWMControl( (U08)control ); } } else @@ -546,15 +583,15 @@ /*********************************************************************//** * @brief - * The getHeaterDutyCycle function returns the heater's duty cycle. + * The getHeaterControl function returns the heater's duty cycle. * @details \b Inputs: heaterStatus * @details \b Outputs: none * @param heater: The heater Id to get the duty cycle. * @return PWM duty cycle for the given heater *************************************************************************/ -static F32 getHeaterDutyCycle( DD_HEATERS_T heater ) +static F32 getHeaterControl( DD_HEATERS_T heater ) { - F32 duty = getF32OverrideValue( &heatersStatus[ heater ].dutyCycle ); + F32 duty = getF32OverrideValue( &heatersStatus[ heater ].control ); return duty; } @@ -576,8 +613,8 @@ // F32 trimmerVoltage = getMonitoredLineLevel( MONITORED_LINE_24V_GND_TRIM_HTR_V ); // // // Voltage to PWM is reverse. If PWM = 0 -> V = 24V -// F32 mainPriDC = getHeaterDutyCycle( DD_PRIMARY_HEATER ); -// F32 trimmerDC = getHeaterDutyCycle( DD_TRIMMER_HEATER ); +// F32 mainPriDC = getHeaterControl( DD_PRIMARY_HEATER ); +// F32 trimmerDC = getHeaterControl( DD_TRIMMER_HEATER ); // // // The expected voltage is the inverse of the duty cycle // F32 mainPriExpectedVoltage = HEATERS_MAX_OPERATING_VOLTAGE_V * ( 1.0F - mainPriDC ); @@ -615,8 +652,8 @@ { HEATERS_DATA_T data; - data.mainPrimayHeaterDC = getHeaterDutyCycle( DD_PRIMARY_HEATER ) * FRACTION_TO_PERCENT_FACTOR; - data.trimmerHeaterDC = getHeaterDutyCycle( DD_TRIMMER_HEATER ) * FRACTION_TO_PERCENT_FACTOR; + data.mainPrimayHeaterDC = getHeaterControl( DD_PRIMARY_HEATER ); + data.trimmerHeaterDC = getHeaterControl( DD_TRIMMER_HEATER ); data.primaryTargetTemp = heatersStatus[ DD_PRIMARY_HEATER ].targetTempC; data.trimmerTargetTemp = heatersStatus[ DD_TRIMMER_HEATER ].targetTempC; data.primaryHeaterState = heatersStatus[ DD_PRIMARY_HEATER ].state; @@ -665,7 +702,7 @@ *************************************************************************/ BOOL testHeaterDutyCycleOverride( MESSAGE_T *message ) { - BOOL result = f32ArrayOverride( message, &heatersStatus[0].dutyCycle, NUM_OF_DD_HEATERS - 1 ); + BOOL result = f32ArrayOverride( message, &heatersStatus[0].control, NUM_OF_DD_HEATERS - 1 ); return result; }