Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r9490539a39d2bfd8d40558f3c05b09b48f041e6c -r5f538f79c346c041661d039e92b4fa1f77c3e1ac --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 9490539a39d2bfd8d40558f3c05b09b48f041e6c) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 5f538f79c346c041661d039e92b4fa1f77c3e1ac) @@ -112,7 +112,7 @@ // set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setDrainPumpTargetRPMDelayed( TARGET_DRAIN_PUMP_RPM, DELAY_DRAIN_PUMP_MS ); + setDrainPumpTargetRPMDelayed( /*TARGET_DRAIN_PUMP_RPM*/ 500, DELAY_DRAIN_PUMP_MS ); // NOTE: The target flow rate should be set prior to setting the start primary heater // because the initial guess in the heaters driver needs the target flow to calculate Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r550a5df210ac26217412e5e312d0a08864c5682e -r5f538f79c346c041661d039e92b4fa1f77c3e1ac --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 550a5df210ac26217412e5e312d0a08864c5682e) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 5f538f79c346c041661d039e92b4fa1f77c3e1ac) @@ -48,8 +48,7 @@ #define MIN_DRAIN_INLET_PSI_EMPTY -3.0 ///< Minimum drain inlet pressure (in PSI) to indicate reservoir is empty while drain pump on. #define RESERVOIR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< interval (ms/task time) at which the reservoir data is published on the CAN bus. #define MAX_REDUNDANT_LOAD_CELL_DIFF 50.0 ///< Maximum difference in redundant load cells when determining if fill completed. -// 2400 rpm is ~ 2400 mL/min and it results 1 mL of flow change. -#define DRAIN_THRESHOLD_ML(rpm) ( (F32)rpm / 2400.0 ) ///< Drain threshold in milliliters. +#define MAX_DRAIN_RPM_MLP 2400.0 ///< Maximum drain RPM in mL/min. #define DATA_PUBLISH_COUNTER_START_COUNT 5 ///< Data publish counter start count. // ********** private data ********** @@ -69,6 +68,13 @@ F32 flowTargetDialysateLPM; ///< Dialysate target flow rate in L/min. } HEATERS_TEMPERATURE_CALC_DATA_T; +/// Reservoirs previous status +typedef struct +{ + F32 previousReservoirWeightG; ///< Previous reservoir weight in grams. + F32 previousDrainFlowML; ///< Previous reservoir drain flow in milliliters. +} RESERVOIRS_PREVIOUS_STATUS; + static HEATERS_TEMPERATURE_CALC_DATA_T heatersTempCalc; ///< Heaters temperature calculations data structure. static U32 dataPublishCounter; ///< used to schedule reservoir data publication to CAN bus. @@ -89,7 +95,7 @@ static DG_HEATING_CAL_RECORD_T heatingConstsCalRecord; ///< DG heating calibration record. static F32 targetFillFlowRateLPM; ///< Target fill flow rate in L/min. static BOOL isThisTheFirstCycle = TRUE; ///< Boolean flag to indicate whether this is the first cycle. -static F32 previousReservoirWeight[ NUM_OF_DG_RESERVOIRS ]; ///< Previous reservoir weight. +static RESERVOIRS_PREVIOUS_STATUS reservoirPreviousStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoirs previous status. /*********************************************************************//** * @brief @@ -109,7 +115,7 @@ isThisTheFirstCycle = TRUE; dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; - memset( &previousReservoirWeight, 0.0, sizeof( F32 ) * NUM_OF_DG_RESERVOIRS ); + memset( &reservoirPreviousStatus, 0.0, sizeof( RESERVOIRS_PREVIOUS_STATUS ) * NUM_OF_DG_RESERVOIRS ); } /*********************************************************************//** @@ -151,6 +157,12 @@ data.tempLastFill = getLastFillTemperature(); data.timereservoirFill = heatersTempCalc.timeReservoirFillMS; + // TODO remove + data.previousDrainFlow = reservoirPreviousStatus[ DG_RESERVOIR_1 ].previousDrainFlowML; + data.previousLoadCell = reservoirPreviousStatus[ DG_RESERVOIR_1 ].previousReservoirWeightG; + data.drainTime = reservoirWeightUnchangeStartTime[ DG_RESERVOIR_1 ]; + // TODO remove + broadcastData( MSG_ID_DG_RESERVOIRS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( RESERVOIR_DATA_T ) ); dataPublishCounter = 0; } @@ -673,30 +685,61 @@ F32 loadcellWeightML = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); U32 targetDrainVolML = getU32OverrideValue( &drainVolumeTargetMl ); - F32 drainFlowML = loadcellWeightML - previousReservoirWeight[ reservoirId ]; - F32 drainThresholdML = ( (F32)getDrainPumpTargetRPM() ) / 2400.0; + F32 drainFlowML = reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG - loadcellWeightML; + F32 drainThresholdML = ( (F32)getDrainPumpTargetRPM() ) / MAX_DRAIN_RPM_MLP; + U32 drainPumpFeedbackRPM = getDrainPumpMeasuredRPM(); - // Update the structure with the current weight as the previous - previousReservoirWeight[ reservoirId ] = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + if ( ( reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG > getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ) ) && + ( drainPumpFeedbackRPM > 0 ) ) + { + reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + reservoirPreviousStatus[ reservoirId ].previousDrainFlowML = drainFlowML; + // If the flow is less than the threshold and the time has not been set, set the timer + // If the flow is greater than the threshold and timer has been set, 0 it because the flow is out of range and we are not + // ready to consider this the end of the reservoir flow + // If the wait for drain to steady has elapsed and the drain pump inlet pressure sensor is indicating and increased vacuum, + // signal the drain is complete + if ( ( reservoirPreviousStatus[ reservoirId ].previousDrainFlowML <= drainThresholdML ) && ( 0 == reservoirWeightUnchangeStartTime[ reservoirId ] ) ) + { + reservoirWeightUnchangeStartTime[ reservoirId ] = getMSTimerCount(); + } + else if ( reservoirPreviousStatus[ reservoirId ].previousDrainFlowML > drainThresholdML ) + { + reservoirWeightUnchangeStartTime[ reservoirId ] = 0; + } + else if ( ( TRUE == didTimeout( reservoirWeightUnchangeStartTime[ reservoirId ], timeout ) && + ( getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ) > MIN_DRAIN_INLET_PSI_EMPTY ) ) ) + { + result = TRUE; + } + } + + /*if ( ( drainFlowML < reservoirPreviousStatus[ reservoirId ].previousDrainFlowML ) )//|| ( 0 == reservoirPreviousStatus[ reservoirId ].previousDrainFlowML ) ) + { + // Update the structure with the current weight as the previous + reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + reservoirPreviousStatus[ reservoirId ].previousDrainFlowML = drainFlowML; + } + // If the flow is less than the threshold and the time has not been set, set the timer // If the flow is greater than the threshold and timer has been set, 0 it because the flow is out of range and we are not // ready to consider this the end of the reservoir flow // If the wait for drain to steady has elapsed and the drain pump inlet pressure sensor is indicating and increased vacuum, // signal the drain is complete - if ( ( drainFlowML <= drainThresholdML ) && ( 0 == reservoirWeightUnchangeStartTime[ reservoirId ] ) ) + if ( ( reservoirPreviousStatus[ reservoirId ].previousDrainFlowML <= drainThresholdML ) && ( 0 == reservoirWeightUnchangeStartTime[ reservoirId ] ) ) { reservoirWeightUnchangeStartTime[ reservoirId ] = getMSTimerCount(); } - else if ( drainFlowML > drainThresholdML ) + else if ( reservoirPreviousStatus[ reservoirId ].previousDrainFlowML > drainThresholdML ) { reservoirWeightUnchangeStartTime[ reservoirId ] = 0; } else if ( ( TRUE == didTimeout( reservoirWeightUnchangeStartTime[ reservoirId ], timeout ) && ( getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ) > MIN_DRAIN_INLET_PSI_EMPTY ) ) ) { result = TRUE; - } + }*/ return result; } @@ -752,8 +795,9 @@ void initDrainParameters( DG_RESERVOIR_ID_T reservoirId ) { // Set the start time to 0 for the next drain and update the current load cell reading to the previous value - reservoirWeightUnchangeStartTime[ reservoirId ] = 0; - previousReservoirWeight[ reservoirId ] = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + reservoirWeightUnchangeStartTime[ reservoirId ] = 0; + reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + reservoirPreviousStatus[ reservoirId ].previousDrainFlowML = 0.0; } Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r9490539a39d2bfd8d40558f3c05b09b48f041e6c -r5f538f79c346c041661d039e92b4fa1f77c3e1ac --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 9490539a39d2bfd8d40558f3c05b09b48f041e6c) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 5f538f79c346c041661d039e92b4fa1f77c3e1ac) @@ -85,6 +85,12 @@ F32 tempAvgFill; ///< Average fill temperature F32 tempLastFill; ///< Last fill temperature F32 timereservoirFill; ///< Reservoir fill time in milliseconds + + // TODO for testing only + F32 previousDrainFlow; + F32 previousLoadCell; + U32 drainTime; + // TODO for testing only } RESERVOIR_DATA_T; // ********** public function prototypes **********