Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r2f2d0ccadd8a09037eb3d0dd144549b2c8c8129b -rd3671cad1447db7ad496ad6282324ef7570c5625 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 2f2d0ccadd8a09037eb3d0dd144549b2c8c8129b) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision d3671cad1447db7ad496ad6282324ef7570c5625) @@ -54,19 +54,19 @@ #define ROP_I_COEFFICIENT 0.0015 ///< I term for RO pump pressure control #define ROP_RAMP_UP_P_COEFFICIENT 0.0 ///< P term for RO pump flow control -#define ROP_RAMP_UP_I_COEFFICIENT 0.01 ///< I term for RO pump flow control +#define ROP_RAMP_UP_I_COEFFICIENT 0.1 ///< I term for RO pump flow control #define ROP_FLOW_TARGET_TOLERANCE 0.05 ///< Tolerance in between the target flow rate and the actual flow rate in liter #define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor) -#define FLOW_SAMPLES_TO_AVERAGE (250 / TASK_PRIORITY_INTERVAL) ///< Averaging flow data over 250 ms intervals. -#define FLOW_AVERAGE_MULTIPLIER (1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE) ///< Optimization - multiplying is faster than dividing +#define FLOW_SAMPLES_TO_AVERAGE ( 250 / TASK_PRIORITY_INTERVAL ) ///< Averaging flow data over 250 ms intervals. +#define FLOW_AVERAGE_MULTIPLIER ( 1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing #define FLOW_VERIFICATION_COUNTER_TARGET 40U ///< The time in counts to check the flow and make sure it is in range #define RO_FLOW_ADC_TO_LPM_FACTOR 10909.0909 ///< conversion factor from ADC counts to LPM (liters/min) for RO flow rate (multiply this by inverse of FPGA reading). // Initial PWM for the requested flow rate. It is assumed that 100% duty cycle will provide 1.2 LPM -#define ROP_FLOW_TO_PWM_DC(flow) ((F32)(flow / 1.2)) ///< Initial conversion factor from target flow rate to PWM duty cycle estimate +#define ROP_FLOW_TO_PWM_DC(flow) ( (F32)(flow / 1.2) ) ///< Initial conversion factor from target flow rate to PWM duty cycle estimate #define MAX_RO_PUMP_PWM_STEP_CHANGE 0.01 ///< Max duty cycle change for controller. #define MAX_RO_PUMP_PWM_DUTY_CYCLE 0.99 ///< Max duty cycle. @@ -78,8 +78,8 @@ #define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor). -#define FLOW_SAMPLES_TO_AVERAGE (250 / TASK_PRIORITY_INTERVAL) ///< Averaging flow data over 250 ms intervals. -#define FLOW_AVERAGE_MULTIPLIER (1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE) ///< Optimization - multiplying is faster than dividing. +#define FLOW_SAMPLES_TO_AVERAGE ( 250 / TASK_PRIORITY_INTERVAL ) ///< Averaging flow data over 250 ms intervals. +#define FLOW_AVERAGE_MULTIPLIER ( 1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing. // TODO - this is a place holder for real conversion #define ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) ///< conversion factor from target PSI to PWM duty cycle estimate. @@ -118,24 +118,22 @@ static BOOL isROPumpOn = FALSE; ///< RO pump is currently running static F32 roPumpPWMDutyCyclePct = 0.0; ///< initial RO pump PWM duty cycle static F32 roPumpPWMDutyCyclePctSet = 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 //TODO remove +static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested RO pump control mode //TODO remove? static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set RO pump control mode static OVERRIDE_F32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; ///< Target RO flow rate (in LPM) 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 LPM) -static F32 measuredROPumpPressure = 0.0; ///< measured RO pressure (in PSI) // TODO remove -static F32 tgtROPumpPressure = 0.0; ///< Target RO control pressure (in PSI) 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 U32 roControlTimerCounter = 0; ///< determines when to perform control on RO pump -static U32 roPumpOpenLoopTargetPWM = 0; ///< Target RO pump open loop PWM -static F32 roPumpFlowRateRunningSum = 0; -static F32 roPumpPressureRunningSum = 0; +static F32 roPumpOpenLoopTargetPWM = 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 /* The variables used for POST. They are not in use yet, so they are commented out static RO_PUMP_SELF_TEST_STATE_T roPumpSelfTestState = RO_PUMP_SELF_TEST_STATE_START; ///< current ro pump self test state @@ -147,10 +145,6 @@ static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging. static U32 flowFilterCounter = 0; ///< Flow filtering counter. - -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. - // ********** private function prototypes ********** static RO_PUMP_STATE_T handleROPumpOffState( void ); @@ -233,14 +227,15 @@ * @param: pwm * @return whether the value was set (TRUE) or not (FALSE) *************************************************************************/ -BOOL setROPumpTargetPWM( U32 pwm ) +BOOL setROPumpTargetPWM( F32 pwm ) { BOOL result = FALSE; if ( pwm > 0 ) { roPumpOpenLoopTargetPWM = pwm; - roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( getTargetROPumpFlowRate() ); + roPumpPWMDutyCyclePct = roPumpOpenLoopTargetPWM; //ROP_FLOW_TO_PWM_DC( getTargetROPumpFlowRate() ); + roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; roPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; result = TRUE; } @@ -257,14 +252,15 @@ * @param: roFlowRate : new target RO flow rate * @return TRUE if new target flow rate is set, FALSE if not *************************************************************************/ -BOOL setROPumpTargetFlowRate( F32 roFlowRate ) +BOOL setROPumpTargetFlowRate( F32 roFlowRate, F32 maxPressure ) { BOOL result = FALSE; if ( roFlowRate < MAX_RO_FLOWRATE_LPM && roFlowRate >= MIN_RO_FLOWRATE_LPM ) { - tgtROPumpPressure = 0.0; - targetROPumpPressure.data = 0.0; + // For now maximum allowed pressure is inserted into the target pressure override + // if the target flow rate exceeded the max pressure, it will set the maximum pressure + targetROPumpPressure.data = maxPressure; targetROPumpFlowRate.data = roFlowRate; roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( roFlowRate ); @@ -295,7 +291,8 @@ targetROPumpFlowRate.data = 0; stopROPump(); roPumpState = RO_PUMP_OFF_STATE; - roPumpPWMDutyCyclePct = 0.0; + roPumpPWMDutyCyclePct = 0.0; + roPumpOpenLoopTargetPWM = 0.0; roControlTimerCounter = 0; flowVerificationCounter = 0; isROPumpOn = FALSE; @@ -315,13 +312,15 @@ U16 roFlowReading = getFPGAROPumpFlowRate(); S32 roFlow = (S32)roFlowReading; - // update sum for flow average calculation + // Update sum for flow average calculation measuredFlowReadingsSum += roFlow; - // filter every 250ms + // Filter every 250ms if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE ) { F32 avgROFlow = (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER; - + + // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that + // the flow is 0 if ( ( roFlowReading == FLOW_SENSOR_ZERO_READING ) || ( roFlowReading == 0 ) ) { measuredROFlowRateLPM.data = 0.0; @@ -334,7 +333,7 @@ flowFilterCounter = 0; } - measuredROPumpPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); + //measuredROPumpPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); TODO what do we do with this? // TODO - check pressure? @@ -435,7 +434,7 @@ #endif // If there is a flow, transition to P controller to get the corresponding pressure of that flow - if ( getTargetROPumpFlowRate() > 0 && roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP ) + if ( getTargetROPumpFlowRate() > 0 && roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP ) { roPumpControlModeSet = roPumpControlMode; // Set initial PWM duty cycle @@ -471,7 +470,7 @@ { RO_PUMP_STATE_T result = RO_PUMP_RAMP_UP_STATE; - // control at set interval + // Control at set interval if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) { F32 targetFlowRate = getTargetROPumpFlowRate(); @@ -516,26 +515,33 @@ // Check if the time for flow verification has elapsed if ( ++flowVerificationCounter >= FLOW_VERIFICATION_COUNTER_TARGET ) { - // Calculate the average pressure and flow rate - F32 avgPressure = roPumpPressureRunningSum / flowVerificationCounter; - F32 avgFlowRate = roPumpFlowRateRunningSum / flowVerificationCounter; + F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - F32 targetFlowRate = getTargetROPumpFlowRate(); + // If the flow has been achieved without reaching to the maximum pressure, set the new pressure + // otherwise, stay with the maximum allowed pressure as target pressure + if ( actualPressure < getTargetROPumpPressure() ) + { + // Calculate the average pressure and flow rate + F32 avgPressure = roPumpPressureRunningSum / flowVerificationCounter; + F32 avgFlowRate = roPumpFlowRateRunningSum / flowVerificationCounter; - // Calculate the flow rate deviation from the target flow rate - F32 flowRateDeviation = ( targetFlowRate - avgFlowRate ) / targetFlowRate; - // Use the flow rate deviation to adjust the average calculated pressure. This - // pressure is used as the target pressure - avgPressure = avgPressure + ( avgPressure * flowRateDeviation ); + F32 targetFlowRate = getTargetROPumpFlowRate(); + // Calculate the flow rate deviation from the target flow rate + F32 flowRateDeviation = ( targetFlowRate - avgFlowRate ) / targetFlowRate; + // Use the flow rate deviation to adjust the average calculated pressure. This + // pressure is used as the target pressure + avgPressure = avgPressure + ( avgPressure * flowRateDeviation ); + + targetROPumpPressure.data = avgPressure; + } + // Reset the P controller for the flow rate resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE ); - tgtROPumpPressure = avgPressure; - // set initial PWM duty cycle - //roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; + // Set initial PWM duty cycle setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); - // reset controller + // Reset controller resetPIController( PI_CONTROLLER_ID_RO_PUMP, roPumpPWMDutyCyclePctSet ); flowVerificationCounter = 0; roPumpFlowRateRunningSum = 0; @@ -564,9 +570,9 @@ { F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - F32 newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, tgtROPumpPressure, actualPressure ); + F32 newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, getTargetROPumpPressure(), actualPressure ); roPumpPWMDutyCyclePctSet = newPWM; - setROPumpControlSignalPWM( newPWM ); + setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); #ifndef EMC_TEST_BUILD newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, tgtPres, actPres ); @@ -699,6 +705,18 @@ } return result; +} + +F32 getTargetROPumpPressure( void ) +{ + F32 result = targetROPumpPressure.data; + + if ( OVERRIDE_KEY == targetROPumpPressure.override ) + { + result = targetROPumpPressure.ovData; + } + + return result; } /*********************************************************************//** @@ -716,7 +734,7 @@ { RO_PUMP_DATA_T pumpData; - pumpData.roPumpTgtPressure = tgtROPumpPressure; + pumpData.roPumpTgtPressure = getTargetROPumpPressure(); pumpData.measROFlowRate = getMeasuredROFlowRate(); pumpData.roPumpPWM = roPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; pumpData.roPumpState = (U32)roPumpState; @@ -817,7 +835,7 @@ targetROPumpFlowRate.ovInitData = targetROPumpFlowRate.data; // backup current target pressure targetROPumpFlowRate.ovData = value; targetROPumpFlowRate.override = OVERRIDE_KEY; - result = setROPumpTargetFlowRate( value ); + //result = setROPumpTargetFlowRate( value ); } return result; @@ -842,7 +860,7 @@ targetROPumpFlowRate.override = OVERRIDE_RESET; targetROPumpFlowRate.ovInitData = 0; targetROPumpFlowRate.ovData = 0; - result = setROPumpTargetFlowRate( targetROPumpFlowRate.data ); + //result = setROPumpTargetFlowRate( targetROPumpFlowRate.data ); } return result;