Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -re803f3e6d135641015dc78e2aeac0a5489c9492c -rae31b4c999dccae70fb40fb9d98a4380ce2c7415 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e803f3e6d135641015dc78e2aeac0a5489c9492c) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision ae31b4c999dccae70fb40fb9d98a4380ce2c7415) @@ -1,23 +1,24 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file Heaters.c * * @author (last) Vinayakam Mani -* @date (last) 07-Oct-2024 +* @date (last) 03-Mar-2026 * * @author (original) Vinayakam Mani -* @date (original) 07-Oct-2024 +* @date (original) 11-Oct-2024 * ***************************************************************************/ #include // Used for mathematical operations #include "Conductivity.h" +#include "ConductivityTeensy.h" #include "FpgaDD.h" #include "Heaters.h" #include "Level.h" @@ -41,6 +42,7 @@ */ // ********** private definitions ********** + #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 @@ -83,7 +85,7 @@ #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. -#define D5_TARGET_TEMP_ADJUST_INTERVAL_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature +#define D5_TARGET_TEMP_ADJUST_INTERVAL_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Adjust primary target temperature #define PRIMARY_HEATER_MAX_PWR_WATTS 1400.0F ///< AC Primary Heater Max Power consumeption in Watts #define TX_PRIMARY_HEATER_MAX_PWR_WATTS 700.0F ///< Estimated power to be supplied to the primary heater during treatement mode #define HEAT_PRIMARY_HEATER_MAX_PWR_WATTS 980.0F ///< Estimated power to be supplied to the primary heater during heat disinfect mode @@ -120,6 +122,8 @@ F32 temperature; ///< Temperature range ( 10.0 to 90.0 deg ) } HEATER_START_CMD_PAYLOAD_T; +// ********** private data ********** + static HEATER_STATUS_T heatersStatus[ NUM_OF_DD_HEATERS ]; ///< Heaters status. static OVERRIDE_F32_T targetTempC[ NUM_OF_DD_HEATERS ]; ///< Heater target temperature. static OVERRIDE_F32_T control[ NUM_OF_DD_HEATERS ]; ///< Heater control ( Primary : On/Off, Trimmer : Dutycycle). @@ -128,18 +132,19 @@ static U32 dataPublicationTimerCounter; ///< Data publication timer counter. static U32 primaryTargetTempAdjCounter; ///< Primary target temperature adjustment counter. static BOOL isTargetTempAdjusted; ///< Flag indicating that target temperature is adjusted -static U32 adjustedPrimaryTargetTemp; ///< Adjusted primary target temperature +static F32 adjustedPrimaryTargetTemp; ///< Adjusted primary target temperature static BOOL isDialyzerTempFeedbackEnabled; ///< Flag indicating enable/disable the dilayser temp ( D28) based feedback adjustment 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 F32 lastDialTargetTemperatureSet[ NUM_OF_DD_HEATERS ]; ///< last dialysate target temperature set for heater control static BOOL startupHeaterControl; ///< First time control with the energy equation. //For testing #ifdef __HEATERS_DEBUG__ static F32 pIControlSignal[ NUM_OF_CONTROLLER_SIGNAL ]; #endif + // ********** private function prototypes ********** static HEATERS_STATE_T handleHeaterStateOff( DD_HEATERS_T heater ); @@ -196,7 +201,8 @@ heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; heatersStatus[ D45_HEAT ].controlIntervalCounter = 0; startupHeaterControl = TRUE; - lastDialTargetTemperatureSet = 0.0F; + lastDialTargetTemperatureSet[ D5_HEAT ] = 0.0F; + lastDialTargetTemperatureSet[ D45_HEAT ] = 0.0F; primaryTargetTempAdjCounter = 0; adjustedPrimaryTargetTemp = 0.0F; isTargetTempAdjusted = FALSE; @@ -269,18 +275,17 @@ // Check if the requested temperature is within the allowed range if ( ( ( targetTemperature >= HEATER_TARGET_TEMPERATURE_MIN ) && ( targetTemperature <= HEATER_TARGET_TEMPERATURE_MAX ) ) && - ( lastDialTargetTemperatureSet != targetTemperature ) ) + ( lastDialTargetTemperatureSet[ heater ] != targetTemperature ) ) { targetTempC[ heater ].data = targetTemperature; heatersStatus[ heater ].hasTargetTempChanged = TRUE; result = TRUE; - lastDialTargetTemperatureSet = targetTemperature; + lastDialTargetTemperatureSet[ heater ] = targetTemperature; if ( D5_HEAT == heater ) { startupHeaterControl = TRUE; } - } } else @@ -400,7 +405,17 @@ if ( ++primaryTargetTempAdjCounter >= D5_TARGET_TEMP_ADJUST_INTERVAL_MS ) { F32 targetTempfromTD = getTDTargetDialysateTemperature(); - F32 measuredTempAtDialyzer = getConductivityTemperatureValue( D27_COND ); + F32 measuredTempAtDialyzer = 0.0F; + + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) != TRUE ) + { + measuredTempAtDialyzer = getTeensyConductivityTemperatureValue( D27_COND ); + } + else + { + measuredTempAtDialyzer = getConductivityTemperature( D27_COND ); + } + F32 calcTargetTemp = getHeaterTargetTemperature( D5_HEAT ); F32 dialysateFlowrate = getTDDialysateFlowrate(); F32 deltaTempC = targetTempfromTD - measuredTempAtDialyzer; @@ -738,7 +753,7 @@ { measuredTemperature = getD4AverageTemperature(); // Inlet temperature post heat exchanger - inletTemperature = getTemperatureValue( X6_TEMP ); + inletTemperature = getTemperatureValue( D78_TEMP ); if ( TRUE == startupHeaterControl ) { @@ -769,31 +784,31 @@ control[ heater ].data = ctrl; } } -#ifdef __HEATERS_DEBUG__ - U32 i; - - for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) - { - pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D5_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); - } -#endif - } - else - { - 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 ); +// pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D5_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); // } //#endif } + else + { + 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 + } + heatersStatus[ heater ].hasTargetTempChanged = FALSE; heatersStatus[ heater ].controlIntervalCounter = 0; @@ -842,6 +857,9 @@ F32 control = getHeaterControl( heater ); F32 period = getHeaterPWMPeriod ( heater ); + //Make sure PWM control is enabled all time + setFPGAD5HeaterPWMEnableControl( TRUE ); + if ( D5_HEAT == heater ) { //Convert duty cycle into LowState and multiply by period