Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r22176ce95e49213c48454f34ddf5d29b8109f2cb -r87ebf31788a90216c65e0264e2b8cb21d25e5b9b --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 22176ce95e49213c48454f34ddf5d29b8109f2cb) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 87ebf31788a90216c65e0264e2b8cb21d25e5b9b) @@ -8,7 +8,7 @@ * @file ROPump.c * * @author (last) Dara Navaei -* @date (last) 25-May-2022 +* @date (last) 03-Aug-2022 * * @author (original) Sean * @date (original) 04-Apr-2020 @@ -55,8 +55,8 @@ #define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. #define ROP_RAMP_UP_CONTROL_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. #define ROP_RAMP_UP_P_COEFFICIENT 0.22F ///< P term for RO pump ramp up to flow control. -#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.25F ///< P term for RO pump flow control. -#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.25F ///< I term for RO pump flow control. +#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.4F ///< P term for RO pump flow control. +#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.05F ///< I term for RO pump flow control. #define ROP_MAX_PRESSURE_P_COEFFICIENT 0.01F ///< P term for RO pump max pressure control. #define ROP_MAX_PRESSURE_I_COEFFICIENT 0.01F ///< I term for RO pump max pressure control. @@ -68,8 +68,11 @@ #define FLOW_SAMPLES_TO_AVERAGE ( 250 / TASK_PRIORITY_INTERVAL ) ///< Averaging flow data over 250 ms intervals. #define FLOW_AVERAGE_MULTIPLIER ( 1.0F / (F32)FLOW_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing. -#define RO_FLOW_ADC_TO_LPM_FACTOR 300.0F ///< Conversion factor from ADC counts to LPM (liters/min) for RO flow rate (multiply this by inverse of FPGA reading). - +// The ADC to LPM factor is calculated using the following steps: +// 0.1 to 2 LPM range +// 110000 pulses/liter +// For 2 LPM => 2LPM x 110000 pulses/liter * 1 edges/pulse * 1 min/60 seconds = 3666.66 counts/sec => 272.72 microseconds => for 1 LPM = 136.36 counts +#define RO_FLOW_ADC_TO_LPM_FACTOR 272.72F ///< 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_SLOPE 0.1F ///< Slope of flow to PWM line equation. #define ROP_FLOW_TO_PWM_INTERCEPT 0.0F ///< Intercept of flow to PWM line equation. @@ -126,7 +129,7 @@ static F32 pendingROPumpCmdTargetFlow = 0.0; ///< Delayed (pending) RO pump target flow rate (in mL/min) setting. static U32 pendingROPumpCmdCountDown = 0; ///< Delayed (pending) RO pump command count down timer (in task intervals). -static F32 targetROPumpFlowRate = 0.0; ///< Target RO flow rate (in L/min). +static F32 targetROPumpFlowRateLPM; ///< Target RO flow rate (in L/min). static F32 targetROPumpMaxPressure = 0.0; ///< Target RO max allowed pressure (in PSI). static OVERRIDE_U32_T roPumpDataPublishInterval = { RO_PUMP_DATA_PUB_INTERVAL, @@ -201,6 +204,7 @@ isROPumpOn = FALSE; roPumpFeedbackDutyCyclePct = 0.0; roVolumeL = 0.0; + targetROPumpFlowRateLPM = 0.0; } /*********************************************************************//** @@ -229,7 +233,7 @@ // 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 targetROPumpMaxPressure = maxPressure; - targetROPumpFlowRate = roFlowRate; + targetROPumpFlowRateLPM = roFlowRate; roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; roPumpState = RO_PUMP_RAMP_UP_TO_TARGET_FLOW_STATE; // Get the initial guess of the duty cycle @@ -241,13 +245,13 @@ // Requested max pressure is out of range else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, maxPressure ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, maxPressure ) } } // Requested flow rate is out of range else { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, roFlowRate ) + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, roFlowRate ) } return result; @@ -284,13 +288,13 @@ // Requested max pressure is out of range else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, maxPressure ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, maxPressure ) } } // Requested flow rate is out of range else { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, roFlowRate ) + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, roFlowRate ) } return result; @@ -311,7 +315,7 @@ void signalROPumpHardStop( void ) { stopROPump(); - targetROPumpFlowRate = 0; + targetROPumpFlowRateLPM = 0; roPumpState = RO_PUMP_OFF_STATE; roPumpPWMDutyCyclePct = 0.0; roPumpOpenLoopTargetDutyCycle = 0.0; @@ -353,7 +357,7 @@ if ( TRUE == isNewCalibrationRecordAvailable() ) { getNVRecord2Driver( GET_CAL_FLOW_SENSORS, (U08*)&flowSensorsCalRecord, sizeof( DG_FLOW_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_FLOW_SENSORS_INVALID_CAL_RECORD ); + NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_RO_FLOW_SENSOR_INVALID_CAL_RECORD ); } // Read flow at the control set @@ -401,7 +405,7 @@ if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) && ( RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE == roPumpState ) ) { F32 currentFlow = getMeasuredROFlowRateLPM(); - F32 targetFlow = getTargetROPumpFlowRate(); + F32 targetFlow = getTargetROPumpFlowRateLPM(); // The flow cannot be out of range for than 10% of the target flow BOOL isFlowOutOfRange = ( fabs( 1.0 - ( currentFlow / targetFlow ) ) > MAX_ALLOWED_FLOW_DEVIATION ? TRUE : FALSE ); // Figure out whether flow is out of range from which side @@ -446,13 +450,13 @@ if ( 0 == pendingROPumpCmdCountDown ) { targetROPumpMaxPressure = pendingROPumpCmdMaxPressure; - targetROPumpFlowRate = pendingROPumpCmdTargetFlow; + targetROPumpFlowRateLPM = pendingROPumpCmdTargetFlow; pendingROPumpCmdMaxPressure = 0.0; pendingROPumpCmdTargetFlow = 0.0; roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; roPumpState = RO_PUMP_RAMP_UP_TO_TARGET_FLOW_STATE; // Get the initial guess of the duty cycle - roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( targetROPumpFlowRate ); + roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( targetROPumpFlowRateLPM ); roControlTimerCounter = 0; isROPumpOn = TRUE; } @@ -501,7 +505,7 @@ BOOL calStatus = FALSE; calStatus |= getNVRecord2Driver( GET_CAL_FLOW_SENSORS, (U08*)&flowSensorsCalRecord, sizeof( DG_FLOW_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_FLOW_SENSORS_INVALID_CAL_RECORD ); + NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_RO_FLOW_SENSOR_INVALID_CAL_RECORD ); calStatus |= getNVRecord2Driver( GET_CAL_RO_PUMP_RECORD, (U08*)&roPumpCalRecord, sizeof( DG_RO_PUMP_CAL_RECORD_T ), NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_NO_ALARM ); @@ -533,15 +537,15 @@ /*********************************************************************//** * @brief - * The getTargetROPumpFlowRate function gets the current target RO pump + * The getTargetROPumpFlowRateLPM function gets the current target RO pump * flow rate. - * @details Inputs: targetROPumpFlowRate - * @details Outputs: targetROPumpFlowRate + * @details Inputs: targetROPumpFlowRateLPM + * @details Outputs: none * @return the current target RO flow rate (in L/min). *************************************************************************/ -F32 getTargetROPumpFlowRate( void ) +F32 getTargetROPumpFlowRateLPM( void ) { - return targetROPumpFlowRate; + return targetROPumpFlowRateLPM; } /*********************************************************************//** @@ -608,17 +612,17 @@ RO_PUMP_STATE_T state = RO_PUMP_OFF_STATE; // If there is a flow, transition to the PI controller to get the corresponding pressure of that flow - if ( getTargetROPumpFlowRate() > 0 && roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP ) + if ( getTargetROPumpFlowRateLPM() > 0.0F && roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP ) { // Set pump to on isROPumpOn = TRUE; - roPumpDutyCyclePctSet = ROP_FLOW_TO_PWM_DC( getTargetROPumpFlowRate() ); + roPumpDutyCyclePctSet = ROP_FLOW_TO_PWM_DC( getTargetROPumpFlowRateLPM() ); setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); state = RO_PUMP_RAMP_UP_TO_TARGET_FLOW_STATE; } // If the target duty cycle is greater than zero (minimum is 10%) and the mode has been set to open // loop, set the duty cycle - if ( roPumpOpenLoopTargetDutyCycle > 0 && roPumpControlMode == PUMP_CONTROL_MODE_OPEN_LOOP ) + if ( roPumpOpenLoopTargetDutyCycle > 0.0F && roPumpControlMode == PUMP_CONTROL_MODE_OPEN_LOOP ) { setROPumpControlSignalDutyCycle( roPumpOpenLoopTargetDutyCycle ); isROPumpOn = TRUE; @@ -644,7 +648,7 @@ // Get the current pressure from the sensor F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - F32 targetFlowRate = getTargetROPumpFlowRate(); + F32 targetFlowRate = getTargetROPumpFlowRateLPM(); F32 actualFlowRate = (F32)getMeasuredROFlowRateLPM(); F32 flowRateDeviation = fabs( targetFlowRate - actualFlowRate ) / targetFlowRate; BOOL isFlowOutOfRange = flowRateDeviation > ROP_FLOW_TARGET_TOLERANCE; @@ -709,7 +713,7 @@ } else { - roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, getTargetROPumpFlowRate(), getMeasuredROFlowRateLPM() ); + roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, getTargetROPumpFlowRateLPM(), getMeasuredROFlowRateLPM() ); } setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); @@ -745,7 +749,7 @@ } else { - roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_MAX_PRES, getTargetROPumpFlowRate(), getMeasuredROFlowRateLPM() ); + roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_MAX_PRES, getTargetROPumpFlowRateLPM(), getMeasuredROFlowRateLPM() ); } setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); @@ -843,7 +847,7 @@ { RO_PUMP_DATA_T pumpData; - pumpData.roPumpTgtFlowRateLM = getTargetROPumpFlowRate(); + pumpData.roPumpTgtFlowRateLM = getTargetROPumpFlowRateLPM(); pumpData.roPumpTgtPressure = getTargetROPumpPressure(); pumpData.measROFlowRate = getMeasuredROFlowRateLPM(); pumpData.roPumpDutyCycle = roPumpDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR;