Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r9f79bc2ee4ab3e5b3b14c4a1d9c337af5d001ebd -r19dd28ed9c1c81d3bbf50e7a6bf691f19be0b54e --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 9f79bc2ee4ab3e5b3b14c4a1d9c337af5d001ebd) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 19dd28ed9c1c81d3bbf50e7a6bf691f19be0b54e) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* Copyright (c) 2025-2026 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 ROPump.c * * @author (last) “rkallala” -* @date (last) 09-Dec-2025 +* @date (last) 20-Jan-2026 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -61,7 +61,8 @@ #define ROP_FLOW_TO_PWM(slope, intercept, flow) ( slope * log(flow) + intercept ) ///< PWM line equation for flow converted to percentage. #define FP_FLOW_RATE_BELOW_TARGET_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Timeout for flow rate below 75% of target flow rate -#define FP_FLOW_RATE_BELOW_TARGET_CLEAR_MS ( 10 * MS_PER_SECOND ) ///< Clear timeout for flow rate below target flow rate +#define FP_FLOW_RATE_BELOW_TARGET_CLEAR_MS ( 10 * MS_PER_SECOND ) ///< Clear timeout for flow rate below target flow rate +#define PERMEATE_FLOW_LOW_OUT_OF_RANGE_EXEMPT_MS ( 10 * MS_PER_SECOND ) ///< Permeate flow low alarm exempt for 10 seconds after starting from Off // ********** private data ********** @@ -76,6 +77,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 timeSinceP12Started; ///< Time when RO pump is started from off state. // ********** private function prototypes ********** @@ -84,6 +86,7 @@ static RO_PUMP_STATE_T handleROPumpControlToTargetPressureState( void ); static RO_PUMP_STATE_T handleROPumpOpenLoopState( void ); +static U32 getROPumpLowFlowExemptTimer( void ); static F32 roPumpPresToPWM( F32 targetPressure ); static F32 roPumpFlowToPWM( U32 targetFlow ); static void stopROPump( void ); @@ -92,9 +95,7 @@ /*********************************************************************//** * @brief * The initROPump function initializes the RO Pump module. - * @details \b Inputs: roPumpState, roPumpControlMode, isROPumpOn, stopPumpRequest, - * roControlTimerCounter, roPumpDutyCyclePctSet, roPumpOpenLoopTargetDutyCycle, roPumpDataPublicationTimerCounter, - * roPumpDataPublishInterval, targetROPumpFlowRate, targetROPumpPressure + * @details \b Inputs: none * @details \b Outputs: RO Pump controller unit initialized * @return none *************************************************************************/ @@ -110,8 +111,6 @@ initializePIController( PI_CONTROLLER_ID_RO_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, ROP_PRESSURE_CONTROL_P_COEFFICIENT, ROP_PRESSURE_CONTROL_I_COEFFICIENT, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); - initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_RATE_BELOW_TARGET, FP_FLOW_RATE_BELOW_TARGET_CLEAR_MS, FP_FLOW_RATE_BELOW_TARGET_TIMEOUT_MS ); - roPumpState = RO_PUMP_OFF_STATE; isROPumpOn = FALSE; stopPumpRequest = FALSE; @@ -135,6 +134,7 @@ roPumpOpenLoopTargetDutyCycle.ovData = 0.0; roPumpOpenLoopTargetDutyCycle.ovInitData = 0.0; roPumpOpenLoopTargetDutyCycle.override = OVERRIDE_RESET; + timeSinceP12Started = 0; stopROPump(); } @@ -192,6 +192,7 @@ { RO_PUMP_STATE_T state = RO_PUMP_OFF_STATE; isROPumpOn = FALSE; + timeSinceP12Started = 0; // If there is a target flow set, transition to the PI controller and control to flow if ( getTargetROPumpFlowRateMLPM() > 0 ) @@ -224,6 +225,11 @@ state = RO_PUMP_OPEN_LOOP_STATE; } + if ( state != RO_PUMP_OFF_STATE ) + { + timeSinceP12Started = getMSTimerCount(); + } + return state; } @@ -286,10 +292,8 @@ static RO_PUMP_STATE_T handleROPumpControlToTargetFlowState( void ) { RO_PUMP_STATE_T state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; - F32 nexttgtflow = 0.0; - F32 currentFlowRate = 0.0; - F32 adjustedFlowRRate = 0.0; - BOOL isFlowRateLow = FALSE; + F32 currentFlowRate = 0.0F; + F32 minRequiredFlowRate = 0.0F; // Check if need to switch control modes if ( getTargetROPumpPressure() > 0.0F ) @@ -313,10 +317,10 @@ else if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) { currentFlowRate = getFilteredFlow( P16_FLOW ); - adjustedFlowRRate = (F32)getTargetROPumpFlowRateMLPM() * ROP_MIN_FLOW_TO_CONTROL_PCT; + minRequiredFlowRate = (F32)getTargetROPumpFlowRateMLPM() * ROP_MIN_FLOW_TO_CONTROL_PCT; // P16 flow seems to lag in current Leahi HW. We will wait till we hit a % of target flow before we start changing control. - if( ( TRUE == roPumpStartControl ) || ( currentFlowRate >= ( adjustedFlowRRate ) ) ) + if( ( TRUE == roPumpStartControl ) || ( currentFlowRate >= ( minRequiredFlowRate ) ) ) { roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), currentFlowRate ); roPumpDutyCyclePctSet = MIN( roPumpDutyCyclePctSet, ( MAX_FLUID_PUMP_PWM_DUTY_CYCLE * MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ); @@ -328,11 +332,6 @@ } } roControlTimerCounter = 0; - - //is flow rate less than 75% of the target flow rate - // wait for 10 seconds for timeout - isFlowRateLow = ( ( currentFlowRate < ( adjustedFlowRRate ) ) ? TRUE : FALSE); - checkPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_RATE_BELOW_TARGET, isFlowRateLow, currentFlowRate, adjustedFlowRRate); } return state; @@ -609,6 +608,39 @@ /*********************************************************************//** * @brief + * The isROPumpLowflowAlarmExempt function gets the flag whether or not + * to exempt the low flow alarm. + * @details \b Inputs: none + * @details \b Outputs: none + * @return TRUE if low flow alarm is exempt, FALSE if not. + *************************************************************************/ +BOOL isROPumpLowflowAlarmExempt( void ) +{ + BOOL result = FALSE; + + if ( ( roPumpState == RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE ) && ( FALSE == didTimeout( getROPumpLowFlowExemptTimer(), PERMEATE_FLOW_LOW_OUT_OF_RANGE_EXEMPT_MS ) ) ) + { + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @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). + *************************************************************************/ +static U32 getROPumpLowFlowExemptTimer( void ) +{ + return timeSinceP12Started; +} + +/*********************************************************************//** + * @brief * The roPumpPresToPWM function calculates the duty cycle for the given target * pressure. * @details \b Inputs: none