Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -r5bc2cbda7e16937366aeae9f2b55995314120781 -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -251,26 +251,18 @@ pumpTargetPressure[D48_PUMP].ovData = 0.0F; pumpTargetPressure[D48_PUMP].override = OVERRIDE_RESET; - // Initialize the fresh dialysate pump PI controller (D12 always Diener 2000: 200-2650) + // Initialize the fresh dialysate pump PI controller (D12 always Diener 2000: 200-2650, independent of D48 pump selection) initializePIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, D12_PUMP_P_COEFFICIENT, D12_PUMP_I_COEFFICIENT, 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 (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. Index: firmware/App/Controllers/DialysatePumps.h =================================================================== diff -u -r5bc2cbda7e16937366aeae9f2b55995314120781 -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) +++ firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -24,8 +24,8 @@ * @defgroup DialysatePumps DialysatePumps * @brief Dialysate Pumps monitor/controller module. Controls and monitors the dialysate pumps. * Dialysate pump manufacturer: Diener Silencer Series Gear Pumps, PN: 01483-PM-3-RA. - * The pump shall run at 200(10%) -2700(90%)RPM. - * D12 always uses Diener 2000 (200-2650 RPM). D48 uses Diener 1000 (200-1300) when + * The pump shall run nominally between 10% and 90% duty: 10% ≈ 120 RPM, 90% ≈ 2800 RPM. + * D12 always uses Diener 2000 (200-2650 RPM). D48 uses Diener 1000 (120-2800) when * TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP is set via Dialin, else Diener 2000 (200-2650). * * @addtogroup DialysatePumps @@ -39,17 +39,17 @@ #define DIENER_2000_MAX_RPM 2650 ///< Diener 2000 maximum RPM. /** Diener 1000 pump limits (when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP is set, or __NEW_D48_PUMP__ defined). */ -#define DIENER_1000_MIN_RPM 150 ///< Diener 1000 minimum RPM. -#define DIENER_1000_MAX_RPM 1350 ///< Diener 1000 maximum RPM. +#define DIENER_1000_MIN_RPM 120 ///< Diener 1000 minimum RPM (10% duty target). +#define DIENER_1000_MAX_RPM 2800 ///< Diener 1000 maximum RPM (90% duty target). #ifdef __NEW_D48_PUMP__ -#define MIN_DIALYSATE_PUMP_RPM 150 ///< Minimum RPM target for dialysate pump (150 accepted; zero allowed when turning pump off). -#define MAX_DIALYSATE_PUMP_RPM 1300 ///< Maximum RPM target for dialysate pump (new D48 / Diener 1000). +#define MIN_DIALYSATE_PUMP_RPM 120 ///< Minimum RPM target for dialysate pump (10% duty; zero allowed when turning pump off). +#define MAX_DIALYSATE_PUMP_RPM 2800 ///< Maximum RPM target for dialysate pump (new D48 / Diener 1000). #else -#define MIN_DIALYSATE_PUMP_RPM 150 ///< Minimum RPM target for dialysate pump (150 accepted; zero allowed when turning pump off). +#define MIN_DIALYSATE_PUMP_RPM 150 ///< Minimum RPM target for dialysate pump when using Diener 2000 (150 accepted; zero allowed when turning pump off). #define MAX_DIALYSATE_PUMP_RPM 2650 ///< Maximum RPM target for dialysate pump (Diener 2000; use getMaxDialysatePumpRpm() for runtime config). #endif Index: firmware/App/DDCommon.h =================================================================== diff -u -r5bc2cbda7e16937366aeae9f2b55995314120781 -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -45,18 +45,25 @@ //Uncomment below once characterization/study completed //#define ENABLE_ALARM_2 +//Uncomment below for spent chamber filling +//#define __SPENT_CHAMBER_FILL__ 1 + //Uncomment below for bicarb chamber filling //#define __BICARB_CHAMBER_FILL__ 1 +//Uncomment below for new D48 pump (Diener 1000: min 200, max 1300 RPM). When undefined, Diener 2000 (200-2650 RPM) is used. +#define __NEW_D48_PUMP__ 1 + //Uncomment below for Maxon controller speed change //#define __MAXON_SPEED_UPDATE__ 1 //Uncomment below to disable heaters debug message -#define __HEATERS_DEBUG__ 1 +#define __HEATERS_DEBUG__ 1 //Uncomment below to disable Teensy conductivity driver #define __TEENSY_CONDUCTIVITY_DRIVER__ 1 + #include #include #endif Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r5bc2cbda7e16937366aeae9f2b55995314120781 -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -525,7 +525,20 @@ *************************************************************************/ void setD48PumpSpeedForBCFill( U32 pumpSpeed ) { - d48PumpSpeed = pumpSpeed; + U32 maxD48Rpm = getMaxDialysatePumpRpm(); /* D48: 1300 when Diener 1000, else 2650 */ + + if ( pumpSpeed < MIN_DIALYSATE_PUMP_RPM ) + { + d48PumpSpeed = MIN_DIALYSATE_PUMP_RPM; + } + else if ( pumpSpeed > maxD48Rpm ) + { + d48PumpSpeed = maxD48Rpm; + } + else + { + d48PumpSpeed = pumpSpeed; + } } /*********************************************************************//** @@ -593,8 +606,19 @@ *************************************************************************/ U32 getCalculatedD48PumpSpeedForBCFill( void ) { - F32 dialFlowrate = getTDDialysateFlowrate(); - return dialFlowrate; + F32 dialFlowrate = getTDDialysateFlowrate(); + F32 calculatedRpm = ( PUMP_SPEED_SLOPE_FACTOR * dialFlowrate ) + PUMP_SPEED_INTERCEPT_FACTOR; + U32 maxD48Rpm = getMaxDialysatePumpRpm(); + + if ( calculatedRpm < (F32)MIN_DIALYSATE_PUMP_RPM ) + { + return MIN_DIALYSATE_PUMP_RPM; + } + if ( calculatedRpm > (F32)maxD48Rpm ) + { + return maxD48Rpm; + } + return (U32)calculatedRpm; } /*********************************************************************//** Index: firmware/App/Modes/ModeGenDialysate.h =================================================================== diff -u -r5bc2cbda7e16937366aeae9f2b55995314120781 -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/Modes/ModeGenDialysate.h (.../ModeGenDialysate.h) (revision 5bc2cbda7e16937366aeae9f2b55995314120781) +++ firmware/App/Modes/ModeGenDialysate.h (.../ModeGenDialysate.h) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -32,7 +32,7 @@ // ********** public definitions ********** #define FRESH_DIAL_PUMP_INITIAL_RPM 2500 ///< Nominal RPM target for fresh dialysate pump to maintain required pressure. -#define SPENT_DIAL_PUMP_INITIAL_RPM 2300 ///< Nominal RPM target for spent dialysate pump to maintain required pressure. +#define SPENT_DIAL_PUMP_INITIAL_RPM 2000 ///< Nominal RPM target for spent dialysate pump to maintain required pressure (updated for new pump). #define SPENT_DIAL_PUMP_FILL_RPM 200 ///< Nominal RPM target for spent chamber fill operations. #define DIAL_PUMP_DRAIN_RPM 1000 Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -re163e9faf44d2eb475188b8ea4d6a3befb6e753f -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision e163e9faf44d2eb475188b8ea4d6a3befb6e753f) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) @@ -114,6 +114,10 @@ #define PUMP_SPEED_OFFSET 168.7F ///< Speed Scale adjustment intercept factor #define PUMP_SPEED_FULL_SCALE 3187.0F ///< Speed scale adjustment slope factor +#define D48_NEW_PUMP_PWM_SLOPE 0.000296F ///< Slope term for RPM in D48 PWM mapping. +#define D48_NEW_PUMP_PWM_INTERCEPT 0.07040F ///< Intercept term in D48 PWM mapping. +#define D48_NEW_PUMP_PWM_FULL_SCALE 3150.0F ///< Full-scale FPGA PWM counts for D48. + #pragma pack(push,1) /// FPGA header struct. typedef struct @@ -766,13 +770,23 @@ { #ifdef __MAXON_SPEED_UPDATE__ { - U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); - fpgaActuatorSetPoints.fpgaD48PumpSpeed = currentSpeed; - } +#ifdef __NEW_D48_PUMP__ + /* Diener Silencer 1000 pump (D48): map commanded RPM to FPGA PWM counts + * using characterization: PWM(FPGA) = (D48_NEW_PUMP_PWM_SLOPE * RPM + D48_NEW_PUMP_PWM_INTERCEPT) + * * D48_NEW_PUMP_PWM_FULL_SCALE. + * This yields ~10% duty (≈120 RPM) at the low end and ~90% duty (≈2800 RPM) at the high end. */ + F32 rpm = (F32)speed; + F32 pwmRatio = (D48_NEW_PUMP_PWM_SLOPE * rpm) + D48_NEW_PUMP_PWM_INTERCEPT; /* duty fraction (0.0–1.0) */ + F32 countsF = pwmRatio * D48_NEW_PUMP_PWM_FULL_SCALE; /* 0–full-scale counts */ + U16 currentSpeed = (U16)CLAMP( countsF, 0.0F, D48_NEW_PUMP_PWM_FULL_SCALE ); #else + /* Legacy mapping for Diener 2000 pump: keep existing scaling. */ + U16 currentSpeed = (U16)( ( ( (F32)speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); +#endif + fpgaActuatorSetPoints.fpgaD48PumpSpeed = currentSpeed; } +#else { - fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; - } + fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; } #endif }