Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -rcbcd41ec1ac2d5ae6446ec206ed6991a5306c249 -rdcd360fb4dc37db2dcbeb7fb14fb327fe68235f4 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision cbcd41ec1ac2d5ae6446ec206ed6991a5306c249) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision dcd360fb4dc37db2dcbeb7fb14fb327fe68235f4) @@ -1,25 +1,28 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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 Reservoirs.c +* @file Reservoirs.c * -* @author (last) Quang Nguyen -* @date (last) 26-Aug-2020 +* @author (last) Dara Navaei +* @date (last) 11-Nov-2021 * -* @author (original) Sean -* @date (original) 18-Mar-2020 +* @author (original) Sean +* @date (original) 18-Mar-2020 * ***************************************************************************/ #include // for memcpy() #include "LoadCell.h" +#include "MessageSupport.h" +#include "ModeDrain.h" #include "ModeGenIdle.h" #include "OperationModes.h" +#include "Pressures.h" #include "Reservoirs.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -39,10 +42,14 @@ #define DEFAULT_DRAIN_VOLUME_ML 0 ///< Default drain volume in mL. #define MAX_DRAIN_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///< Maximum drain volume in mL. -#define MAX_RESERVOIR_WEIGHT 10000 ///< Maximum reservoir weight in grams. +#define MAX_RESERVOIR_WEIGHT 10000 ///< Maximum reservoir weight in grams. + +#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 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 determing if fill completed. + // ********** private data ********** static U32 reservoirDataPublicationTimerCounter = 0; ///< used to schedule reservoir data publication to CAN bus. @@ -84,8 +91,8 @@ /*********************************************************************//** * @brief * The execReservoirs function manages periodic tasks for the Reservoirs module. - * @details Inputs: none - * @details Outputs: Reservoir data broadcast on interval + * @details Inputs: reservoirDataPublicationTimerCounter + * @details Outputs: reservoirDataPublicationTimerCounter * @return none *************************************************************************/ void execReservoirs( void ) @@ -99,11 +106,14 @@ // publish active reservoir, fill/drain volume targets at 1 Hz. if ( ++reservoirDataPublicationTimerCounter >= RESERVOIR_DATA_PUB_INTERVAL ) - { - U32 actRes = getU32OverrideValue( &activeReservoir ); - U32 filVol = getU32OverrideValue( &fillVolumeTargetMl ); - U32 drnVol = getU32OverrideValue( &drainVolumeTargetMl ); - broadcastReservoirData( actRes, filVol, drnVol ); + { + RESERVOIR_DATA_T data; + + data.activeReservoir = getU32OverrideValue( &activeReservoir ); + data.fillToVolumeMl = getU32OverrideValue( &fillVolumeTargetMl ); + data.drainToVolumeMl = getU32OverrideValue( &drainVolumeTargetMl ); + + broadcastData( MSG_ID_DG_RESERVOIR_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( RESERVOIR_DATA_T ) ); reservoirDataPublicationTimerCounter = 0; } } @@ -327,6 +337,7 @@ { drainVolumeTargetMl.data = drainCmd.targetVolume; tareLoadCellRequest = drainCmd.tareLoadCell; + signalDrainModeRinseConcentrateLines( drainCmd.rinseConcentrateLines ); requestNewOperationMode( DG_MODE_DRAI ); cmdResponse.rejected = FALSE; } @@ -456,10 +467,17 @@ *************************************************************************/ BOOL hasTargetFillVolumeBeenReached( DG_RESERVOIR_ID_T reservoirId ) { - F32 const loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + F32 const loadcellWeight1 = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + F32 const loadcellWeight2 = getLoadCellSmallFilteredWeight( redundantLoadCell[ reservoirId ] ); U32 const targetFillVolume = getU32OverrideValue( &fillVolumeTargetMl ); - BOOL const hasTargetReached = ( loadcellWeight >= targetFillVolume ); + BOOL const hasTargetReached = ( ( loadcellWeight1 >= targetFillVolume || loadcellWeight2 > ( targetFillVolume + MAX_REDUNDANT_LOAD_CELL_DIFF ) ) ? TRUE : FALSE ); + // if redundant load cells too far apart at end of fill, alarm + if ( loadcellWeight1 < targetFillVolume ) + { + // TODO - alarm + } + return hasTargetReached; } @@ -491,7 +509,8 @@ // If the goal is to tare the load cell, then the target drain should be reached and timing out on the // reservoir weight is not enough - if ( ( TRUE == hasTimeOut ) || ( ( TRUE == hasTargetReached ) && ( FALSE == tareLoadCellRequest ) ) ) + if ( ( ( TRUE == hasTimeOut ) && ( getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ) > MIN_DRAIN_INLET_PSI_EMPTY ) ) || + ( ( TRUE == hasTargetReached ) && ( FALSE == tareLoadCellRequest ) ) ) { result = TRUE; // Reset for next drain