Index: firmware/App/Monitors/Temperature.c =================================================================== diff -u -r2cdff97cc76e7a7b9ec3c087dacf767f2c022b31 -r7f97b34440ff591f75dbedb9ae3284ced36e73b7 --- firmware/App/Monitors/Temperature.c (.../Temperature.c) (revision 2cdff97cc76e7a7b9ec3c087dacf767f2c022b31) +++ firmware/App/Monitors/Temperature.c (.../Temperature.c) (revision 7f97b34440ff591f75dbedb9ae3284ced36e73b7) @@ -1,22 +1,26 @@ /************************************************************************** * -* Copyright (c) 2024-2025 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 Temperature.c * -* @author (last) Zoltan Miskolci -* @date (last) 10-Dec-2025 +* @author (last) Raghu Kallala +* @date (last) 10-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" @@ -42,7 +46,8 @@ #define TEMP_SENSORS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Temperature sensors publish data time interval. #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 25 ///< D50 temperature sensor moving average number of samples ( 250ms filter ). +#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. @@ -90,15 +95,23 @@ static F32 d4TempSamplesC[ D4_TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< D4 temperature samples array in C. static U32 d4TempSamplesNextIndex; ///< D4 temperature sample next index number. static U32 d4TempCount; ///< D4 Number of samples in average buffer. -static U32 tempDataColTimeInterval; ///< Temperature data collection time interval in milliseconds. +static U32 tempDataCollectionTimeInterval; ///< Temperature data collection time interval in milliseconds. static U32 d4TempSampleIntervalCounter; ///< D4 temperature sensor sample collection timer counter. +static U32 d50TempSampleIntervalCounter; ///< D50 temperature sensor sample collection timer counter. static F32 d50TempAvgC; ///< D50 temperature average in C. static F32 d50TempRunningSumC; ///< D50 temperature running sum in C. static F32 d50TempSamplesC[ D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< D50 temperature samples array in C. 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. @@ -134,8 +147,14 @@ d50TempAvgC = 0.0F; d50TempSamplesNextIndex = 0; d50TempCount = 0; + d99TempRunningSumC = 0.0F; + d99TempAvgC = 0.0F; + d99TempSamplesNextIndex = 0; + d99TempCount = 0; d4TempSampleIntervalCounter = 0; - tempDataColTimeInterval = 0; + d50TempSampleIntervalCounter = 0; + d99TempSampleIntervalCounter = 0; + tempDataCollectionTimeInterval = 0; tempDriftEventCheck = FALSE; dialTempMovingAvgData[ DIAL_TEMP_D28 ].dialTempColHasTimerBeenSet = FALSE; @@ -282,16 +301,17 @@ * @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 ) { // Moving average sample collection interval varies based on the dialysate flow rate - if ( ++d4TempSampleIntervalCounter >= tempDataColTimeInterval ) + if ( ++d4TempSampleIntervalCounter >= tempDataCollectionTimeInterval ) { // Filter D4 Temperature for AC heater if ( d4TempCount >= D4_TEMP_MOVING_AVG_NUM_OF_SAMPLES ) @@ -308,19 +328,42 @@ d4TempSampleIntervalCounter = 0; } - // Filter D50 Temperature ( 250 ms filter ) for trimmer heater - if ( d50TempCount >= D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES ) + // Moving average sample collection interval varies based on the dialysate flow rate + if ( ++d50TempSampleIntervalCounter >= tempDataCollectionTimeInterval ) { - d50TempRunningSumC -= d50TempSamplesC[ d50TempSamplesNextIndex ]; + if ( d50TempCount >= D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES ) + { + d50TempRunningSumC -= d50TempSamplesC[ d50TempSamplesNextIndex ]; + } + + F32 d50Temp = getTemperatureValue( D50_TEMP ); + d50TempSamplesC[ d50TempSamplesNextIndex ] = d50Temp; + d50TempRunningSumC += d50Temp; + d50TempSamplesNextIndex = INC_WRAP( d50TempSamplesNextIndex, 0, D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); + d50TempCount = INC_CAP( d50TempCount, D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES ); + d50TempAvgC = d50TempRunningSumC / (F32)d50TempCount; + d50TempSampleIntervalCounter = 0; } - F32 d50Temp = getTemperatureValue( D50_TEMP ); - d50TempSamplesC[ d50TempSamplesNextIndex ] = d50Temp; - d50TempRunningSumC += d50Temp; - d50TempSamplesNextIndex = INC_WRAP( d50TempSamplesNextIndex, 0, D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); - d50TempCount = INC_CAP( d50TempCount, D50_TEMP_MOVING_AVG_NUM_OF_SAMPLES ); - d50TempAvgC = d50TempRunningSumC / (F32)d50TempCount; + // Moving average sample collection interval varies based on the dialysate flow rate + if ( ++d99TempSampleIntervalCounter >= tempDataCollectionTimeInterval ) + { + + // 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(); } @@ -347,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 ]; @@ -425,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. @@ -438,7 +498,7 @@ U32 sampleInterval = (U32)( ( period / (F32)D4_TEMP_MOVING_AVG_NUM_OF_SAMPLES ) * MS_PER_SECOND ); - tempDataColTimeInterval = (U32) ( sampleInterval / TASK_PRIORITY_INTERVAL ); + tempDataCollectionTimeInterval = (U32) ( sampleInterval / TASK_PRIORITY_INTERVAL ); } /*********************************************************************//** @@ -463,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; @@ -487,15 +558,17 @@ { TEMPERATURE_SENSORS_FP_DATA_T data; - data.m3Temp = getFilteredPressureSensorTemperature( M3_PRES ); - data.p10Temp = getFilteredConductivitySensorTemperature( P9_COND ); - data.p19Temp = getFilteredConductivitySensorTemperature( P18_COND ); - data.p8Temp = getFilteredPressureSensorTemperature( P8_PRES ); - data.p13Temp = getFilteredPressureSensorTemperature( P13_PRES ); - data.p17Temp = getFilteredPressureSensorTemperature( P17_PRES ); - data.p7Temp = getFilteredFlowSensorTemperature( P7_FLOW ); - data.p16Temp = getFilteredFlowSensorTemperature( P16_FLOW ); - data.p46Temp = getFilteredPressureSensorTemperature( P46_PRES ); + data.m3Temp = getFilteredPressureSensorTemperature( M3_PRES ); + data.p8Temp = getFilteredPressureSensorTemperature( P8_PRES ); + data.p13Temp = getFilteredPressureSensorTemperature( P13_PRES ); + data.p17Temp = getFilteredPressureSensorTemperature( P17_PRES ); + data.p46Temp = getFilteredPressureSensorTemperature( P46_PRES ); + data.p10Temp = getFilteredConductivitySensorTemperature( P9_COND ); + data.p19Temp = getFilteredConductivitySensorTemperature( P18_COND ); + data.p7Temp = getFilteredFlowSensorTemperature( P7_FLOW ); + data.p16Temp = getFilteredFlowSensorTemperature( P16_FLOW ); + data.p7InternalTemp = getFlowInternalTemperature( P7_FLOW ); + data.p16InternalTemp = getFlowInternalTemperature( P16_FLOW ); broadcastData( MSG_ID_FP_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_SENSORS_FP_DATA_T ) ); fpTempDataPublicationTimerCounter = 0;