Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -reb4850dc520d673985b3e95ddb68ab379a6e816c -re734f2d5dbdf3fa44a46892d1207e1f0859ed242 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision eb4850dc520d673985b3e95ddb68ab379a6e816c) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision e734f2d5dbdf3fa44a46892d1207e1f0859ed242) @@ -23,6 +23,7 @@ #include "MessageSupport.h" #include "PersistentAlarm.h" #include "PIControllers.h" +#include "PIDControllers.h" #include "Pressure.h" #include "ROPump.h" #include "SafetyShutdown.h" @@ -39,32 +40,32 @@ // ********** private definitions ********** #define RO_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO Pump data is published on the CAN bus. -#define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. +#define ROP_CONTROL_INTERVAL ( 300 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. -#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.00009F ///< P term for RO pump flow control. -#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.00018F ///< I term for RO pump flow control. +#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.00010F ///< P term for RO pump flow control. +#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.000075F ///< I term for RO pump flow control. +#define ROP_FLOW_CONTROL_D_COEFFICIENT 0.00070F ///< D term for RO pump flow control #define ROP_MIN_FLOW_TO_CONTROL_PCT 0.75F #define ROP_PRESSURE_CONTROL_P_COEFFICIENT 0.15F ///< P term for RO pump pressure control. #define ROP_PRESSURE_CONTROL_I_COEFFICIENT 0.65F ///< I term for RO pump pressure control. -#define ROP_FLOW_TO_PWM_SLOPE_PERM_FLUSH 117.63F ///< Slope of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_INTERCEPT_PERM_FLUSH -648.05F ///< Intercept of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_SLOPE_NO_RECOVERY 000.00F ///< Slope of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_INTERCEPT_NO_RECOVERY 000.00F ///< Intercept of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_SLOPE_MED_RECOVERY 000.00F ///< Slope of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_INTERCEPT_MED_RECOVERY 000.00F ///< Intercept of flow to PWM line equation for permeate flush. -#define ROP_FLOW_TO_PWM_SLOPE_MAX_RECOVER 202.17F ///< Slope of flow to PWM line equation for max RO recovery. -#define ROP_FLOW_TO_PWM_INTERCEPT_MAX_RECOVER -997.75F ///< Intercept of flow to PWM line equation for max RO recovery. +#define ROP_FLOW_TO_PWM_SLOPE_NO_RECOVERY 0.1621F ///< Slope of flow to PWM line equation for permeate flush. +#define ROP_FLOW_TO_PWM_INTERCEPT_NO_RECOVERY -10.86F ///< Intercept of flow to PWM line equation for permeate flush. +#define ROP_FLOW_TO_PWM_SLOPE_MED_RECOVERY 0.4285F ///< Slope of flow to PWM line equation for permeate flush. +#define ROP_FLOW_TO_PWM_INTERCEPT_MED_RECOVERY 122.45F ///< Intercept of flow to PWM line equation for permeate flush. +#define ROP_FLOW_TO_PWM_SLOPE_MAX_RECOVER 0.2046F ///< Slope of flow to PWM line equation for max RO recovery. +#define ROP_FLOW_TO_PWM_INTERCEPT_MAX_RECOVER 157.0F ///< Intercept of flow to PWM line equation for max RO recovery. #define ROP_PRESSURE_TO_PWM_SLOPE 0.5F ///< Slope of pressure to PWM line equation. #define ROP_PRESSURE_TO_PWM_INTERCEPT 0.0F ///< Intercept of pressure to PWM line equation. #define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. /// PWM line equation for pressure. converted to percentage. #define ROP_PRESSURE_TO_PWM_PCT(pres) ( ( ROP_PRESSURE_TO_PWM_SLOPE * pres + ROP_PRESSURE_TO_PWM_INTERCEPT ) / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) - +/// PWM log equation for flow converted to percentage. +#define ROP_FLOW_TO_PWM_LOG_PCT(slope, intercept, flow) ( ( slope * log(flow) + intercept ) / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) /// PWM line equation for flow converted to percentage. -#define ROP_FLOW_TO_PWM_PCT(slope, intercept, flow) ( ( slope * log(flow) + intercept ) / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) +#define ROP_FLOW_TO_PWM_LIN_PCT(slope, intercept, flow) ( ( slope * flow + intercept ) / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) #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 @@ -110,8 +111,8 @@ initFluidPump(); // Initialize RO pump PI controller to flow - initializePIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_RO_FLOWRATE_MLPM, ROP_FLOW_CONTROL_P_COEFFICIENT, ROP_FLOW_CONTROL_I_COEFFICIENT, - MIN_RO_FLOWRATE_MLPM, MAX_RO_FLOWRATE_MLPM, FALSE, 0 ); + initializePIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, MIN_RO_FLOWRATE_MLPM, ROP_FLOW_CONTROL_P_COEFFICIENT, ROP_FLOW_CONTROL_I_COEFFICIENT, + ROP_FLOW_CONTROL_D_COEFFICIENT, MIN_RO_FLOWRATE_MLPM, MAX_RO_FLOWRATE_MLPM, FALSE, 0 ); // Initialize RO pump PI controller to target pressure initializePIController( PI_CONTROLLER_ID_RO_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, ROP_PRESSURE_CONTROL_P_COEFFICIENT, ROP_PRESSURE_CONTROL_I_COEFFICIENT, @@ -206,7 +207,7 @@ // Set pump to on isROPumpOn = TRUE; roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateMLPM() ); - resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); + resetPIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); roPumpStartControl = FALSE; state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; @@ -269,7 +270,7 @@ { roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateMLPM() ); } - resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); + resetPIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; } // If there is a target pressure set, transition to the PI controller and control to pressure. @@ -328,7 +329,7 @@ // 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 >= ( minRequiredFlowRate ) ) ) { - roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), currentFlowRate ); + roPumpDutyCyclePctSet = runPIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), currentFlowRate ); roPumpDutyCyclePctSet = MIN( roPumpDutyCyclePctSet, ( MAX_FLUID_PUMP_PWM_DUTY_CYCLE * MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ); setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); @@ -358,7 +359,7 @@ // Check if we are changing control if ( getTargetROPumpFlowRateMLPM() > 0 ) { - resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, getTargetROPumpFlowRateMLPM(), 0 ); + resetPIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0 ); state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; } else if ( getTargetROPumpDutyCyclePCT() > 0.0F ) @@ -672,13 +673,31 @@ *************************************************************************/ static F32 roPumpFlowToPWM( U32 targetFlow ) { - F32 dutyCyclePct = ROP_FLOW_TO_PWM_PCT( ROP_FLOW_TO_PWM_SLOPE_MAX_RECOVER, ROP_FLOW_TO_PWM_INTERCEPT_MAX_RECOVER, targetFlow ); + F32 dutyCyclePct = 0.0F; + RECOVERY_STATE_T recovery = getRecoveryState(); if ( FP_PRE_GENP_PERMEATE_FLUSH == getCurrentFPSubMode() && ( FP_MODE_PGEN == getCurrentFPOperationMode() ) ) { - dutyCyclePct = ROP_FLOW_TO_PWM_PCT( ROP_FLOW_TO_PWM_SLOPE_PERM_FLUSH, ROP_FLOW_TO_PWM_INTERCEPT_PERM_FLUSH, targetFlow ); + dutyCyclePct = ROP_FLOW_TO_PWM_LIN_PCT( ROP_FLOW_TO_PWM_SLOPE_NO_RECOVERY, ROP_FLOW_TO_PWM_INTERCEPT_NO_RECOVERY, targetFlow ); } + else + { + switch( recovery ) + { + case NO_RECOVERY: + dutyCyclePct = ROP_FLOW_TO_PWM_LIN_PCT( ROP_FLOW_TO_PWM_SLOPE_NO_RECOVERY, ROP_FLOW_TO_PWM_INTERCEPT_NO_RECOVERY, targetFlow ); + break; + case MEDIUM_RECOVERY: + dutyCyclePct = ROP_FLOW_TO_PWM_LIN_PCT( ROP_FLOW_TO_PWM_SLOPE_MED_RECOVERY, ROP_FLOW_TO_PWM_INTERCEPT_MED_RECOVERY, targetFlow ); + break; + + case MAX_RECOVERY: + default: + dutyCyclePct = ROP_FLOW_TO_PWM_LIN_PCT( ROP_FLOW_TO_PWM_SLOPE_MAX_RECOVER, ROP_FLOW_TO_PWM_INTERCEPT_MAX_RECOVER, targetFlow ); + break; + } + } return dutyCyclePct; } @@ -696,7 +715,7 @@ if( targetROPumpFlowRate.data > 0 ) { targetROPumpFlowRate.data = 0; - resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0.0F ); + resetPIDController( PID_CONTROLLER_ID_RO_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0.0F ); } if( targetROPumpPressure.data > 0.0F )