Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r47a7b0fce13cf38919932a8662c378f4f6a8b9f3 -r4bb331eccddd3c929266b9c01066347533726774 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 47a7b0fce13cf38919932a8662c378f4f6a8b9f3) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 4bb331eccddd3c929266b9c01066347533726774) @@ -64,8 +64,10 @@ // ********** private data ********** static RO_PUMP_STATE_T roPumpState; ///< Current state of pump controller state machine. +static RO_PUMP_STATE_T prevROPumpState; ///< Previous state of RO pump controller state machine. static BOOL isROPumpOn; ///< Flag indicating whether pump is currently running. static BOOL stopPumpRequest; ///< Flag indicating pump stop is requested. +static BOOL exemptLowFlowAlarm; ///< Flag indicating whether to exempt low permeate flow alarm. static U32 roPumpDataPublicationTimerCounter; ///< Used to schedule RO pump data publication to CAN bus. static OVERRIDE_U32_T roPumpDataPublishInterval; ///< Interval (in ms) at which to publish boost pump data to CAN bus. static U32 roControlTimerCounter; ///< Determines when to perform control on RO pump. @@ -74,7 +76,7 @@ static F32 roPumpDutyCyclePctSet; ///< Currently set RO pump PWM duty cycle. static OVERRIDE_F32_T roPumpOpenLoopTargetDutyCycle; ///< Target RO pump open loop PWM. static BOOL roPumpStartControl; ///< boolean to determine when closed loop flow control starts -static U32 roPumpClosedLoopStartTimeMS; ///< Timeout timer for RO pump to reach minimum target flow +static U32 lowFlowExemptTimer; ///< Timer to exempt low flow rate alarm // ********** private function prototypes ********** @@ -91,9 +93,9 @@ /*********************************************************************//** * @brief * The initROPump function initializes the RO Pump module. - * @details \b Inputs: roPumpState, roPumpControlMode, isROPumpOn, stopPumpRequest, + * @details \b Inputs: roPumpState, prevROPumpState, roPumpControlMode, isROPumpOn, stopPumpRequest, * roControlTimerCounter, roPumpDutyCyclePctSet, roPumpOpenLoopTargetDutyCycle, roPumpDataPublicationTimerCounter, - * roPumpDataPublishInterval, targetROPumpFlowRate, targetROPumpPressure + * roPumpDataPublishInterval, targetROPumpFlowRate, targetROPumpPressure, exemptLowFlowAlarm * @details \b Outputs: RO Pump controller unit initialized * @return none *************************************************************************/ @@ -110,8 +112,10 @@ MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); roPumpState = RO_PUMP_OFF_STATE; + prevROPumpState = RO_PUMP_OFF_STATE; isROPumpOn = FALSE; stopPumpRequest = FALSE; + exemptLowFlowAlarm = TRUE; roControlTimerCounter = 0; roPumpDutyCyclePctSet = 0.0F; roPumpStartControl = FALSE; @@ -132,7 +136,7 @@ roPumpOpenLoopTargetDutyCycle.ovData = 0.0; roPumpOpenLoopTargetDutyCycle.ovInitData = 0.0; roPumpOpenLoopTargetDutyCycle.override = OVERRIDE_RESET; - roPumpClosedLoopStartTimeMS = 0; + lowFlowExemptTimer = 0; stopROPump(); } @@ -174,6 +178,15 @@ break; } + if ( prevROPumpState == RO_PUMP_OFF_STATE ) + { + exemptLowFlowAlarm = TRUE; + } + else + { + exemptLowFlowAlarm = FALSE; + } + prevROPumpState = roPumpState; // Publish RO pump data on interval publishROPumpData(); } @@ -190,6 +203,7 @@ { RO_PUMP_STATE_T state = RO_PUMP_OFF_STATE; isROPumpOn = FALSE; + lowFlowExemptTimer = 0; // If there is a target flow set, transition to the PI controller and control to flow if ( getTargetROPumpFlowRateMLPM() > 0 ) @@ -200,6 +214,7 @@ resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); roPumpStartControl = FALSE; + lowFlowExemptTimer = getMSTimerCount(); state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; } // If there is a target pressure set, transition to the PI controller and control to pressure. @@ -210,6 +225,7 @@ roPumpDutyCyclePctSet = roPumpPresToPWM( getTargetROPumpPressure() ); resetPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, roPumpDutyCyclePctSet, 0.0F ); setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + lowFlowExemptTimer = getMSTimerCount(); state = RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; } // If the target duty cycle is greater than zero (minimum is 10%) and the mode has been set to open @@ -219,6 +235,7 @@ roPumpDutyCyclePctSet = getTargetROPumpDutyCyclePCT(); setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); isROPumpOn = TRUE; + lowFlowExemptTimer = getMSTimerCount(); state = RO_PUMP_OPEN_LOOP_STATE; } @@ -409,7 +426,6 @@ // Get the initial guess of the duty cycle roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateMLPM() ); roControlTimerCounter = 0; - roPumpClosedLoopStartTimeMS = getMSTimerCount(); isROPumpOn = TRUE; result = TRUE; } @@ -601,6 +617,32 @@ /*********************************************************************//** * @brief + * The getROPumpLowFlowExemptTimer function gets the timer when RO pump + * starts from Off state. + * @details \b Inputs: none + * @details \b Outputs: none + * @return the timer when RO pump started from Off state (in ms). + *************************************************************************/ +U32 getROPumpLowFlowExemptTimer( void ) +{ + return lowFlowExemptTimer; +} + +/*********************************************************************//** + * @brief + * The getROPumpLowFlowExemptFlag function gets the flag whether or not + * to exempt the low flow alarm. + * @details \b Inputs: none + * @details \b Outputs: none + * @return the flag whether or not to exempt low flow alarm (in mL/min). + *************************************************************************/ +BOOL getROPumpLowFlowExemptFlag( void ) +{ + return exemptLowFlowAlarm; +} + +/*********************************************************************//** + * @brief * The roPumpPresToPWM function calculates the duty cycle for the given target * pressure. * @details \b Inputs: none Index: firmware/App/Controllers/ROPump.h =================================================================== diff -u -r830213bc6dcc1a684610caf78c79d55f2cb41e93 -r4bb331eccddd3c929266b9c01066347533726774 --- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 830213bc6dcc1a684610caf78c79d55f2cb41e93) +++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 4bb331eccddd3c929266b9c01066347533726774) @@ -78,6 +78,8 @@ F32 getTargetROPumpDutyCyclePCT( void ); U32 getTargetROPumpFlowRateMLPM( void ); F32 getTargetROPumpPressure( void ); +U32 getROPumpLowFlowExemptTimer( void ); +BOOL getROPumpLowFlowExemptFlag( void ); BOOL testROPumpDataPublishIntervalOverride( MESSAGE_T *message ); BOOL testROPumpTargetPressureOverride( MESSAGE_T *message ); Index: firmware/App/Monitors/WaterQualityMonitor.c =================================================================== diff -u -r47a7b0fce13cf38919932a8662c378f4f6a8b9f3 -r4bb331eccddd3c929266b9c01066347533726774 --- firmware/App/Monitors/WaterQualityMonitor.c (.../WaterQualityMonitor.c) (revision 47a7b0fce13cf38919932a8662c378f4f6a8b9f3) +++ firmware/App/Monitors/WaterQualityMonitor.c (.../WaterQualityMonitor.c) (revision 4bb331eccddd3c929266b9c01066347533726774) @@ -26,6 +26,7 @@ #include "SystemCommDD.h" #include "TaskPriority.h" #include "Temperature.h" +#include "Timers.h" #include "WaterQualityMonitor.h" /** @@ -68,7 +69,7 @@ #define PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Verify Water timer ( in ms ) #define PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_CLEAR_MS ( 5 * MS_PER_SECOND ) ///< Verify Water timer ( in ms ) #define PERMEATE_FLOW_FAULT_MIN_THRESHOLD 200.0F ///< Permeate flow low tolerance limit -#define PERMEATE_FLOW_OUT_OF_RANGE_TIMEOUT_MS ( 12 * MS_PER_SECOND ) ///< Permeate flow low tolerance out of range timeout +#define PERMEATE_FLOW_LOW_OUT_OF_RANGE_EXEMPT_MS ( 5 * MS_PER_SECOND ) ///< Permeate flow low alarm exempt for 10 seconds after starting from Off (5 seconds is considered in persistence) #define RO_PUMP_DUTY_CYCLE_WARNING_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Persistence period for duty cycle in warning range in milliseconds. #define RO_PUMP_DUTY_CYCLE_WARNING_CLEAR_MS ( 1 * MS_PER_SECOND ) ///< Persistence period for duty cycle warning range clear in milliseconds. @@ -113,7 +114,7 @@ //Flow Alarms initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_HIGH_RANGE, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_CLEAR_MS, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_TIMEOUT_MS ); // fault , clearing timeout is not applicable - initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, 0, PERMEATE_FLOW_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_CLEAR_MS, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_TIMEOUT_MS ); // duty cycle warning alarm initPersistentAlarm( ALARM_ID_FP_POWER_BUDGET_OUT_OF_RANGE, RO_PUMP_DUTY_CYCLE_WARNING_CLEAR_MS, RO_PUMP_DUTY_CYCLE_WARNING_TIMEOUT_MS ); @@ -197,8 +198,12 @@ BOOL isFlowOutOfRange = FALSE; F32 minimumAllowedPermeateFlow = (F32)getTargetROPumpFlowRateMLPM() - PERMEATE_FLOW_FAULT_MIN_THRESHOLD; - isFlowOutOfRange = ( ( permeateFlow < minimumAllowedPermeateFlow ) ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, isFlowOutOfRange, permeateFlow, minimumAllowedPermeateFlow ); + if ( TRUE == getROPumpLowFlowExemptFlag() && didTimeout( getROPumpLowFlowExemptTimer(), PERMEATE_FLOW_LOW_OUT_OF_RANGE_EXEMPT_MS ) ) + { + isFlowOutOfRange = ( ( permeateFlow < minimumAllowedPermeateFlow ) ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, isFlowOutOfRange, permeateFlow, minimumAllowedPermeateFlow ); + } + } /*********************************************************************//**