Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r4b358e1af8512dd9a0e948ef7c534b6af393b611 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 4b358e1af8512dd9a0e948ef7c534b6af393b611) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -27,6 +27,7 @@ #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "Rinseback.h" +#include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -58,6 +59,10 @@ static const U32 TREATMENT_STATE_DATA_PUB_INTERVAL = ( 250 / TASK_GENERAL_INTERVAL ); /// Interval (ms/task time) at which updated, valid treatment setting ranges are published on the CAN bus. static const U32 TREATMENT_SETTINGS_RANGES_PUB_INTERVAL = ( ( 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ); +/// Interval (ms/task time) at which the treatment periodic data is published on the CAN bus. +static const U32 TREATMENT_PERIODIC_DATA_PUB_INTERVAL = ( ( 30 * SEC_PER_MIN * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ); +/// Interval (ms/task time) at which the treatment periodic data is logged. +static const U32 TREATMENT_PERIODIC_DATA_LOG_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); #define CALC_ELAPSED_TREAT_TIME_IN_SECS() ( treatmentTimeMS / MS_PER_SECOND ) ///< Macro to calculate the elapsed treatment time in seconds. /// Macro to calculate the elapsed treatment time in minutes. @@ -84,6 +89,7 @@ static U32 treatmentTimeBroadcastTimerCtr; ///< Treatment time data broadcast timer counter used to schedule when to transmit data. static U32 treatmentStateBroadcastTimerCtr; ///< Treatment state data broadcast timer counter used to schedule when to transmit data. static U32 treatmentParamsRangesBroadcastTimerCtr; ///< Treatment parameter ranges broadcast timer counter used to schedule when to transmit updated ranges. +static U32 treatmentPeriodDataBroadcastTimerCtr; ///< Treatment 30 minutes periodic data broadcast timer counter used to schedule when to transmit data. static BOOL resumeTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment resume. static BOOL initiateRinsebackAlarmResponseRequest; ///< Flag indicates user has requested rinseback. @@ -99,11 +105,18 @@ static F32 pendingUFRateChange; ///< An ultrafiltration rate change (mL/min) is pending user confirmation. static U32 pendingTreatmentTimeChange; ///< A treatment time change (min) is pending user confirmation. +static F32 bloodFlowRateTotal; ///< Blood flow rate total, used to calculate blood flow rate average over 30 minutes. +static F32 dialysateFlowRateTotal; ///< Dialysate flow rate total, used to calculate dialysate flow rate average over 30 minutes. +static F32 ultraFiltrationRateTotal; ///< UF rate total, used to calculate UF rate average over 30 minutes. +static F32 arterialPressureTotal; ///< Arterial pressure total, used to calculate arterial pressure average over 30 minutes. +static F32 venousPressureTotal; ///< Venous pressure total, used to calculate venous pressure average over 30 minutes. + // ********** private function prototypes ********** static void resetSignalFlags( void ); static void resetAlarmSignalFlags( void ); static void broadcastTreatmentSettingsRanges( void ); +static void broadcastTreatmentPeriodicData(); static TREATMENT_STATE_T handleTreatmentStartState( void ); static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ); static TREATMENT_STATE_T handleTreatmentDialysisState( void ); @@ -132,6 +145,7 @@ treatmentTimeBroadcastTimerCtr = TREATMENT_TIME_DATA_PUB_INTERVAL; // So we send time data immediately when we begin treatment mode treatmentStateBroadcastTimerCtr = TREATMENT_STATE_DATA_PUB_INTERVAL; // So we send state data immediately when we begin treatment mode treatmentParamsRangesBroadcastTimerCtr = TREATMENT_SETTINGS_RANGES_PUB_INTERVAL; // So we send ranges immediately when we begin treatment mode + treatmentPeriodDataBroadcastTimerCtr = 0; presTreatmentTimeSecs = 0; presBloodFlowRate = 0; @@ -146,6 +160,12 @@ pendingUFVolumeChange = 0.0; pendingUFRateChange = 0.0; pendingTreatmentTimeChange = 0; + + bloodFlowRateTotal = 0.0; + dialysateFlowRateTotal = 0.0; + ultraFiltrationRateTotal = 0.0; + arterialPressureTotal = 0.0; + venousPressureTotal = 0.0; } /*********************************************************************//** @@ -241,6 +261,19 @@ /*********************************************************************//** * @brief + * The getActualTreatmentTimeMins function determines the actual treatment + * duration in minutes. + * @details Inputs: treatmentTimeMS + * @details Outputs: none + * @return The actual treatment duration in minutes. + *************************************************************************/ +U32 getActualTreatmentTimeMins( void ) +{ + return ( treatmentTimeMS / ( MS_PER_SECOND * SEC_PER_MIN ) ); +} + +/*********************************************************************//** + * @brief * The getRinsebackCompleted function determines whether a rinseback has been * completed (indicating blood-side circuit should be primarily saline). * @details Inputs: rinsebackDone @@ -461,6 +494,7 @@ // Broadcast treatment data broadcastTreatmentTimeAndState(); broadcastTreatmentSettingsRanges(); + broadcastTreatmentPeriodicData(); // Manage air trap control execAirTrapMonitorTreatment(); @@ -1221,7 +1255,48 @@ } } +/*********************************************************************//** + * @brief + * The broadcastTreatmentPeriodicData function computes and broadcasts + * periodic treatment data during treatment. + * @details Inputs: treatmentPeriodDataBroadcastTimerCtr + * @details Outputs: collected and sent average treatment data over 30 minutes + * @return none + *************************************************************************/ +static void broadcastTreatmentPeriodicData( void ) +{ + if ( ( treatmentPeriodDataBroadcastTimerCtr % TREATMENT_PERIODIC_DATA_LOG_INTERVAL ) == 0 ) + { + bloodFlowRateTotal += getMeasuredBloodFlowRate(); + dialysateFlowRateTotal += getMeasuredDialInFlowRate(); + ultraFiltrationRateTotal += getTotalMeasuredUFVolumeInMl() / getActualTreatmentTimeMins(); + arterialPressureTotal += getMeasuredArterialPressure(); + venousPressureTotal += getMeasuredVenousPressure(); + } + if ( ++treatmentPeriodDataBroadcastTimerCtr >= TREATMENT_PERIODIC_DATA_PUB_INTERVAL ) + { + U32 const numberOfDataPoint = TREATMENT_PERIODIC_DATA_PUB_INTERVAL / TREATMENT_PERIODIC_DATA_LOG_INTERVAL; + TREATMENT_LOG_DATA_PERIODIC_T periodTreatmentData; + + periodTreatmentData.timestamp = getRTCTimestamp(); + periodTreatmentData.avgBloodFlowRate += bloodFlowRateTotal / numberOfDataPoint; + periodTreatmentData.avgDialysateFlowRate += dialysateFlowRateTotal / numberOfDataPoint; + periodTreatmentData.avgUFRate += ultraFiltrationRateTotal / numberOfDataPoint; + periodTreatmentData.avgArterialPressure += arterialPressureTotal / numberOfDataPoint; + periodTreatmentData.avgVenousPressure += venousPressureTotal / numberOfDataPoint; + + treatmentPeriodDataBroadcastTimerCtr = 0; + bloodFlowRateTotal = 0.0; + dialysateFlowRateTotal = 0.0; + ultraFiltrationRateTotal = 0.0; + arterialPressureTotal = 0.0; + venousPressureTotal = 0.0; + sendTreatmentPeriodDataToUI( &periodTreatmentData ); + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/