Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r8f5feed92f41a476d5656038bcdfe884e17bd593 -r53af4ddc318cc5299f15e3cc1ce506b166e6e156 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 8f5feed92f41a476d5656038bcdfe884e17bd593) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 53af4ddc318cc5299f15e3cc1ce506b166e6e156) @@ -60,14 +60,20 @@ #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 ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) ///< conversion factor from target PSI to PWM duty cycle estimate TODO - this is a place holder for real conversion +#define ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) //TODO remove ///< conversion factor from target PSI to PWM duty cycle estimate TODO - this is a place holder for real conversion #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). +#define ROP_FLOW_TO_PWM_DC(flow) ((F32)(flow / 1000)) //TODO dara ///< Initial conversion factor from target flow rate to PWM duty cycle estimate +#define ROP_RAMP_UP_P_COEFFICIENT 0.009 //TODO dara +#define ROP_RAMP_UP_I_COEFFICIENT 0.00 //TODO dara +#define ROP_FLOW_TARGET_TOLERANCE 20U //TODO dara ///< Tolerance in between the target flow rate and the actual flow rate in mL + /// Enumeration of RO pump states. typedef enum ROPump_States { RO_PUMP_OFF_STATE = 0, ///< RO pump off state. + RO_PUMP_RAMP_UP_STATE, ///< RO pump ramp up to target flow rate state. RO_PUMP_CONTROL_TO_TARGET_STATE, ///< RO pump control to target pressure state. NUM_OF_RO_PUMP_STATES ///< Number of RO pump states. } RO_PUMP_STATE_T; @@ -97,10 +103,14 @@ 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 OVERRIDE_U32_T roPumpDataPublishInterval = { 0, 0, 0, 0 }; //From branch Remove ///< interval (in ms) at which to publish RO flow data to CAN bus. +static OVERRIDE_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI). //TODO remove +static OVERRIDE_U32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; //From Branch ///< Target RO flow rate (in LPM_) // TODO dara 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_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI). 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). +static F32 tgtROPumpPressure = 0.0; // TODO dara static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging. static U32 flowFilterCounter = 0; ///< used to schedule flow filtering. @@ -113,6 +123,7 @@ // ********** private function prototypes ********** static RO_PUMP_STATE_T handleROPumpOffState( void ); +static RO_PUMP_STATE_T handleROPumpRampUpState( void ); static RO_PUMP_STATE_T handleROPumpControlToTargetState( void ); static void setROPumpControlSignalPWM( F32 newPWM ); static void stopROPump( void ); @@ -135,6 +146,11 @@ initializePIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_PWM_DUTY_CYCLE, ROP_P_COEFFICIENT, ROP_I_COEFFICIENT, MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE ); + + // Initialize the P controller during ramp up + initializePIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE, + ROP_RAMP_UP_P_COEFFICIENT, ROP_RAMP_UP_I_COEFFICIENT, + MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE ); } /*********************************************************************//** @@ -174,6 +190,24 @@ return result; } +BOOL setROPumpTargetFlowRate( U32 roFlowRate, PUMP_CONTROL_MODE_T mode ) +{ + BOOL result = FALSE; + + if ( roFlowRate < MAX_RO_FLOWRATE && roFlowRate >= MIN_RO_FLOWRATE ) + { + targetROPumpFlowRate.data = roFlowRate; + roPumpControlMode = mode; + roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( roFlowRate ); + } + else // requested pressure out of range + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, 0, roFlowRate ) // TODO - replace 1st param with s/w fault enum + } + + return result; +} + /*********************************************************************//** * @brief * The signalROPumpHardStop function stops the RO pump immediately. @@ -189,6 +223,7 @@ roPumpState = RO_PUMP_OFF_STATE; roPumpPWMDutyCyclePct = 0.0; roControlTimerCounter = 0; + isROPumpOn = FALSE; resetPIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_PWM_DUTY_CYCLE ); } @@ -250,6 +285,10 @@ roPumpState = handleROPumpOffState(); break; + case RO_PUMP_RAMP_UP_STATE: + roPumpState = handleROPumpRampUpState(); + break; + case RO_PUMP_CONTROL_TO_TARGET_STATE: roPumpState = handleROPumpControlToTargetState(); break; @@ -312,8 +351,23 @@ #endif #endif + // If there is a + if ( getTargetROPumpFlowRate() > 0 ) + { + roPumpControlModeSet = roPumpControlMode; + // set initial PWM duty cycle + roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; + setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); + // reset controller + resetPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, roPumpPWMDutyCyclePctSet ); + // set pump to on + isROPumpOn = TRUE; + result = RO_PUMP_RAMP_UP_STATE; + } + + // TODO remove // if we've been given a pressure, transition to control to target state - if ( getTargetROPumpPressure() > 0 ) + /*if ( getTargetROPumpPressure() > 0 ) { roPumpControlModeSet = roPumpControlMode; // set initial PWM duty cycle @@ -324,6 +378,49 @@ // set pump to on isROPumpOn = TRUE; result = RO_PUMP_CONTROL_TO_TARGET_STATE; + }*/ + + return result; +} + +static RO_PUMP_STATE_T handleROPumpRampUpState( void ) +{ + RO_PUMP_STATE_T result = RO_PUMP_RAMP_UP_STATE; + + // control at set interval + if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) + { + F32 targetFlowRate = targetROPumpFlowRate.data; + + if ( OVERRIDE_KEY == targetROPumpFlowRate.override ) + { + targetFlowRate = targetROPumpFlowRate.ovData; + } + + F32 actualFlowRate = (F32)getMeasuredROFlowRate(); + + if ( fabs( actualFlowRate - targetFlowRate ) > ROP_FLOW_TARGET_TOLERANCE ) + { + F32 newPWM = runPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, targetFlowRate, actualFlowRate ); + roPumpPWMDutyCyclePctSet = newPWM; + setROPumpControlSignalPWM( newPWM ); + } + else + { + // Reset the P controller for the flow rate + resetPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE ); + tgtROPumpPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); + + roPumpControlModeSet = roPumpControlMode; + // set initial PWM duty cycle + roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; + setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); + // reset controller + resetPIController( PI_CONTROLLER_ID_RO_PUMP, roPumpPWMDutyCyclePctSet ); + + result = RO_PUMP_CONTROL_TO_TARGET_STATE; + } + roControlTimerCounter = 0; } return result; @@ -347,7 +444,7 @@ { if ( roPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) { - F32 tgtPres = (F32)getTargetROPumpPressure(); + F32 tgtPres = tgtROPumpPressure; F32 actPres = measuredROPumpPressure; F32 newPWM; @@ -439,13 +536,14 @@ * Outputs : none * @return the current target RO pressure (in PSI). *************************************************************************/ -U32 getTargetROPumpPressure( void ) +//U32 getTargetROPumpPressure( void ) +U32 getTargetROPumpFlowRate( void ) { - U32 result = targetROPumpPressure.data; + U32 result = targetROPumpFlowRate.data; - if ( OVERRIDE_KEY == targetROPumpPressure.override ) + if ( OVERRIDE_KEY == targetROPumpFlowRate.override ) { - result = targetROPumpPressure.ovData; + result = targetROPumpFlowRate.ovData; } return result; @@ -486,10 +584,11 @@ // publish RO pump data on interval if ( ++roPumpDataPublicationTimerCounter >= getPublishROPumpDataInterval() ) { - U32 presStPt = getTargetROPumpPressure(); + //U32 presStPt = getTargetROPumpPressure(); + F32 targetPressure = tgtROPumpPressure; F32 measFlow = getMeasuredROFlowRate(); F32 pumpPWMPctDutyCycle = roPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; - broadcastROPumpData( presStPt, measFlow, pumpPWMPctDutyCycle ); + broadcastROPumpData( targetPressure, measFlow, pumpPWMPctDutyCycle ); roPumpDataPublicationTimerCounter = 0; } } @@ -593,6 +692,37 @@ return result; } +BOOL testSetTargetROPumpFlowRateOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + targetROPumpFlowRate.ovInitData = targetROPumpFlowRate.data; // backup current target pressure + targetROPumpFlowRate.ovData = value; + targetROPumpFlowRate.override = OVERRIDE_KEY; + result = setROPumpTargetFlowRate( value, roPumpControlMode ); + } + + return result; +} + +BOOL testResetTargetROPumpFlowRateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + targetROPumpFlowRate.data = targetROPumpFlowRate.ovInitData; // restore pre-override target pressure + targetROPumpFlowRate.override = OVERRIDE_RESET; + targetROPumpFlowRate.ovInitData = 0; + targetROPumpFlowRate.ovData = 0; + result = setROPumpTargetFlowRate( targetROPumpFlowRate.data, roPumpControlMode ); + } + + return result; +} + /*********************************************************************//** * @brief * The testResetTargetROPumpPressureOverride function resets the override of the \n