Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r50144ec3e96785cf76d5bfd22ee65029c82e732b -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 50144ec3e96785cf76d5bfd22ee65029c82e732b) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -57,7 +57,7 @@ static U32 balChamberValveClosePeriod; ///< Close balancing chamber valves with the defined time prior switching state. static U32 currentBalChamberSwitchingCounter; ///< Counter (in task interval) to monitor the timing spent during balancing chamber fill/drain operation. static BOOL isBalChamberFillInProgress; ///< Flag indicating balancing chamber fill/drain is in progress. -static BOOL isPressureStalbilizedDuringFill; ///< Flag indicating that the pressure is stablized due to fill complete. +static BOOL isPressureStabilizedDuringFill; ///< Flag indicating that the pressure is stabilized due to fill complete. static BAL_CHAMBER_SW_STATE_T balChamberSWState; ///< Current balancing chamber switching state ( state 1 or state 2). static U32 balChamberDataPublicationTimerCounter; ///< Used to schedule balancing chamber data publication to CAN bus. static U32 balChamberFillPressureDropCounter; ///< Counter to check balancing chamber valves opened and there by pressure drop is seen. @@ -116,7 +116,7 @@ balChamberValveClosePeriod = 0; isBalChamberFillInProgress = FALSE; currentBalChamberSwitchingCounter = 0; - isPressureStalbilizedDuringFill = FALSE; + isPressureStabilizedDuringFill = FALSE; lastTdDialysateFlowrate = 0.0F; balChamberDataPublicationTimerCounter = 0; balChamberFillPressureDropCounter = 0; @@ -407,7 +407,7 @@ BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE1_FILL_START; currentBalChamberSwitchingCounter = 0; isBalChamberFillInProgress = FALSE; - isPressureStalbilizedDuringFill = FALSE; + isPressureStabilizedDuringFill = FALSE; isPressureDroppedDuringFill = FALSE; balChamberSWState = BAL_CHAMBER_SW_STATE1; @@ -416,6 +416,9 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + // Check fresh and spent dialysate pressure in range or BC switch only flag set if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || @@ -506,7 +509,7 @@ * The handleBalChamberState1ValvesClose function check for the balancing chamber * fill complete and close the currently opened valves. * @details \b Inputs: currentBalChamberSwitchingCounter, spent and fresh dialysate pressure - * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @details \b Outputs: isPressureStabilizedDuringFill,isBalChamberFillInProgress * @return next balancing chamber state. *************************************************************************/ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState1ValvesClose( void ) @@ -517,26 +520,19 @@ spentDialPressure = getFilteredPressure( D51_PRES ); // Check fresh and spent dialysate pressure back in range to indicate fill complete. - if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && + ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) { - if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && - ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) + if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) { - if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) - { - // stabilized pressure indicating fill is complete - isPressureStalbilizedDuringFill = TRUE; - } + // stabilized pressure indicating fill is complete + isPressureStabilizedDuringFill = TRUE; } } - else - { - isPressureStalbilizedDuringFill = FALSE; - } // Switching time met or pressure in range, close valves if ( ( currentBalChamberSwitchingCounter >= balChamberValveClosePeriod ) || - ( TRUE == isPressureStalbilizedDuringFill ) ) + ( TRUE == isPressureStabilizedDuringFill ) ) { // close the state 1 opened valves valveControlForBCState1FillEnd(); @@ -580,7 +576,7 @@ // When fill initiated, pressure is not dropped to the expected range, possible valve failures. SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_PRESSURE_DROP_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); } - else if ( TRUE != isPressureStalbilizedDuringFill ) + else if ( TRUE != isPressureStabilizedDuringFill ) { // Alarm when switching time expired, but still pressure not in range which indicates fill is not yet completed. SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_END_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); @@ -621,7 +617,7 @@ BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE2_FILL_START; currentBalChamberSwitchingCounter = 0; isBalChamberFillInProgress = FALSE; - isPressureStalbilizedDuringFill = FALSE; + isPressureStabilizedDuringFill = FALSE; isPressureDroppedDuringFill = FALSE; balChamberSWState = BAL_CHAMBER_SW_STATE2; @@ -630,6 +626,9 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + // Check fresh and spent dialysate pressure in range if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || @@ -669,7 +668,7 @@ * The handleBalChamberState2ValvesClose function check for the balancing chamber * fill complete and close the currently opened valves. * @details \b Inputs: currentBalChamberSwitchingCounter, spent and fresh dialysate pressure - * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @details \b Outputs: isPressureStabilizedDuringFill,isBalChamberFillInProgress * @return next balancing chamber state. *************************************************************************/ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2ValvesClose( void ) @@ -680,26 +679,19 @@ spentDialPressure = getFilteredPressure( D51_PRES ); // Check fresh and spent dialysate pressure back in range to indicate fill complete. - if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && + ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) { - if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && - ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) + if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) { - if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) - { - // stabilized pressure indicating fill is complete - isPressureStalbilizedDuringFill = TRUE; - } + // stabilized pressure indicating fill is complete + isPressureStabilizedDuringFill = TRUE; } } - else - { - isPressureStalbilizedDuringFill = FALSE; - } // Check switching cycle time or pressure check for valve closure if ( ( currentBalChamberSwitchingCounter >= balChamberValveClosePeriod ) || - ( TRUE == isPressureStalbilizedDuringFill ) ) + ( TRUE == isPressureStabilizedDuringFill ) ) { // close the valves valveControlForBCState2FillEnd(); @@ -717,7 +709,7 @@ * The handleBalChamberState2FillEnd function check for the balancing chamber * switching period complete and transition to next state. * @details \b Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod - * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @details \b Outputs: isPressureStabilizedDuringFill,isBalChamberFillInProgress * @details \b Alarm: ALARM_ID_DD_BC_STATE2_FILL_PRESSURE_DROP_OUT_OF_RANGE * when pressure is not in range during balacing chamber state 2 fill in progress. * @details \b Alarm: ALARM_ID_DD_BC_STATE2_FILL_END_PRESSURE_OUT_OF_RANGE @@ -744,7 +736,7 @@ // When fill initiated, pressure is not dropped to the expected range, possible valve failures. SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_PRESSURE_DROP_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); } - else if ( TRUE != isPressureStalbilizedDuringFill ) + else if ( TRUE != isPressureStabilizedDuringFill ) { // Alarm when switching time expired, but still pressure not in range which indicates fill is not completed. SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_END_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); @@ -904,7 +896,7 @@ data.balChamberSwPeriod = balChamberSwitchingPeriod; data.isBalChamberFillInProgress = isBalChamberFillInProgress; data.currentBalChamberSwitchingCounter = currentBalChamberSwitchingCounter; - data.isPressureStalbilizedDuringFill = isPressureStalbilizedDuringFill; + data.isPressureStabilizedDuringFill = isPressureStabilizedDuringFill; data.balChamberSWOnlyState = balanceChamberSwitchingOnly; broadcastData( MSG_ID_DD_BAL_CHAMBER_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( BAL_CHAMBER_DATA_T ) ); Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r25dfec9cbd60f1fc9f22c00342a1d009c95533ff -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 25dfec9cbd60f1fc9f22c00342a1d009c95533ff) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -7,8 +7,8 @@ * * @file Heaters.c * -* @author (last) Vinayakam Mani -* @date (last) 18-Sep-2025 +* @author (last) Michael Garthwaite +* @date (last) 13-Jan-2026 * * @author (original) Vinayakam Mani * @date (original) 11-Oct-2024 @@ -405,7 +405,11 @@ if ( ++primaryTargetTempAdjCounter >= D5_TARGET_TEMP_ADJUST_INTERVAL_MS ) { F32 targetTempfromTD = getTDTargetDialysateTemperature(); +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + F32 measuredTempAtDialyzer = getTeensyConductivityTemperatureValue( D27_COND ); +#else F32 measuredTempAtDialyzer = getConductivityTemperatureValue( D27_COND ); +#endif F32 calcTargetTemp = getHeaterTargetTemperature( D5_HEAT ); F32 dialysateFlowrate = getTDDialysateFlowrate(); F32 deltaTempC = targetTempfromTD - measuredTempAtDialyzer; Index: firmware/App/Controllers/Ultrafiltration.c =================================================================== diff -u -r830213bc6dcc1a684610caf78c79d55f2cb41e93 -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision 830213bc6dcc1a684610caf78c79d55f2cb41e93) +++ firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -104,9 +104,22 @@ // Calculate UF volume and determine UF pause/run updateUFRequest(); - // Compensate balancing error at defined interval - UpdateUFCompensation(); + // Trimmer heater enabled, hence UF temp compensation is optional + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_UF_TEMP_COMPENSATION ) == TRUE ) + { + // Compensate balancing error at defined interval + UpdateUFCompensation(); + } + else if ( TRUE == isUFRateUpdated ) + { + //get updated UF rate + compUFrate = getTDUFRate(); + // Update UF rate + setConcentratePumpTargetSpeed( D76_PUMP, compUFrate, DOSING_CONT_VOLUME ); + isUFRateUpdated = FALSE; + } + // execute current ultrafiltration exec state switch ( ufExecState ) { @@ -181,10 +194,10 @@ /*********************************************************************//** * @brief - * The updateUFRequest function updates the ultrafiltration rate per iteration - * and of the ultrafiltration. + * The updateUFRequest function updates the ultrafiltration requested + * flag to true or false based on the conditions. * @details \b Inputs: TD Uf rate, TD Dialysate flow rate and bypass flag - * @details \b Outputs: ufVolumeperIteration , isUltrafiltrationRequested + * @details \b Outputs: isUltrafiltrationRequested * @return none. *************************************************************************/ static void updateUFRequest( void ) Index: firmware/App/DDCommon.h =================================================================== diff -u -r0094b61e6ec21feb06b7a04e3d230abdd79a459c -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 0094b61e6ec21feb06b7a04e3d230abdd79a459c) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -7,8 +7,8 @@ * * @file DDCommon.h * -* @author (last) Vinayakam Mani -* @date (last) 14-Nov-2025 +* @author (last) Michael Garthwaite +* @date (last) 02-Feb-2026 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 @@ -25,7 +25,7 @@ #define DD_VERSION_MAJOR 0 #define DD_VERSION_MINOR 0 #define DD_VERSION_MICRO 0 -#define DD_VERSION_BUILD 35 +#define DD_VERSION_BUILD 41 // ********** development build switches ********** @@ -45,9 +45,6 @@ //Uncomment below once characterization/study completed //#define ENABLE_ALARM_2 -//Uncomment below for spent chamber filling -//#define __SPENT_CHAMBER_FILL__ 1 - //Uncomment below for bicarb chamber filling //#define __BICARB_CHAMBER_FILL__ 1 @@ -57,6 +54,8 @@ //Uncomment below to disable heaters debug message #define __HEATERS_DEBUG__ 1 +//Uncomment below to disable Teensy conductivity driver +#define __TEENSY_CONDUCTIVITY_DRIVER__ 1 #include #include Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -rbd896114f304304a7096b30b2a85067a64645e82 -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision bd896114f304304a7096b30b2a85067a64645e82) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -226,6 +226,10 @@ setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + //Turn on Trimmer heater + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + startHeater( D45_HEAT ); + //Testing : Enable close loop once testing is complete //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); @@ -255,6 +259,10 @@ setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + //Turn on Trimmer heater + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + startHeater( D45_HEAT ); + //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); @@ -289,6 +297,8 @@ setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); setD28TempFeedbackControl( TRUE ); startHeater( D5_HEAT ); + // Stop trimmer heater + stopHeater( D45_HEAT ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_FILL_RPM, TRUE ); Index: firmware/App/Monitors/Temperature.c =================================================================== diff -u -r25dfec9cbd60f1fc9f22c00342a1d009c95533ff -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Monitors/Temperature.c (.../Temperature.c) (revision 25dfec9cbd60f1fc9f22c00342a1d009c95533ff) +++ firmware/App/Monitors/Temperature.c (.../Temperature.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -7,16 +7,20 @@ * * @file Temperature.c * -* @author (last) “rkallala” -* @date (last) 19-Jan-2026 +* @author (last) Michael Garthwaite +* @date (last) 02-Feb-2026 * * @author (original) Vinayakam Mani * @date (original) 25-Sep-2024 * ***************************************************************************/ #include "BalancingChamber.h" +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ +#include "ConductivityTeensy.h" +#else #include "ConductivitySensors.h" +#endif #include "Conductivity.h" #include "Flow.h" #include "Messaging.h" @@ -43,6 +47,7 @@ #define TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Temperature sensors FPGA error timeout in milliseconds. #define D4_TEMP_MOVING_AVG_NUM_OF_SAMPLES 50 ///< D4 temperature sensor moving average number of samples. #define D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES 50 ///< D50 temperature sensor moving average number of samples. +#define D99_TEMP_MOVING_AVG_NUM_OF_SAMPLES 50 ///< D99 temperature sensor moving average number of samples #define DATA_PUBLISH_COUNTER_START_COUNT 30 ///< Data publish counter start count. #define DIAL_TEMP_MOVING_AVG_NUM_OF_SAMPLES 30 ///< Dialysate temperature sensors moving average number of samples. #define D28_D30_DATA_COLLECTION_TIME_MS ( 1 * MS_PER_SECOND ) ///< Dialysate temperature sensors data collection time in milliseconds. @@ -100,6 +105,13 @@ static U32 d50TempSamplesNextIndex; ///< D50 temperature sample next index number. static U32 d50TempCount; ///< D50 Number of samples in average buffer. +static F32 d99TempAvgC; ///< D99 temperature average in C. +static F32 d99TempRunningSumC; ///< D99 temperature running sum in C. +static F32 d99TempSamplesC[ D99_TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< D99 temperature samples array in C. +static U32 d99TempSamplesNextIndex; ///< D99 temperature sample next index number. +static U32 d99TempCount; ///< D99 Number of samples in average buffer. +static U32 d99TempSampleIntervalCounter; ///< D99 temperature sensor sample collection timer counter. + static U32 ddTempDataPublicationTimerCounter; ///< DD Temperature sensors data publish timer counter. static U32 fpTempDataPublicationTimerCounter; ///< FP Temperature sensors data publish timer counter. static OVERRIDE_U32_T ddTempSensorsPublishInterval; ///< DD Temperature sensors publish time interval override. @@ -135,8 +147,13 @@ d50TempAvgC = 0.0F; d50TempSamplesNextIndex = 0; d50TempCount = 0; + d99TempRunningSumC = 0.0F; + d99TempAvgC = 0.0F; + d99TempSamplesNextIndex = 0; + d99TempCount = 0; d4TempSampleIntervalCounter = 0; d50TempSampleIntervalCounter = 0; + d99TempSampleIntervalCounter = 0; tempDataColTimeInterval = 0; tempDriftEventCheck = FALSE; @@ -284,10 +301,11 @@ * @brief * The filterTemperatureReadings function adds a new temperature sensor * sample to the filters. - * @details \b Inputs: D4 and D50 Temperature + * @details \b Inputs: D4, D50 and D99 Temperature * @details \b Outputs: d4TempSamplesC[], d4TempSamplesNextIndex, d4TempRunningSumC, * d4TempCount, d4TempAvgC, d50TempSamplesC, d50TempRunningSumC, d50TempSamplesNextIndex, - * d50TempCount, d50TempAvgC + * d50TempCount, d50TempAvgC, d99TempSamplesC, d99TempRunningSumC, d99TempSamplesNextIndex, + * d99TempCount, d99TempAvgC * @return none *************************************************************************/ static void filterTemperatureReadings( void ) @@ -327,6 +345,25 @@ d50TempSampleIntervalCounter = 0; } + + // Moving average sample collection interval varies based on the dialysate flow rate + if ( ++d99TempSampleIntervalCounter >= tempDataColTimeInterval ) + { + + // Filter D99 Temperature for fresh dialysate temperature + if ( d99TempCount >= D99_TEMP_MOVING_AVG_NUM_OF_SAMPLES ) + { + d99TempRunningSumC -= d99TempSamplesC[ d99TempSamplesNextIndex ]; + } + + F32 d99Temp = getTemperatureValue( D99_TEMP ); + d99TempSamplesC[ d99TempSamplesNextIndex ] = d99Temp; + d99TempRunningSumC += d99Temp; + d99TempSamplesNextIndex = INC_WRAP( d99TempSamplesNextIndex, 0, D99_TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); + d99TempCount = INC_CAP( d99TempCount, D99_TEMP_MOVING_AVG_NUM_OF_SAMPLES ); + d99TempAvgC = d99TempRunningSumC / (F32)d99TempCount; + } + // dailysate temperature moving average filterDialTemperatureReadings(); } @@ -353,7 +390,11 @@ else if ( TRUE == didTimeout( dialTempMovingAvgData[ i ].dialTempDataColStartTimeMS, D28_D30_DATA_COLLECTION_TIME_MS ) ) { CONDUCTIVITY_SENSORS_T sensor = ( DIAL_TEMP_D28 == i ? D27_COND : D29_COND ); +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + F32 temperatureC = getTeensyConductivityTemperatureValue( sensor ); +#else F32 temperatureC = getConductivityTemperatureValue( sensor ); +#endif U32 currentIndex = dialTempMovingAvgData[ i ].dialTempSamplesNextIndex; F32 prevSampleToRemoveC = dialTempMovingAvgData[ i ].dialTempSamplesC[ currentIndex ]; @@ -431,6 +472,19 @@ /*********************************************************************//** * @brief + * The getD99AverageTemperature function returns the average temperature + * for D99 temperature sensor. + * @details \b Inputs: none + * @details \b Outputs: none + * @return the D99 average temperature + *************************************************************************/ +F32 getD99AverageTemperature( void ) +{ + return d99TempAvgC; +} + +/*********************************************************************//** + * @brief * The getTempMovingAverageTimeInterval function calculates the temperature * interval used for sample collection based on the dialysate flow rate, * to find the average value. @@ -469,21 +523,32 @@ data.d78Temp = getTemperatureValue( D78_TEMP ); data.d4Temp = getTemperatureValue( D4_TEMP ); data.d50Temp = getTemperatureValue( D50_TEMP ); + data.d99Temp = getTemperatureValue( D99_TEMP ); data.boardTemp = getTemperatureValue( BRD_TEMP ); +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + data.d16CondTemp = getTeensyConductivityTemperatureValue( D17_COND ); + data.d28CondTemp = getTeensyConductivityTemperatureValue( D27_COND ); + data.d30CondTemp = getTeensyConductivityTemperatureValue( D29_COND ); + data.d44CondTemp = getTeensyConductivityTemperatureValue( D43_COND ); + data.d75CondTemp = getTeensyConductivityTemperatureValue( D74_COND ); +#else data.d16CondTemp = getConductivityTemperatureValue( D17_COND ); data.d28CondTemp = getConductivityTemperatureValue( D27_COND ); data.d30CondTemp = getConductivityTemperatureValue( D29_COND ); data.d44CondTemp = getConductivityTemperatureValue( D43_COND ); data.d75CondTemp = getConductivityTemperatureValue( D74_COND ); +#endif data.d4AvgTemp = getD4AverageTemperature(); data.d50AvgTemp = getD50AverageTemperature(); + data.d99AvgTemp = getD99AverageTemperature(); data.d28AvgTemp = dialTempMovingAvgData[ DIAL_TEMP_D28 ].dialTempAvgC; data.d30AvgTemp = dialTempMovingAvgData[ DIAL_TEMP_D30 ].dialTempAvgC; data.d9PresTemp = getFilteredPressureSensorTemperature( D9_PRES ); data.d66PresTemp = getFilteredPressureSensorTemperature( D66_PRES ); data.d51PresTemp = getFilteredPressureSensorTemperature( D51_PRES ); data.d18PresTemp = getFilteredPressureSensorTemperature( D18_PRES ); data.d41PresTemp = getFilteredPressureSensorTemperature( D41_PRES ); + data.d87PresTemp = getFilteredPressureSensorTemperature( D87_PRES ); broadcastData( MSG_ID_DD_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_SENSORS_DD_DATA_T ) ); ddTempDataPublicationTimerCounter = 0; Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -r25dfec9cbd60f1fc9f22c00342a1d009c95533ff -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 25dfec9cbd60f1fc9f22c00342a1d009c95533ff) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -8,8 +8,8 @@ * * @file FpgaDD.c * -* @author (last) “rkallala” -* @date (last) 19-Jan-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 27-Jan-2026 * * @author (original) Vinayakam Mani * @date (original) 26-Aug-2024 @@ -162,7 +162,7 @@ U16 fpgaD43CondTemp; ///< Reg 576. D43 Temperature U08 fpgaD43CondReadCnt; ///< Reg 578. D43 successful read count U08 fpgaD43CondErrorCnt; ///< Reg 579. D43 error read count - U16 fpgaD63LevelSensor; ///< Reg 580. Level Sensor 1 + U16 fpgaD63LevelSensor; ///< Reg 580. Upper level Sensor U16 fpgaD46LevelSensor; ///< Reg 582. Level Sensor 2 U08 fpgaHallSensInputs; ///< Reg 584. Hall sensor Inputs U08 fpgaD42TxFIFOCnt; ///< Reg 585. Blood leak sensor transmit FIFO count @@ -184,11 +184,10 @@ U32 fpgaD1Temp; ///< Reg 610. Inlet heat exchanger temperature U32 fpgaD4Temp; ///< Reg 614. Hydraulics primary heater temperature U32 fpgaD50Temp; ///< Reg 618. Trimmer heater temperature - U08 fpga_UnUsed_1; ///< Reg 622. Not used - U08 fpgaRTDReadCnt; ///< Reg 623. Read count for all RTD sensors + U16 fpgaD98LevelSensor; ///< Reg 622. Lower level Sensor U16 fpgaD12MeasuredSpeed; ///< Reg 624. Fresh dialysate pump measured speed U16 fpgaD48MeasuredSpeed; ///< Reg 626. Spent dialysate pump measured speed - U08 fpga_UnUsed_2; ///< Reg 628. Not used + U08 fpgaRTDReadCnt; ///< Reg 628. Read count for all RTD sensors U08 fpgaD12D48PumpStatus; ///< Reg 629. Dialysate pumps Error status U16 fpgaD12CurrentFeedback; ///< Reg 630. Fresh dialysate pump current feedback U16 fpgaD48CurrentFeedback; ///< Reg 632. Spent dialysate pump current feedback @@ -245,8 +244,9 @@ U16 p40PumpPWMReadback; ///< Reg 720. P40 pump PWM read back. U08 p7flowReadCount; ///< Reg 722. P7 Flow sensor read counter. U08 p7flowErrorCount; ///< Reg 723. P7 Flow sensor error counter. - U32 tempP23; ///< Reg 724. P23 temperature sensor reading. - U32 tempP22; ///< Reg 728. P22 ( TRO2 ) temperature sensor reading. + U16 fpgaD87PresPressure; ///< Reg 724. D87 MPM pressure sensor RAW pressure data + U16 fpgaD87PresTemp; ///< Reg 726. D87 MPM pressure sensor RAW temperature data + U32 fpgaD99Temp; ///< Reg 728. D99 temperature sensor U32 tempTax1; ///< Reg 732. ( Tax1 ) temperature sensor reading. U32 tempRTD; ///< Reg 736. spare temperature sensor reading. U08 ad7124errcnt; ///< Reg 740. Counter which increments when an invalid transaction happen between FPGA and AD7124. @@ -2434,6 +2434,32 @@ /*********************************************************************//** * @brief + * The getFPGAD87PresRawPressure function gets fresh dialysate post ultrafilter + * pressure sensor raw pressure value. + * @details \b Inputs: fpgaSensorReadings.fpgaD87PresPressure + * @details \b Outputs: none + * @return Fresh dialysate post ultrafilter pressure sensor raw pressure data + *************************************************************************/ +U16 getFPGAD87PresRawPressure( void ) +{ + return fpgaSensorReadings.fpgaD87PresPressure; +} + +/*********************************************************************//** + * @brief + * The getFPGAD87PresRawTemperature function gets fresh dialysate post ultrafilter + * pressure sensor raw temperature value. + * @details \b Inputs: fpgaSensorReadings.fpgaD87PresTemp + * @details \b Outputs: none + * @return Fresh dialysate post ultrafilter pressure sensor raw temperature data + *************************************************************************/ +U16 getFPGAD87PresRawTemperature( void ) +{ + return fpgaSensorReadings.fpgaD87PresTemp; +} + +/*********************************************************************//** + * @brief * The getFPGACD1ReadCount function gets D17 conductivity sensor read count. * @details \b Inputs: fpgaSensorReadings.fpgaD17CondReadCnt * @details \b Outputs: none @@ -2734,11 +2760,11 @@ /*********************************************************************//** * @brief - * The getFPGAD63LevelSensor function gets the latest FPGA D63 level sensor - * reading. + * The getFPGAD63LevelSensor function gets the latest FPGA D63 upper level + * sensor reading. * @details \b Inputs: fpgaSensorReadings.fpgaD63LevelSensor * @details \b Outputs: none - * @return last FPGA D63 level sensor reading + * @return last FPGA D63 upper level sensor reading *************************************************************************/ U16 getFPGAD63LevelSensor( void ) { @@ -2747,6 +2773,19 @@ /*********************************************************************//** * @brief + * The getFPGAD98LevelSensor function gets the latest FPGA D98 lower level + * sensor reading. + * @details \b Inputs: fpgaSensorReadings.fpgaD98LevelSensor + * @details \b Outputs: none + * @return last FPGA D98 lower level sensor reading + *************************************************************************/ +U16 getFPGAD98LevelSensor( void ) +{ + return fpgaSensorReadings.fpgaD98LevelSensor; +} + +/*********************************************************************//** + * @brief * The getFPGAD46LevelSensor function gets the latest FPGA level sensor 2 * reading. * @details \b Inputs: fpgaSensorReadings.fpgaD46LevelSensor @@ -2849,6 +2888,18 @@ /*********************************************************************//** * @brief + * The getFPGAD99Temp function gets the fresh dialysate temperature. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return Fresh dialysate temperature + *************************************************************************/ +U32 getFPGAD99Temp( void ) +{ + return fpgaSensorReadings.fpgaD99Temp; +} + +/*********************************************************************//** + * @brief * The getFPGARTDReadCount function gets the RTD sensors group read count. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none @@ -3472,30 +3523,6 @@ /*********************************************************************//** * @brief - * The getFPGAP23Temperature function gets the P23 temperature sensor reading. - * @details \b Inputs: fpgaSensorReadings.tempP23 - * @details \b Outputs: none - * @return P23 temperature sensor reading - *************************************************************************/ -U32 getFPGAP23Temperature( void ) -{ - return fpgaSensorReadings.tempP23; -} - -/*********************************************************************//** - * @brief - * The getFPGAP22Temperature function gets the P22 temperature sensor reading. - * @details \b Inputs: fpgaSensorReadings.tempP22 - * @details \b Outputs: none - * @return P22 temperature sensor reading - *************************************************************************/ -U32 getFPGAP22Temperature( void ) -{ - return fpgaSensorReadings.tempP22; -} - -/*********************************************************************//** - * @brief * The getFPGAP25FloaterState function gets the P25 floater level state. * @details \b Inputs: fpgaSensorReadings.levelSwitch * @details \b Outputs: none Index: firmware/App/Services/FpgaDD.h =================================================================== diff -u -r25dfec9cbd60f1fc9f22c00342a1d009c95533ff -re163e9faf44d2eb475188b8ea4d6a3befb6e753f --- firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision 25dfec9cbd60f1fc9f22c00342a1d009c95533ff) +++ firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) @@ -7,8 +7,8 @@ * * @file FpgaDD.h * -* @author (last) “rkallala” -* @date (last) 19-Jan-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 27-Jan-2026 * * @author (original) Vinayakam Mani * @date (original) 26-Aug-2024 @@ -222,8 +222,12 @@ U16 getFPGAD41PresRawPressure( void ); U16 getFPGAD41PresRawTemperature( void ); +U16 getFPGAD87PresRawPressure( void ); +U16 getFPGAD87PresRawTemperature( void ); + //Level sensor U16 getFPGAD63LevelSensor( void ); +U16 getFPGAD98LevelSensor( void ); U16 getFPGAD46LevelSensor( void ); BOOL getFPGAD6LevelStatus( void ); U08 getFPGAFloater2Status( void ); @@ -233,6 +237,7 @@ U32 getFPGAD78Temp( void ); U32 getFPGAD4Temp( void ); U32 getFPGAD50Temp( void ); +U32 getFPGAD99Temp( void ); U08 getFPGARTDReadCount( void ); U08 getFPGARTDCountErrorCycles( void ); @@ -294,8 +299,6 @@ S16 getFPGAP13RawTemperature( void ); S16 getFPGAP17RawPressure( void ); S16 getFPGAP17RawTemperature( void ); -U32 getFPGAP23Temperature( void ); -U32 getFPGAP22Temperature( void ); U08 getFPGAP25FloaterState( void );