Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -r830213bc6dcc1a684610caf78c79d55f2cb41e93 -r5bc2cbda7e16937366aeae9f2b55995314120781 --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 830213bc6dcc1a684610caf78c79d55f2cb41e93) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) @@ -22,6 +22,7 @@ #include "FpgaDD.h" #include "MessageSupport.h" #include "Messaging.h" +#include "TestSupport.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" @@ -69,10 +70,13 @@ #define SPEED_COUNT_ZERO 0 ///< Measured speed count zero check. #define SPEED_CONV_FACTOR 1500000 ///< Measured speed count conversion to RPM -#define D12_PUMP_P_COEFFICIENT 20.0F ///< P term for fresh dialysate pump delta pressure control. -#define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control. -#define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control. -#define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control. +#define D12_PUMP_P_COEFFICIENT 20.0F ///< P term for fresh dialysate pump delta pressure control (Diener 2000). +#define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control (Diener 2000). +#define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control (Diener 2000). +#define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control (Diener 2000). +/** Diener 1000 pump gains for D48 when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP is set. Tune as needed. */ +#define D48_PUMP_P_COEFFICIENT_1000 20.0F ///< P term for D48 when Diener 1000 enabled. +#define D48_PUMP_I_COEFFICIENT_1000 60.0F ///< I term for D48 when Diener 1000 enabled. #define DIAL_PUMP_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control #define DEGAS_PUMP_SLOPE_FACTOR -0.0156F ///< Dialysate pump target pressure multiply factor ( m factor in 'y = mx + b' equation) #define DEGAS_PUMP_INTERCEPT_FACTOR 0.1153F ///< Dialysate pump target pressure addition factor ( b factor in 'y = mx + b' equation) @@ -156,6 +160,36 @@ /*********************************************************************//** * @brief + * Returns maximum dialysate pump RPM for D48 (Diener 1000: 1300 when + * TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP set, else Diener 2000: 2650). + * Used by ModeGenDialysate/BalancingChamber for D48 speed limits. + * @return MAX RPM for D48 pump. + *************************************************************************/ +U32 getMaxDialysatePumpRpm( void ) +{ + return ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) + ? (U32)DIENER_1000_MAX_RPM + : (U32)DIENER_2000_MAX_RPM; +} + +/*********************************************************************//** + * @brief + * Returns maximum dialysate pump RPM for the given pump. D12 always 2650; + * D48 uses TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP (1300 vs 2650). + * @param pumpId D12_PUMP or D48_PUMP. + * @return MAX RPM for that pump. + *************************************************************************/ +U32 getMaxDialysatePumpRpmForPump( DIALYSATE_PUMPS_T pumpId ) +{ + if ( pumpId == D48_PUMP ) + { + return getMaxDialysatePumpRpm(); + } + return (U32)DIENER_2000_MAX_RPM; +} + +/*********************************************************************//** + * @brief * The initDialysatePump function initializes the DialysatePumps unit. * @details \b Inputs: none * @details \b Outputs: Dialysate pump unit variables initialized. @@ -217,13 +251,27 @@ pumpTargetPressure[D48_PUMP].ovData = 0.0F; pumpTargetPressure[D48_PUMP].override = OVERRIDE_RESET; - // Initialize the fresh dialysate pump PI controller + // Initialize the fresh dialysate pump PI controller (D12 always Diener 2000: 200-2650) initializePIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, D12_PUMP_P_COEFFICIENT, D12_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); + MIN_DIALYSATE_PUMP_RPM, +#ifdef __NEW_D48_PUMP__ + MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); +#else + (U32)DIENER_2000_MAX_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); +#endif - // Initialize spent dialysate pump PI controller - initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, D48_PUMP_P_COEFFICIENT, D48_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM,FALSE, DIAL_PUMP_NO_FEED_FORWARD ); + // Initialize spent dialysate pump PI controller (D48: Diener 1000 when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP, else 2000) + { + F32 d48Kp = ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) ? D48_PUMP_P_COEFFICIENT_1000 : D48_PUMP_P_COEFFICIENT; + F32 d48Ki = ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) ? D48_PUMP_I_COEFFICIENT_1000 : D48_PUMP_I_COEFFICIENT; + initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, d48Kp, d48Ki, + MIN_DIALYSATE_PUMP_RPM, +#ifdef __NEW_D48_PUMP__ + MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); +#else + getMaxDialysatePumpRpm(), FALSE, DIAL_PUMP_NO_FEED_FORWARD ); +#endif + } // Init the dialysate pump with valid PWM while motor is disabled. // when enable triggers, we dont want invlid RPM set that triggers alarm in motor controller. @@ -290,7 +338,7 @@ if ( pumpId < NUM_OF_DIALYSATE_PUMPS ) { - if ( ( MIN_DIALYSATE_PUMP_RPM <= rpm ) && ( rpm <= MAX_DIALYSATE_PUMP_RPM ) ) + if ( ( MIN_DIALYSATE_PUMP_RPM <= rpm ) && ( rpm <= getMaxDialysatePumpRpmForPump( pumpId ) ) ) { pumpTargetSpeed[ pumpId ].data = rpm; } @@ -301,7 +349,7 @@ } else { - pumpTargetSpeed[ pumpId ].data = MAX_DIALYSATE_PUMP_RPM; + pumpTargetSpeed[ pumpId ].data = getMaxDialysatePumpRpmForPump( pumpId ); } // Assign Open loop or close loop control @@ -360,7 +408,7 @@ } // Reset all the variables to stop mode - dialysatePumps[ pumpId ].currentPumpSpeed = MIN_DIALYSATE_PUMP_RPM; + dialysatePumps[ pumpId ].currentPumpSpeed = (F32)MIN_DIALYSATE_PUMP_RPM; pumpTargetSpeed[ pumpId ].data = 0.0F; dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; dialysatePumps[ pumpId ].controlTimerCounter = 0; @@ -753,7 +801,7 @@ // If the pump's target speed is set to be 0, do not ramp down set it to zero immediately // if ( getDialysatePumpTargetSpeed( pumpId ) < MIN_DIALYSATE_PUMP_RPM ) // { -// dialysatePumps[ pumpId ].currentPumpSpeed = MIN_DIALYSATE_PUMP_RPM; +// dialysatePumps[ pumpId ].currentPumpSpeed = (F32)MIN_DIALYSATE_PUMP_RPM; // } } @@ -786,10 +834,24 @@ { DIALYSATE_PUMP_STATE_T state = DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE; - // control at set minimum interval or interval is expired and balance chamber fill is complete - if ( ( ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) || - ( TRUE == dialPumpsReadyToControl ) ) && ( TRUE != isDialPumpOpenLoopEnabled[ pumpId ] ) ) + // Open-loop: continuously apply target RPM so pump stays at setpoint (not overwritten by any prior closed-loop output). + if ( TRUE == isDialPumpOpenLoopEnabled[ pumpId ] ) { + F32 targetSpeed = getDialysatePumpTargetSpeed( pumpId ); + dialysatePumps[ pumpId ].currentPumpSpeed = targetSpeed; + if ( D12_PUMP == pumpId ) + { + setFPGAD12PumpSpeed( (U16)targetSpeed ); + } + else + { + setFPGAD48PumpSpeed( (U16)targetSpeed ); + } + } + // Closed-loop: control at set interval when balancing chamber fill is complete. + else if ( ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) || + ( TRUE == dialPumpsReadyToControl ) ) + { dialysatePumps[ pumpId ].controlTimerCounter = 0; dialPumpsReadyToControl = TRUE; @@ -1164,7 +1226,7 @@ { // Handle start command if ( ( TRUE == payload.startStop ) && - ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= MAX_DIALYSATE_PUMP_RPM ) ) ) + ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= getMaxDialysatePumpRpmForPump( (DIALYSATE_PUMPS_T)payload.pumpID ) ) ) ) { setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm, (BOOL)payload.pumpControl ); result = TRUE;