Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r26f63d0260a3c35277e3e6dbca3573c253775318 -r622eebf6fb7f1c6c232ffd82bc072dd30a7b3f94 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 622eebf6fb7f1c6c232ffd82bc072dd30a7b3f94) @@ -22,6 +22,7 @@ #include "FPGA.h" #include "NVDataMgmt.h" +#include "MessageSupport.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "PIControllers.h" @@ -85,6 +86,10 @@ #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 ( 3 * MS_PER_SECOND ) ///< RO pump safety shutdown activation timeout in ms. +#define ROP_ZERO_DUTY_CYCLE_FEEDBACK 0x01FF ///< RO pump zero duty cycle feedback from FPGA. +#define ROP_DUTY_CYCLE_PERIOD_US 500 ///< RO pump duty cycle period in micro seconds. +#define ROP_DUTY_CYCLE_OUT_OF_RANGE_TOLERANCE 0.05 ///< RO pump duty cycle out of range tolerance. + /// Enumeration of RO pump states. typedef enum ROPump_States { @@ -122,8 +127,7 @@ static F32 targetROPumpMaxPressure = 0.0; ///< Target RO max allowed 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. + 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). static U32 roControlTimerCounter = 0; ///< Determines when to perform control on RO pump. @@ -322,15 +326,16 @@ *************************************************************************/ void execROPumpMonitor( void ) { - U16 roFlowReading = getFPGAROPumpFlowRate(); + U16 roFlowReading = getFPGAROPumpFlowRate(); + U16 roFeedbackDCPeriod = getFPGAROPumpDutyCycleFeedback(); // Update sum for flow average calculation measuredFlowReadingsSum += (S32)roFlowReading; // Read the pressure at the sensor. The pump cannot be more that the maximum allowed pressure // to make sure the hardware (especially the ROF) is not damaged. If it is the case, we need to stop immediately F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - BOOL isPressureMax = actualPressure >= MAX_ALLOWED_MEASURED_PRESSURE_PSI; + BOOL isPressureMax = ( actualPressure >= MAX_ALLOWED_MEASURED_PRESSURE_PSI ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_RO_PUMP_PRESSURE_OUT_OF_RANGE, isPressureMax, actualPressure, MAX_ALLOWED_MEASURED_PRESSURE_PSI ); // Check if a new calibration is available @@ -359,7 +364,7 @@ } measuredFlowReadingsSum = 0; - flowFilterCounter = 0; + flowFilterCounter = 0; } #ifndef IGNORE_RO_PUMP_MONITOR @@ -368,32 +373,36 @@ // but the pump is not able to achieve the flow. if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) && ( RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE == roPumpState ) ) { - F32 const currentFlow = getMeasuredROFlowRate(); - F32 const targetFlow = getTargetROPumpFlowRate(); + F32 currentFlow = getMeasuredROFlowRate(); + F32 targetFlow = getTargetROPumpFlowRate(); // The flow cannot be out of range for than 10% of the target flow - BOOL const isFlowOutOfRange = fabs( 1.0 - ( currentFlow / targetFlow ) ) > MAX_ALLOWED_FLOW_DEVIATION; + BOOL isFlowOutOfRange = ( fabs( 1.0 - ( currentFlow / targetFlow ) ) > MAX_ALLOWED_FLOW_DEVIATION ? TRUE : FALSE ); // Figure out whether flow is out of range from which side - BOOL const isFlowOutOfUpperRange = isFlowOutOfRange && ( currentFlow > targetFlow ); - BOOL const isFlowOutOfLowerRange = isFlowOutOfRange && ( currentFlow < targetFlow ); + BOOL isFlowOutOfUpperRange = ( isFlowOutOfRange && ( currentFlow > targetFlow ) ? TRUE : FALSE ); + BOOL isFlowOutOfLowerRange = ( isFlowOutOfRange && ( currentFlow < targetFlow ) ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_UPPER_RANGE, isFlowOutOfUpperRange, currentFlow, targetFlow ); checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_LOWER_RANGE, isFlowOutOfLowerRange, currentFlow, targetFlow ); } - // If the pump is off and PPi + 5psi < PPo for a certain period of time, activate safety shutdown - if ( FALSE == isROPumpOn ) + if ( ( FALSE == isROPumpOn ) && ( roFeedbackDCPeriod != ROP_ZERO_DUTY_CYCLE_FEEDBACK ) ) { - F32 pressureInlet = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); - BOOL isPumpRunning = ( pressureInlet + MAX_PRESSURE_TARGET_TOLERANCE ) < actualPressure; + checkPersistentAlarm( ALARM_ID_RO_PUMP_DUTY_CYCLE_OUT_OF_RANGE, TRUE, roFeedbackDCPeriod, ROP_ZERO_DUTY_CYCLE_FEEDBACK ); - checkPersistentAlarm( ALARM_ID_RO_PUMP_DUTY_CYCLE_OUT_OF_RANGE, isPumpRunning, pressureInlet, ( pressureInlet + MAX_PRESSURE_TARGET_TOLERANCE ) ); - // Check if it has timed out if ( TRUE == isAlarmActive( ALARM_ID_RO_PUMP_DUTY_CYCLE_OUT_OF_RANGE ) ) { activateSafetyShutdown(); } } + + if ( TRUE == isROPumpOn ) // TODO do we need to check all this every 1 second and not every 10 ms? + { + F32 roDutyCycle = roFeedbackDCPeriod / ROP_DUTY_CYCLE_PERIOD_US; + BOOL isDCOutOfRange = ( fabs( roDutyCycle - roPumpDutyCyclePctSet ) > ROP_DUTY_CYCLE_OUT_OF_RANGE_TOLERANCE ? TRUE : FALSE ); + + checkPersistentAlarm( ALARM_ID_RO_PUMP_DUTY_CYCLE_OUT_OF_RANGE, TRUE, roDutyCycle, roPumpDutyCyclePctSet ); + } #endif // Publish RO pump data on interval @@ -833,7 +842,7 @@ pumpData.roPumpDutyCycle = roPumpDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; pumpData.roPumpState = (U32)roPumpState; - broadcastROPumpData( &pumpData ); + broadcastData( MSG_ID_RO_PUMP_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&pumpData, sizeof( RO_PUMP_DATA_T ) ); roPumpDataPublicationTimerCounter = 0; } }