Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r4d7d40a27130dc813d653f044cbb856b1b7d8481 -r4af713cb53b909ba87893dc814d39af89fb8e8d2 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 4d7d40a27130dc813d653f044cbb856b1b7d8481) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 4af713cb53b909ba87893dc814d39af89fb8e8d2) @@ -22,6 +22,7 @@ #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" +#include "TaskGeneral.h" #include "TemperatureSensors.h" #include "Valves.h" @@ -32,11 +33,15 @@ // ********** private definitions ********** -#define TARGET_DRAIN_PUMP_RPM 2800 ///< Target drain pump speed (in RPM). +#define TARGET_DRAIN_PUMP_RPM 2800 ///< Target drain pump speed (in RPM). +#define DRAIN_WEIGHT_CHANGE_TOLERANCE 0.1 ///< Weight changes during draining tolerance. +#define DRAIN_WEIGH_UNCHANGE_TIMEOUT ( 10 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Time period of unchanged weight during draining before timeout. // ********** private data ********** -static DG_DRAIN_STATE_T drainState = DG_DRAIN_STATE_START; ///< Currently active drain state. +static DG_DRAIN_STATE_T drainState = DG_DRAIN_STATE_START; ///< Currently active drain state. +static F32 previousWeight; ///< Previous weight of the reservoir draining. +static U32 weightNotDroppingTimerCounter; ///< Timer counter for the period weight not dropping. // ********** private function prototypes ********** @@ -52,6 +57,8 @@ void initDrainMode( void ) { drainState = DG_DRAIN_STATE_START; + previousWeight = 0.0; + weightNotDroppingTimerCounter = 0; } /*********************************************************************//** @@ -117,15 +124,31 @@ { DG_DRAIN_STATE_T result = DG_DRAIN_STATE_DRAIN; LOAD_CELL_ID_T drainWeightLoadCell = LOAD_CELL_A1; + F32 currentFilteredWeight; + U32 const targetWeight = getReservoirDrainVolumeTargetMl(); // determine which load cell to use for drain volume - we want weight of inactive reservoir if ( RESERVOIR_1 == getActiveReservoir() ) { drainWeightLoadCell = LOAD_CELL_B1; } + currentFilteredWeight = getLoadCellFilteredWeight( drainWeightLoadCell ); + + // if weight stays the same for 10 seconds, timeout and auto calibration + if ( fabs( previousWeight - currentFilteredWeight ) < DRAIN_WEIGHT_CHANGE_TOLERANCE ) + { + previousWeight = currentFilteredWeight; + + if ( ++weightNotDroppingTimerCounter >= DRAIN_WEIGH_UNCHANGE_TIMEOUT ) + { + weightNotDroppingTimerCounter = 0; + setLoadCellAutoCal( drainWeightLoadCell, currentFilteredWeight - targetWeight ); + } + } + // if we've reached our target drain to volume (by weight), we're done draining - go back to re-circ mode - if ( getReservoirDrainVolumeTargetMl() >= getLoadCellFilteredWeight( drainWeightLoadCell ) ) + if ( targetWeight >= currentFilteredWeight ) { setDrainPumpTargetSpeed( 0 ); requestNewOperationMode( DG_MODE_CIRC );