Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r1644c24b0b51661ceaba579e5ebee0d1d5bad85f -r2c61c4a7037fd5a22ecbcd5732d91d3166ef8c5b --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 1644c24b0b51661ceaba579e5ebee0d1d5bad85f) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 2c61c4a7037fd5a22ecbcd5732d91d3166ef8c5b) @@ -30,7 +30,7 @@ #include "TaskGeneral.h" #include "TaskPriority.h" #include "TDInterface.h" -#include "TemperatureSensors.h" +#include "Temperature.h" #include "Timers.h" #include "Utilities.h" @@ -41,21 +41,25 @@ // ********** private definitions ********** -#define AC_HEATER_TX_MAX_DUTY_CYCLE 0.50F ///< AC Heater Treatement mode max duty cycle (50% of 1400W : 700W ) or ON state -#define AC_HEATER_HEAT_MAX_DUTY_CYCLE 0.70F ///< AC Heater heat disinfect mode max duty cycle (70% of 1400W : 980W ) or ON state +#define AC_HEATER_TX_MAX_DUTY_CYCLE 0.50F ///< AC Heater treatment mode max duty cycle (50% of 1400W : 700W ) +#define AC_HEATER_HEAT_MAX_DUTY_CYCLE 0.70F ///< AC Heater heat disinfect mode max duty cycle (70% of 1400W : 980W ) #define AC_HEATER_MAX_DUTY_CYCLE 1.0F ///< AC Heater max duty cycle (100.0%) or ON state #define DC_HEATER_MAX_DUTY_CYCLE 1.0F ///< DC Heater max duty cycle (100%) or ON state #define HEATERS_MIN_DUTY_CYCLE 0.0F ///< Heaters minimum duty cycle (0.00%) or OFF state #define HEATERS_DISINFECT_TEMPERATURE_DRIFT_C 3.0F ///< Heaters disinfect temperature drift in C. #define HEATERS_ZERO_DELTA_TEMP_C 0.0F ///< Heaters zero delta temperature in C. #define HEATERS_DUTY_CYCLE_CONVERSION_FACTOR 100.0F ///< Heaters duty cycle 0: OFF, 100: 100% duty cycle. #define HEATERS_ZERO_EFFICIENCY 0.0F ///< Zero heater efficiency +#define HEATER_CNTL_TRANSFER_DELTA_TEMP_C 0.50F ///< AC heater delta temperature to transfer control from open to close loop #define D5_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control -#define D5_HEAT_TX_P_COEFFICIENT 0.015F ///< P Term for AC primary heater control during treatment mode. -#define D5_HEAT_TX_I_COEFFICIENT 0.0021F ///< I Term for AC primary heater control during treatment mode. +//#define D5_HEAT_TX_P_COEFFICIENT 0.050F ///< P Term for AC primary heater control during treatment mode. +//#define D5_HEAT_TX_I_COEFFICIENT 0.015F ///< I Term for AC primary heater control during treatment mode. -#define D45_HEAT_P_COEFFICIENT 0.35F ///< P Term for trimmer heater control. +#define D5_HEAT_TX_P_COEFFICIENT 0.035F ///< P Term for AC primary heater control during treatment mode. +#define D5_HEAT_TX_I_COEFFICIENT 0.004F ///< I Term for AC primary heater control during treatment mode. + +#define D45_HEAT_P_COEFFICIENT 0.20F ///< P Term for trimmer heater control. #define D45_HEAT_I_COEFFICIENT 0.05F ///< I Term for trimmer heater control. #define D45_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control @@ -69,8 +73,10 @@ #define HEATERS_MAX_OPERATING_VOLTAGE_V 24.0F ///< Heaters max operating voltage in volts. #define HEATERS_VOLTAGE_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Heaters voltage out of range time out in milliseconds. #define HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL 0.2F ///< Heaters max voltage out of range tolerance. +#define D5_HEATER_DEADBAND_CONTROL 0.1F ///< Heater deadband range for conrtol. -#define D5_HEAT_CONTROL_INTERVAL_MS 30000 /// Primary heater control interval in milli seconds +//#define D5_HEAT_CONTROL_INTERVAL_MS 30000 /// Primary heater control interval in milli seconds +#define D5_HEAT_CONTROL_INTERVAL_MS 3000 /// Primary heater control interval in milli seconds #define D5_HEAT_CONTROL_INTERVAL_COUNT ( D5_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Primary heater control interval count. #define D45_HEAT_CONTROL_INTERVAL_MS ( 1 * MS_PER_SECOND ) ///< Trimmer heater control interval in milli seconds #define D45_HEAT_CONTROL_INTERVAL_COUNT ( D45_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Trimmer heater control interval count. @@ -84,7 +90,6 @@ #define AC_HEATER_EFFICIENCY 0.90F ///< Approximated AC heater efficiency to be used in energy calcualtions. #define DC_HEATER_EFFICIENCY 1.0F ///< DC heater efficiency #define D5_HEAT_CONTROL_INTERVAL_START_COUNT ( D5_HEAT_CONTROL_INTERVAL_COUNT - 10 ) ///< AC heater control interval start count to jump feedforward control from open loop. - #define DATA_PUBLISH_COUNTER_START_COUNT 70 ///< Data publish counter start count. //static const F32 HEATERS_VOLTAGE_TOLERANCE_V = HEATERS_MAX_OPERATING_VOLTAGE_V * HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL; ///< Heaters voltage tolerance in volts. @@ -120,6 +125,7 @@ static const F32 WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES = 4184.0F / (F32)SEC_PER_MIN; ///< Water specific heat in J/KgC / 60. static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval. static F32 convertDC; ///< AC Heater converted duty cycle +static F32 lastDialTargetTemperatureSet; ///< last dialysate target temperature set for heater control static BOOL startupHeaterControl; ///< First time control with the energy equation. //For testing @@ -181,6 +187,7 @@ heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; heatersStatus[ D45_HEAT ].controlIntervalCounter = 0; startupHeaterControl = TRUE; + lastDialTargetTemperatureSet = 0.0F; for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { @@ -242,17 +249,25 @@ { BOOL result = FALSE; - if( heater < NUM_OF_DD_HEATERS ) + if ( heater < NUM_OF_DD_HEATERS ) { // Assume the target temperature has not changed heatersStatus[ heater ].hasTargetTempChanged = FALSE; // Check if the requested temperature is within the allowed range - if ( ( targetTemperature >= HEATER_TARGET_TEMPERATURE_MIN ) && ( targetTemperature <= HEATER_TARGET_TEMPERATURE_MAX ) ) + if ( ( ( targetTemperature >= HEATER_TARGET_TEMPERATURE_MIN ) && ( targetTemperature <= HEATER_TARGET_TEMPERATURE_MAX ) ) && + ( lastDialTargetTemperatureSet != targetTemperature ) ) { targetTempC[ heater ].data = targetTemperature; heatersStatus[ heater ].hasTargetTempChanged = TRUE; result = TRUE; + lastDialTargetTemperatureSet = targetTemperature; + + if ( D5_HEAT == heater ) + { + startupHeaterControl = TRUE; + } + } } else @@ -373,12 +388,12 @@ heatersStatus[ heater ].heaterOnState = FALSE; control[ heater ].data = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; - startupHeaterControl = TRUE; //Update control interval counter if ( D5_HEAT == heater ) { heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; + startupHeaterControl = TRUE; } else { @@ -542,14 +557,14 @@ if ( D5_HEAT == heater ) { - measuredTemperature = getTemperatureValue( D4_TEMP ); + measuredTemperature = getD4AverageTemperature(); if ( DD_MODE_HEAT != opMode ) { - F32 deltaTempC = targetTemperature - measuredTemperature; - F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); + F32 deltaTempC = measuredTemperature - targetTemperature; + F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); - if ( capDeltaTempC <= HEATER_TEMP_CONTROL_TRANSFER ) + if ( capDeltaTempC >= HEATER_CNTL_TRANSFER_DELTA_TEMP_C ) { // Transfer Control to target when delta temp is minimal. state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; @@ -568,7 +583,7 @@ } else { - measuredTemperature = getTemperatureValue( D50_TEMP ); + measuredTemperature = getD50AverageTemperature(); if ( DD_MODE_HEAT != opMode ) { @@ -620,16 +635,14 @@ { if ( D5_HEAT == heater ) { - measuredTemperature = getTemperatureValue( D4_TEMP ); + measuredTemperature = getD4AverageTemperature(); // Inlet temperature post heat exchanger inletTemperature = getTemperatureValue( X6_TEMP ); if ( TRUE == startupHeaterControl ) { startupHeaterControl = FALSE; F32 deltaTempC = targetTemperature - inletTemperature; - //TODO : testing - //F32 deltaTempC = 10.0F; // Hard code for testing, later remove it. F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); F32 flowrate = getTDDialysateFlowrate() / LITER_IN_ML ; F32 feedforward = calculateDutyCycle( flowrate, capDeltaTempC, PRIMARY_HEATER_MAX_PWR_WATTS, AC_HEATER_EFFICIENCY, @@ -639,8 +652,13 @@ } else { - ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT, targetTemperature, measuredTemperature ); - control[ heater ].data = ctrl; + F32 deltaTempC = fabs( targetTemperature - measuredTemperature ); + + if ( deltaTempC >= D5_HEATER_DEADBAND_CONTROL ) + { + ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT, targetTemperature, measuredTemperature ); + control[ heater ].data = ctrl; + } } #ifdef __HEATERS_DEBUG__ U32 i; @@ -653,18 +671,18 @@ } else { - measuredTemperature = getTemperatureValue( D50_TEMP ); + measuredTemperature = getD50AverageTemperature(); ctrl = runPIController( PI_CONTROLLER_ID_D45_HEAT, targetTemperature, measuredTemperature ); control[ heater ].data = ctrl; -#ifdef __HEATERS_DEBUG__ - U32 i; - - for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) - { - pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D45_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); - } -#endif +//#ifdef __HEATERS_DEBUG__ +// U32 i; +// +// for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) +// { +// pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D45_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); +// } +//#endif } heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -838,8 +856,8 @@ { HEATERS_DATA_T data; - data.d5_HeaterDC = getHeaterControl( D5_HEAT ); - data.d45_HeaterDC = getHeaterControl( D45_HEAT ); + data.d5_HeaterDC = getHeaterControl( D5_HEAT ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR; + data.d45_HeaterDC = getHeaterControl( D45_HEAT ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR; data.d5_HeaterTargetTemp = getHeaterTargetTemperature( D5_HEAT ); data.d45_HeaterTargetTemp = getHeaterTargetTemperature( D45_HEAT ); data.d5_HeaterState = heatersStatus[ D5_HEAT ].state;