Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -re0265b8fad80add7a5d54db11ecc72fd6b1665a8 -r9f403b860d7767f4fb07e13692ccdc9852a42105 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision e0265b8fad80add7a5d54db11ecc72fd6b1665a8) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 9f403b860d7767f4fb07e13692ccdc9852a42105) @@ -20,12 +20,14 @@ #include "etpwm.h" #include "mibspi.h" +#include "AlarmDefs.h" #include "FPGA.h" #include "OperationModes.h" #include "PIControllers.h" #include "PersistentAlarm.h" #include "Pressures.h" #include "ROPump.h" +#include "SafetyShutdown.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -70,16 +72,15 @@ #define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor). #define MAX_ALLOWED_FLOW_DEVIATION 0.1 ///< Max allowed deviation from target flow. -#define FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL 5 * MS_PER_SECOND ///< Flow out of range time out in counts. +#define FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL ( 5 * MS_PER_SECOND ) ///< Flow out of range time out in counts. #define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. #define MAX_ALLOWED_PRESSURE_PSI 130 ///< Maximum allowed pressure that the RO pump can go to. #define MIN_ALLOWED_PRESSURE_PSI 10 ///< Minimum allowed pressure that the RO pump can go to. #define MAX_ALLOWED_MEASURED_PRESSURE_PSI 135 ///< Maximum allowed pressure that the sensor measures. RO pump shut off pressure is 140psi. #define MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL MS_PER_SECOND ///< Maximum allowed time that the pressure can be very high. -#define MAX_ALLOWED_RAMP_UP_TIME ( 30 * MS_PER_SECOND ) ///< Maximum allowed ramp up time to a flow rate in ms. -#define RAMP_UP_TIME_OUT_COUNT ( MAX_ALLOWED_RAMP_UP_TIME / \ - TASK_GENERAL_INTERVAL ) ///< Ramp up time out in counts. -#define ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) ///< conversion factor from target PSI to PWM duty cycle estimate. TODO remove? +#define MAX_ALLOWED_RAMP_UP_TIME ( 5 * MS_PER_SECOND ) ///< Maximum allowed ramp up time to a flow rate in ms. +#define ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) ///< conversion factor from target PSI to PWM duty cycle estimate. +#define SAFETY_SHUTDOWN_TIMEOUT ( 2 * MS_PER_SECOND ) ///< RO pump safety shutdown activation timeout in ms. /// Enumeration of RO pump states. typedef enum ROPump_States @@ -103,36 +104,35 @@ // ********** private data ********** -static RO_PUMP_STATE_T roPumpState = RO_PUMP_OFF_STATE; ///< current state of RO pump controller state machine -static U32 roPumpDataPublicationTimerCounter = 0; ///< used to schedule RO pump data publication to CAN bus -static BOOL isROPumpOn = FALSE; ///< RO pump is currently running -static F32 roPumpPWMDutyCyclePct = 0.0; ///< initial RO pump PWM duty cycle -static F32 roPumpDutyCyclePctSet = 0.0; ///< currently set RO pump PWM duty cycle -static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested RO pump control mode -static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set RO pump control mode +static RO_PUMP_STATE_T roPumpState = RO_PUMP_OFF_STATE; ///< current state of RO pump controller state machine. +static U32 roPumpDataPublicationTimerCounter = 0; ///< used to schedule RO pump data publication to CAN bus. +static BOOL isROPumpOn = FALSE; ///< RO pump is currently running. +static F32 roPumpPWMDutyCyclePct = 0.0; ///< initial RO pump PWM duty cycle. +static F32 roPumpDutyCyclePctSet = 0.0; ///< currently set RO pump PWM duty cycle. +static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested RO pump control mode. +static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set RO pump control mode. -static F32 targetROPumpFlowRate = 0.0; ///< Target RO flow rate (in L/min) -static U32 targetROPumpPressure = 0; ///< Target RO pressure (in PSI) +static F32 targetROPumpFlowRate = 0.0; ///< Target RO flow rate (in L/min). +static U32 targetROPumpPressure = 0; ///< Target RO pressure (in PSI). static OVERRIDE_U32_T roPumpDataPublishInterval = { RO_PUMP_DATA_PUB_INTERVAL, RO_PUMP_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish RO flow data to CAN bus -static OVERRIDE_F32_T measuredROFlowRateLPM = { 0.0, 0.0, 0.0, 0 }; ///< measured RO flow rate (in L/min) + 0, 0 }; ///< Interval (in ms) at which to publish RO flow data to CAN bus. +static OVERRIDE_F32_T measuredROFlowRateLPM = { 0.0, 0.0, 0.0, 0 }; ///< measured RO flow rate (in L/min). -static U32 flowVerificationCounter = 0; ///< Counter to verify the flow is in range -static U32 roControlTimerCounter = 0; ///< determines when to perform control on RO pump -static F32 roPumpOpenLoopTargetDutyCycle = 0; ///< Target RO pump open loop PWM -static F32 roPumpFlowRateRunningSum = 0; ///< RO pump flow rate running sum -static F32 roPumpPressureRunningSum = 0; ///< RO pump pressure running sum +static U32 flowVerificationCounter = 0; ///< Counter to verify the flow is in range. +static U32 roControlTimerCounter = 0; ///< determines when to perform control on RO pump. +static F32 roPumpOpenLoopTargetDutyCycle = 0; ///< Target RO pump open loop PWM. +static F32 roPumpFlowRateRunningSum = 0; ///< RO pump flow rate running sum. +static F32 roPumpPressureRunningSum = 0; ///< RO pump pressure running sum. /* TODO These variables are used for POST. POST has not been implemented yet -static RO_PUMP_SELF_TEST_STATE_T roPumpSelfTestState = RO_PUMP_SELF_TEST_STATE_START; ///< Current ro pump self test state -static U32 roPumpSelfTestTimerCount = 0; ///< Timer counter for ro pump self test +static RO_PUMP_SELF_TEST_STATE_T roPumpSelfTestState = RO_PUMP_SELF_TEST_STATE_START; ///< Current RO pump self test state. +static U32 roPumpSelfTestTimerCount = 0; ///< Timer counter for RO pump self test. */ -static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging -static U32 flowFilterCounter = 0; ///< Flow filtering counter -static U32 rampUp2FlowTimeoutCounter = 0; ///< Counter for ramping up to flow time +static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging. +static U32 flowFilterCounter = 0; ///< Flow filtering counter. // ********** private function prototypes ********** @@ -151,8 +151,11 @@ /*********************************************************************//** * @brief * The initROPump function initializes the RO Pump module. - * @details Inputs: rampUp2FlowTimeoutCounter - * @details Outputs: rampUp2FlowTimeoutCounter + * @details Inputs: roControlTimerCounter,roPumpOpenLoopTargetDutyCycle, + * roPumpFlowRateRunningSum, roPumpPressureRunningSum, measuredFlowReadingsSum, + * flowFilterCounter, flowVerificationCounter, roPumpState, roPumpControlMode + * roPumpDataPublicationTimerCounter, roPumpControlModeSet + * @details Outputs: none * @return none *************************************************************************/ void initROPump( void ) @@ -178,15 +181,20 @@ initPersistentAlarm( PERSISTENT_ALARM_RO_PUMP_PRESSURE_OUT_OF_RANGE, ALARM_ID_RO_PUMP_PRESSURE_OUT_OF_RANGE, TRUE, MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL, MAX_PRESSURE_OUT_OF_RANGE_PERSISTENT_INTERVAL ); + // Initialize the persistent alarm for ramp up to target flow timeout + initPersistentAlarm( PERSISTENT_ALARM_RO_PUMP_RAMP_UP_TO_TARGET_FLOW_TIMEOUT, ALARM_ID_RO_PUMP_RAMP_UP_TO_FLOW_TIMEOUT, TRUE, + MAX_ALLOWED_RAMP_UP_TIME, MAX_ALLOWED_RAMP_UP_TIME ); + + // Initialize the persistent alarm for not turning off the pump + initPersistentAlarm( PERSISTEMT_ALARM_RO_PUMP_OFF_ERROR, ALARM_ID_RO_PUMP_OFF_FAULT, TRUE, SAFETY_SHUTDOWN_TIMEOUT, SAFETY_SHUTDOWN_TIMEOUT ); + // Initialize the variables - rampUp2FlowTimeoutCounter = 0; roControlTimerCounter = 0; roPumpOpenLoopTargetDutyCycle = 0; roPumpFlowRateRunningSum = 0; roPumpPressureRunningSum = 0; measuredFlowReadingsSum = 0; flowFilterCounter = 0; - rampUp2FlowTimeoutCounter = 0; flowVerificationCounter = 0; roPumpDataPublicationTimerCounter = 0; roPumpState = RO_PUMP_OFF_STATE; @@ -224,7 +232,6 @@ roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; // Get the initial guess of the duty cycle roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( roFlowRate ); - rampUp2FlowTimeoutCounter = 0; result = TRUE; } // Requested max pressure is out of range @@ -264,7 +271,6 @@ roControlTimerCounter = 0; flowVerificationCounter = 0; isROPumpOn = FALSE; - rampUp2FlowTimeoutCounter = 0; targetROPumpPressure = 0; resetPIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_DUTY_CYCLE ); } @@ -316,9 +322,9 @@ // meaning, it is controlling to a certain pressure if ( roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP && roPumpState == RO_PUMP_CONTROL_TO_TARGET_STATE ) { - F32 currentFlow = getMeasuredROFlowRate(); - F32 targetFlow = getTargetROPumpFlowRate(); - F32 error = fabs( 1.0 - ( currentFlow / targetFlow ) ); + F32 currentFlow = getMeasuredROFlowRate(); + F32 targetFlow = getTargetROPumpFlowRate(); + F32 error = fabs( 1.0 - ( currentFlow / targetFlow ) ); // Figure out whether flow is out of range from which side if ( error > MAX_ALLOWED_FLOW_DEVIATION ) @@ -330,6 +336,21 @@ } } + // If the pump is off and PPi + 5psi < PPo for a certain period of time, activate safety shutdown + if ( FALSE == isROPumpOn ) + { + F32 pressureInlet = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); + BOOL isPumpRunning = ( pressureInlet + MAX_PRESSURE_TARGET_TOLERANCE ) < actualPressure; + + checkPersistentAlarm( PERSISTEMT_ALARM_RO_PUMP_OFF_ERROR, isPumpRunning, pressureInlet, ( pressureInlet + MAX_PRESSURE_TARGET_TOLERANCE ) ); + + // Check if it has timed out + if ( isAlarmActive( ALARM_ID_RO_PUMP_OFF_FAULT ) ) + { + activateSafetyShutdown(); + } + } + // Publish RO pump data on interval publishROPumpData(); } @@ -389,9 +410,8 @@ * @brief * The execROPumpTest function executes the state machine for the RO pump * self-test. - * @details - * Inputs: TODO FILL UP - * Outputs: TODO FILL UP + * @details Inputs: TODO FILL UP + * @details Outputs: TODO FILL UP * @return the current state of the ROPump self test. *************************************************************************/ SELF_TEST_STATUS_T execROPumpTest( void ) @@ -459,26 +479,34 @@ // Get the current pressure from the sensor F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); + F32 targetFlowRate = getTargetROPumpFlowRate(); + F32 actualFlowRate = (F32)getMeasuredROFlowRate(); - // If we are still in the ramp up mode after the specified time, get the current pressure - // and control from this - if ( ++rampUp2FlowTimeoutCounter > RAMP_UP_TIME_OUT_COUNT ) + BOOL isFlowInRange = fabs( targetFlowRate - actualFlowRate ) > ROP_FLOW_TARGET_TOLERANCE; + + // Check if the ramp up has timed out + checkPersistentAlarm( PERSISTENT_ALARM_RO_PUMP_RAMP_UP_TO_TARGET_FLOW_TIMEOUT, isFlowInRange, actualFlowRate, MAX_ALLOWED_RAMP_UP_TIME ); + + // If the ramp up persistent alarm is active, turn off the pump and go to off state + if ( isAlarmActive( ALARM_ID_RO_PUMP_RAMP_UP_TO_FLOW_TIMEOUT ) ) { - targetROPumpPressure = actualPressure; - rampUp2FlowTimeoutCounter = 0; - result = RO_PUMP_CONTROL_TO_TARGET_STATE; + stopROPump(); + result = RO_PUMP_OFF_STATE; } // Control at set interval else if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) { - F32 targetFlowRate = getTargetROPumpFlowRate(); - F32 actualFlowRate = (F32)getMeasuredROFlowRate(); + F32 targetPressure = getTargetROPumpPressure(); // If the actual pressure is greater than the target pressure or it is within the tolerance of the maximum pressure, move to set // to target pressure straight. At the beginning the maximum pressure is set in the targetROPumpPressure override variable. // If the flow rate was reached without reaching to maximum pressure, the pressure that was set to targetROPumpPressure override will // be reset to the corresponding pressure of the target flow rate. +<<<<<<< HEAD if ( actualPressure > getTargetROPumpPressure() || ( getTargetROPumpPressure() - actualPressure ) < MAX_PRESSURE_TARGET_TOLERANCE ) +======= + if ( ( actualPressure > targetPressure ) || ( ( targetPressure - actualPressure ) < MAX_PRESSURE_TARGET_TOLERANCE ) ) +>>>>>>> staging { result = RO_PUMP_CONTROL_TO_TARGET_STATE; }