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 ) Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -rae31b4c999dccae70fb40fb9d98a4380ce2c7415 -re734f2d5dbdf3fa44a46892d1207e1f0859ed242 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision ae31b4c999dccae70fb40fb9d98a4380ce2c7415) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision e734f2d5dbdf3fa44a46892d1207e1f0859ed242) @@ -68,6 +68,7 @@ static OVERRIDE_U32_T valveSensedStates[ DD_NUM_OF_VALVES ]; ///< Valve sensed states override. static OVERRIDE_U32_T valvesStatesPublishInterval; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. static OVERRIDE_U32_T fpValveStatesPublishInterval; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. +static RECOVERY_STATE_T recoveryState; // ********** private function prototypes ********** @@ -98,7 +99,7 @@ fpValveStatesPublishInterval.ovData = VALVES_STATE_PUB_INTERVAL; fpValveStatesPublishInterval.ovInitData = 0; fpValveStatesPublishInterval.override = OVERRIDE_RESET; - recoveryState = MAX_RECOVERY; + recoveryState = MAX_RECOVERY; // Initialize commanded valve states for ( i = 0; i < DD_NUM_OF_VALVES; i++ ) @@ -527,17 +528,42 @@ /*********************************************************************//** * @brief - * The setRecoveryValvesConfig function sets all recovery valves per + * The getRecoveryValvesConfig function gets * recovery configuration from institutional record. + * @details \b Inputs: recoveryState + * @details \b Outputs: none + * @return recoveryState. + *************************************************************************/ +RECOVERY_STATE_T getRecoveryStatesConfig( void ) +{ + return recoveryState; +} + +/*********************************************************************//** + * @brief + * The setRecoveryStatesConfig function gets + * recovery configuration from institutional record. * @details \b Inputs: none + * @details \b Outputs: recoveryState + * @param recovery state to set valve config. + * @return none. + *************************************************************************/ +void setRecoveryStatesConfig( U32 recovery ) +{ + recoveryState = (RECOVERY_STATE_T)recovery; +} +/*********************************************************************//** + * @brief + * The setRecoveryValvesConfig function sets all recovery valves per + * recovery configuration from institutional record. + * @details \b Inputs: recoveryState * @details \b Outputs: P33, P34 and P37 recovery valve states * @return none. *************************************************************************/ void setRecoveryValvesConfig( void ) { // TODO define hdInstitutionalRecord and get the NVData when it's ready // RECOVERY_STATE_T recoveryState = (RECOVERY_STATE_T)hdInstitutionalRecord.recoveryConfig; - RECOVERY_STATE_T recoveryState = MAX_RECOVERY; // Set all P33, P34 and P37 valves per recovery configuration switch( recoveryState ) @@ -848,4 +874,38 @@ return result; } +/*********************************************************************//** + * @brief + * The testIOFPValveSensedStateOverride function overrides the value of the + * specified sensed state of an IOFP valve with a given value. + * @details \b Inputs: none + * @details \b Outputs: valveSensedStates[] + * @param message Override message from Dialin which includes an ID of + * the valve to override and the state to override the valve to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testIOFPSetValveRecoveryConfig( MESSAGE_T *message ) +{ + BOOL result = FALSE; + // Verify tester has logged in with DD + if ( TRUE == isTestingActivated() ) + { + // Verify payload length is valid + if ( sizeof( U32 ) == message->hdr.payloadLen ) + { + U32 payload; + + memcpy( &payload, message->payload, sizeof(U32) ); + + if (payload < NUM_OF_RECOVERY_STATES ) + { + setRecoveryStatesConfig(payload); + result = TRUE; + } + } + } + + return result; +} + /**@}*/ Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rdfe2f0df5623aaea1aebdbf22a512fb919abdf01 -re734f2d5dbdf3fa44a46892d1207e1f0859ed242 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision dfe2f0df5623aaea1aebdbf22a512fb919abdf01) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision e734f2d5dbdf3fa44a46892d1207e1f0859ed242) @@ -278,6 +278,7 @@ { MSG_ID_FP_DEF_GEN_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testGenPermeateDefDataPublishIntervalOverride}, { MSG_ID_FP_DEF_STATUS_REQUEST, &testGetFPDefeaturedStatus }, { MSG_ID_FP_RO_FILTERED_REJECTION_RATIO_OVERRIDE_REQUEST, &testRORejectionRatioFilteredOverride }, + { MSG_ID_FP_SET_RECOVERY_VALVES_REQUEST, &testIOFPSetValveRecoveryConfig }, }; /// Calculation for number of entries in the incoming message function handler look-up table.