Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -47,6 +47,10 @@ #define DRP_SPEED_ADC_TO_RPM_FACTOR 12.94 ///< conversion factor from ADC counts to RPM for Drain pump #define DRP_SPEED_RPM_TO_ADC_FACTOR ( 1.0 / DRP_SPEED_ADC_TO_RPM_FACTOR ) ///< conversion factor from RPM to ADC counts for Drain pump +#define DRAIN_PUMP_P_COEFFICIENT 0.005 //TODO DARA +#define DRAIN_PUMP_I_COEFFICIENT 0.0015 //TODO DARA +#define DRAIN_PUMP_TARGET_DELTA_PRESSURE NEARLY_ZERO //TODO dara + /// Enumeration of drain pump states. typedef enum DrainPump_States { @@ -111,6 +115,11 @@ void initDrainPump( void ) { stopDrainPump(); + + // Initialize the drain pump + initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, MIN_DRAIN_PUMP_RPM_TARGET, + DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, + MIN_DRAIN_PUMP_RPM_TARGET, MAX_DRAIN_PUMP_RPM_TARGET ); } /*********************************************************************//** @@ -123,7 +132,7 @@ * @param rpm : new target drain pump speed (in RPM). * @return TRUE if new target speed is set, FALSE if not *************************************************************************/ -BOOL setDrainPumpTargetSpeed( U32 rpm ) +BOOL setDrainPumpTargetSpeed( U32 rpm, PUMP_CONTROL_MODE_T mode ) { BOOL result = FALSE; @@ -132,7 +141,7 @@ { drainPumpDAC = (U32)((F32)rpm * DRP_SPEED_RPM_TO_ADC_FACTOR + FLOAT_TO_INT_ROUNDUP_OFFSET); targetDrainPumpSpeed.data = rpm; - drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; + drainPumpControlMode = mode; result = TRUE; } @@ -235,6 +244,11 @@ SET_DRAIN_PUMP_ENABLE(); // set drain pump control mode drainPumpControlModeSet = drainPumpControlMode; + // Check if drain pump mode is closed loop + if ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) + { + resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, MIN_DRAIN_PUMP_RPM_TARGET ); + } // set drain pump DAC drainPumpDACSet = drainPumpDAC; setFPGADrainPumpSpeed( drainPumpDACSet ); @@ -264,7 +278,12 @@ { if ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) { - // TODO - will drain pump have a closed loop? + F32 inletDrainPressure = getMeasuredDGPressure ( PRESSURE_SENSOR_DRAIN_PUMP_INLET ); + F32 outletDrainPressure = getMeasuredDGPressure ( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); + F32 pressureDiff = fabs( inletDrainPressure - outletDrainPressure ); + F32 rpm = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_TARGET_DELTA_PRESSURE, pressureDiff ); + drainPumpDAC = (U32)((F32)rpm * DRP_SPEED_RPM_TO_ADC_FACTOR + FLOAT_TO_INT_ROUNDUP_OFFSET); + setFPGADrainPumpSpeed( drainPumpDAC ); } drainControlTimerCounter = 0; } @@ -466,7 +485,7 @@ targetDrainPumpSpeed.ovInitData = targetDrainPumpSpeed.data; // backup current target pressure targetDrainPumpSpeed.ovData = value; targetDrainPumpSpeed.override = OVERRIDE_KEY; - result = setDrainPumpTargetSpeed( value ); + result = setDrainPumpTargetSpeed( value, PUMP_CONTROL_MODE_OPEN_LOOP ); } return result; @@ -491,7 +510,7 @@ targetDrainPumpSpeed.override = OVERRIDE_RESET; targetDrainPumpSpeed.ovInitData = 0; targetDrainPumpSpeed.ovData = 0; - result = setDrainPumpTargetSpeed( targetDrainPumpSpeed.data ); + result = setDrainPumpTargetSpeed( targetDrainPumpSpeed.data, PUMP_CONTROL_MODE_OPEN_LOOP ); } return result; Index: firmware/App/Controllers/DrainPump.h =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -39,7 +39,7 @@ void execDrainPumpMonitor( void ); void execDrainPumpController( void ); -BOOL setDrainPumpTargetSpeed( U32 rpm ); +BOOL setDrainPumpTargetSpeed( U32 rpm, PUMP_CONTROL_MODE_T mode ); void signalDrainPumpHardStop( void ); SELF_TEST_STATUS_T execDrainPumpTest( void ); Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -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 Index: firmware/App/Controllers/ROPump.h =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -30,29 +30,38 @@ // ********** public definitions ********** -#define MAX_RO_PRESSURE 140 ///< Maximum target RO outlet pressure (in PSI). -#define MIN_RO_PRESSURE 100 ///< Minimum target RO outlet pressure (in PSI). +#define MAX_RO_PRESSURE 140 ///< Maximum target RO outlet pressure (in PSI). //TODO remove +#define MIN_RO_PRESSURE 100 ///< Minimum target RO outlet pressure (in PSI). //TODO remove +#define MAX_RO_FLOWRATE 2000 //TODO dara +#define MIN_RO_FLOWRATE 300 //TODO dara + // ********** public function prototypes ********** void initROPump( void ); void execROPumpMonitor( void ); void execROPumpController( void ); -BOOL setROPumpTargetPressure( U32 roPressure, PUMP_CONTROL_MODE_T mode ); +BOOL setROPumpTargetPressure( U32 roPressure, PUMP_CONTROL_MODE_T mode ); //TODO remove + +BOOL setROPumpTargetFlowRate( U32 roFlowRate, PUMP_CONTROL_MODE_T mode ); void signalROPumpHardStop( void ); BOOL isReverseOsmosisPumpOn( void ); SELF_TEST_STATUS_T execROPumpTest( void ); -DATA_GET_PROTOTYPE( U32, getTargetROPumpPressure ); +DATA_GET_PROTOTYPE( U32, getTargetROPumpFlowRate ); //TODO change DATA_GET_PROTOTYPE( F32, getMeasuredROFlowRate ); BOOL testSetROPumpDataPublishIntervalOverride( U32 value ); BOOL testResetROPumpDataPublishIntervalOverride( void ); -BOOL testSetTargetROPumpPressureOverride( U32 value ); -BOOL testResetTargetROPumpPressureOverride( void ); +BOOL testSetTargetROPumpPressureOverride( U32 value ); //TODO remove +BOOL testResetTargetROPumpPressureOverride( void ); //TODO remove + +BOOL testSetTargetROPumpFlowRateOverride( U32 value ); +BOOL testResetTargetROPumpFlowRateOverride( void ); + BOOL testSetMeasuredROFlowRateOverride( F32 value ); BOOL testResetMeasuredROFlowRateOverride( void ); Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -84,7 +84,7 @@ #define HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF 0.25 ///< Heaters internal temperature sensors ADC to temperature conversion coefficient #define HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF 0.0625 ///< Heaters cold junction temperature sensors ADC to temperature conversion coefficient -#define TEMP_SENSORS_DATA_PUBLISH_INTERVAL (5000 / TASK_PRIORITY_INTERVAL) ///< Temperature sensors publish data time interval +#define TEMP_SENSORS_DATA_PUBLISH_INTERVAL (500 / TASK_PRIORITY_INTERVAL) ///< Temperature sensors publish data time interval #define K_THERMOCOUPLE_TEMP_2_MILLI_VOLT_CONVERSION_COEFF 0.041276 ///< K thermocouple temperature to millivolt conversion coefficient Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -68,7 +68,7 @@ // set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setDrainPumpTargetSpeed( TARGET_DRAIN_PUMP_RPM ); + setDrainPumpTargetSpeed( TARGET_DRAIN_PUMP_RPM, PUMP_CONTROL_MODE_OPEN_LOOP ); } /*********************************************************************//** @@ -128,7 +128,7 @@ // if we've reached our target drain to volume (by weight), we're done draining - go back to re-circ mode if ( getReservoirDrainVolumeTargetMl() >= getLoadCellFilteredWeight( drainWeightLoadCell ) ) { - setDrainPumpTargetSpeed( 0 ); + setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_OPEN_LOOP ); requestNewOperationMode( DG_MODE_CIRC ); } Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -15,22 +15,54 @@ * ***************************************************************************/ +#include "Timers.h" #include "ModeHeatDisinfect.h" #include "OperationModes.h" +#include "Valves.h" +#include "Heaters.h" +#include "DrainPump.h" +#include "LoadCell.h" +#include "ROPump.h" +#include "TemperatureSensors.h" +#include "UVReactors.h" +//TODO control composition pumps + /** * @addtogroup DGHeatDisinfectMode * @{ */ // ********** private definitions ********** +#define HEAT_DISINFECTION_TARGET_TEMP 85U ///< Heat disinfection target temperature +#define HEAT_DISINFECTION_OVERALL_TIME 60U ///< Heat disinfection overall time in minutes +#define HEAT_DISINFECTION_RECIRC_PATH_TIME 5U +#define HEAT_DISINFECTION_FLUSH_TIME 3U + +#define DRAIN_PUMP_TARGET_RPM 2800U +#define RO_PUMP_TARGET_PRESSURE 110U + // ********** private data ********** -static DG_HEAT_DISINFECT_STATE_T heatState = DG_HEAT_DISINFECT_STATE_START; ///< Currently active heat disinfect state. +static DG_HEAT_DISINFECT_STATE_T heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; ///< Currently active heat disinfect state. +static BOOL hasTemperatureReachedToTarget; +static U32 heatDisinfectElapsedTime; // ********** private function prototypes ********** +static void setActuatorsToStop( void ); + +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysate( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWater( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectHeatWater( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRecirculationPath( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectReservoir1To2( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectReservoir2To1( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDrainPath( void ); +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDeprimeReservoirs( void ); + /*********************************************************************//** * @brief * The initHeatDisinfectMode function initializes the heat disinfect Mode module. @@ -41,12 +73,13 @@ *************************************************************************/ void initHeatDisinfectMode( void ) { - heatState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; } /*********************************************************************//** * @brief - * The transitionToHeatDisinfectMode function prepares for transition to heat disinfect mode. + * The transitionToHeatDisinfectMode function prepares for transition + * to heat disinfect mode. * @details * Inputs : none * Outputs : none @@ -55,11 +88,13 @@ void transitionToHeatDisinfectMode( void ) { initHeatDisinfectMode(); + setActuatorsToStop(); } /*********************************************************************//** * @brief - * The execHeatDisinfectMode function executes the heat disinfect Mode state machine. + * The execHeatDisinfectMode function executes the heat disinfect Mode + * state machine. * @details * Inputs : none * Outputs : none @@ -68,18 +103,51 @@ U32 execHeatDisinfectMode( void ) { // execute current heat disinfect state - switch ( heatState ) + switch ( heatDisinfectionState ) { case DG_HEAT_DISINFECT_STATE_START: + heatDisinfectionState = handleHeatDisinfectStart(); break; + case DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE: + heatDisinfectionState = handleHeatDisinfectEvacuateDialysate(); + break; + + case DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER: + heatDisinfectionState = handleHeatDisinfectFillWithWater(); + break; + + case DG_HEAT_DISINFECT_STATE_HEAT_WATER: + heatDisinfectionState = handleHeatDisinfectHeatWater(); + break; + + case DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH: + heatDisinfectionState = handleHeatDisinfectRecirculationPath(); + break; + + case DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_1_TO_2: + heatDisinfectionState = handleHeatDisinfectReservoir1To2(); + break; + + case DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_2_TO_1: + heatDisinfectionState = handleHeatDisinfectReservoir2To1(); + break; + + case DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH: + heatDisinfectionState = handleHeatDisinfectDrainPath(); + break; + + case DG_HEAT_DISINFECT_STATE_DEPRIME_RESERVOIRS: + heatDisinfectionState = handleHeatDisinfectDeprimeReservoirs(); + break; + default: // TODO - s/w fault - heatState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; break; } - return heatState; + return (U32)heatDisinfectionState; } /*********************************************************************//** @@ -93,7 +161,145 @@ *************************************************************************/ DG_HEAT_DISINFECT_STATE_T getCurrentHeatDisinfectState( void ) { - return heatState; + return heatDisinfectionState; } +/*********************************************************************//** + * @brief + * The startDGHeatDisinfect function starts heat disinfect mode. + * @details + * Inputs : none + * Outputs : none + * @return none + *************************************************************************/ +void startDGHeatDisinfect( void ) +{ + // make sure DG is not in the middle of something and it is in standby + // + transitionToHeatDisinfectMode(); // Call request start heat disinfect +} + +/*********************************************************************//** + * @brief + * The stopDGHeatDisinfect function stops heat disinfect mode. + * @details + * Inputs : heatDisinfectionState + * Outputs : heatDisinfectionState + * @return none + *************************************************************************/ +void stopDGHeatDisinfect( void ) +{ + heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; // request standby mode + setActuatorsToStop(); // Not needed +} + +// ********** private function definitions ********** + +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_START; + + setValveState ( VPI, VALVE_STATE_OPEN ); + setValveState ( VBF, VALVE_STATE_OPEN ); + setValveState ( VSP, VALVE_STATE_CLOSED ); + setValveState ( VPD, VALVE_STATE_OPEN_C_TO_NO ); + setValveState ( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setValveState ( VDR, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState ( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState ( VRO, VALVE_STATE_R2_C_TO_NO ); + setValveState ( VRD, VALVE_STATE_R1_C_TO_NO ); + setValveState ( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState ( VRF, VALVE_STATE_R2_C_TO_NO ); + + setROPumpTargetPressure( 0, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_OPEN_LOOP ); + stopInletUVReactor(); + stopOutletUVReactor(); + stopPrimaryHeater(); + stopTrimmerHeater(); + + return state; +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysate( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE; + + return state; + +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWater( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER; + + return state; + +} + +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectHeatWater( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; + + return state; + +} + +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRecirculationPath( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH; + + return state; + + +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectReservoir1To2( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_1_TO_2; + + return state; + + +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectReservoir2To1( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_2_TO_1; + + return state; +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDrainPath( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH; + + return state; +} +static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDeprimeReservoirs( void ) +{ + DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DEPRIME_RESERVOIRS; + + return state; +} + +static void setActuatorsToStop( void ) +{ + setValveState ( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState ( VRI, VALVE_STATE_R2_C_TO_NC ); + setValveState ( VRD, VALVE_STATE_R1_C_TO_NC ); + setValveState ( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState ( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState ( VBF, VALVE_STATE_CLOSED ); + setValveState ( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState ( VDR, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState ( VPI, VALVE_STATE_CLOSED ); + setValveState ( VSP, VALVE_STATE_CLOSED ); + setValveState ( VPD, VALVE_STATE_DRAIN_C_TO_NC ); + + //TODO composition pumps + + setROPumpTargetPressure( 0, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_OPEN_LOOP ); + stopInletUVReactor(); + stopOutletUVReactor(); + stopPrimaryHeater(); + stopTrimmerHeater(); +} + /**@}*/ Index: firmware/App/Modes/ModeHeatDisinfect.h =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -24,7 +24,7 @@ /** * @defgroup DGHeatDisinfectMode DGHeatDisinfectMode * @brief Heat disinfection mode module. Manages the state machine for the - * heat disinfection mode. + * heat disinfect mode. * * @addtogroup DGHeatDisinfectMode * @{ @@ -40,6 +40,9 @@ DG_HEAT_DISINFECT_STATE_T getCurrentHeatDisinfectState( void ); // get the current state of the heat disinfect mode. +void startDGHeatDisinfect( void ); +void stopDGHeatDisinfect( void ); + /**@}*/ #endif Index: firmware/App/Services/PIControllers.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -57,6 +57,8 @@ { // Kp Ki uMax uMin ref meas err esw esum ctrl { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_RO_PUMP + { 0.0, 0.0, 0.99, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // P_CONTROLLER_ID_RO_PUMP_RAMP_UP + { 0.0, 0.0, 3000, 300, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_DRAIN_PUMP { 0.0, 0.0, 0.89, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_PRIMARY_HEATER { 0.0, 0.0, 0.50, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } // PI_CONTROLLER_ID_TRIMMER_HEATER }; Index: firmware/App/Services/PIControllers.h =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -34,6 +34,8 @@ typedef enum ControllerList { PI_CONTROLLER_ID_RO_PUMP = 0, ///< RO Pump controller. + P_CONTROLLER_ID_RO_PUMP_RAMP_UP, ///< RO Pump controller during ramp up time. + PI_CONTROLLER_ID_DRAIN_PUMP, ///< Drain Pump controller. PI_CONTROLLER_ID_PRIMARY_HEATER, ///< Primary Heater controller. PI_CONTROLLER_ID_TRIMMER_HEATER, ///< Trimmer Heater controller. NUM_OF_PI_CONTROLLERS_IDS ///< Number of PI controllers. Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -1011,6 +1011,10 @@ handleStartStopTrimmerHeaterCmd( message ); break; + case MSG_ID_DG_START_STOP_HEAT_DISINFECT: + handleStartStopDGHeatDisinfect( message ); + break; + case MSG_ID_DG_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -35,6 +35,7 @@ #include "Utilities.h" #include "Valves.h" #include "WatchdogMgmt.h" +#include "ModeHeatDisinfect.h" // ********** private definitions ********** @@ -968,6 +969,42 @@ } /************************************************************************* + * @brief + * The handleStartStopDGHeatDisinfect function handles a request start or + * stop DG heat disifect + * @details + * Inputs : none + * Outputs : message handled + * @param message : a pointer to the message to handle + * @return result + *************************************************************************/ +BOOL handleStartStopDGHeatDisinfect( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + BOOL startingDGHeatDisinfect; + + memcpy( &startingDGHeatDisinfect, message->payload, sizeof(U32) ); + + if ( TRUE == startingDGHeatDisinfect ) + { + startDGHeatDisinfect(); + result = TRUE; + } + else + { + stopDGHeatDisinfect(); + result = TRUE; + } + } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); + + return result; +} + +/************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -1185,8 +1222,10 @@ * @param message : a pointer to the message to handle * @return none *************************************************************************/ -DATA_OVERRIDE_HANDLER_FUNC_U32( U32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpPressureOverride, testResetTargetROPumpPressureOverride ) +//DATA_OVERRIDE_HANDLER_FUNC_U32( U32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpPressureOverride, testResetTargetROPumpPressureOverride ) //Todo remove +DATA_OVERRIDE_HANDLER_FUNC_U32( U32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpFlowRateOverride, testResetTargetROPumpFlowRateOverride ) + /************************************************************************* * @brief * The handleTestROMeasuredFlowOverrideRequest function handles a request to \n Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -ra7bf3ca23ea37a61000379facae628a31b3ecc59 -rbe5079c95b05c303878763b458dc0854a600317e --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a7bf3ca23ea37a61000379facae628a31b3ecc59) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision be5079c95b05c303878763b458dc0854a600317e) @@ -157,8 +157,11 @@ void handleTestDGSafetyShutdownOverrideRequest( MESSAGE_T *message ); // MSG_ID_START_STOP_PRIMARY_HEATER -BOOL handleStartStopPrimaryHeater( MESSAGE_T * message ); +BOOL handleStartStopPrimaryHeater( MESSAGE_T *message ); +// MSG_ID_START_STOP_DG_HEAT_DISINFECT +BOOL handleStartStopDGHeatDisinfect( MESSAGE_T *message ); + #ifdef CAN_TEST // MSG_ID_DG_CAN_TEST_1_LARGE_FREQ void broadcastCANTest1LargeFrequentMessage();