Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r081b2525e3a650671d770513eb841057d88ea505 -rf1dc3383b840c39f202b15679e0bbe2b2f7a2f83 --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 081b2525e3a650671d770513eb841057d88ea505) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision f1dc3383b840c39f202b15679e0bbe2b2f7a2f83) @@ -15,6 +15,8 @@ * ***************************************************************************/ +#include // For sqrtf + #include "BalancingChamber.h" #include "Conductivity.h" #include "ConcentratePumps.h" @@ -28,7 +30,6 @@ #include "MixingControl.h" #include "ModeGenDialysate.h" #include "ModeStandby.h" -#include "OperationModes.h" #include "Pressure.h" #include "TaskGeneral.h" #include "TDInterface.h" @@ -45,11 +46,7 @@ #define BAL_CHAMBER_DATA_PUBLISH_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the balancing chamber data published. #define BAL_CHAMBER_FILL_PRES_DROP_MS ( 200 / TASK_GENERAL_INTERVAL ) ///< Time (ms/tasktime) to confirm the balancing chamber filling started and corrosponding valves opened. -#if 1 #define BAL_CHAMBER_FILL_COMPLETE_MS ( 100 / TASK_GENERAL_INTERVAL ) ///< Time (ms/tasktime) to confirm the balancing chamber fill completed and pressure is within range -#else -#define BAL_CHAMBER_FILL_COMPLETE_MS ( 300 / TASK_GENERAL_INTERVAL ) ///< Time (ms/tasktime) to confirm the balancing chamber fill completed and pressure is within range -#endif #define SPENT_FILL_COMPLETE_QD_LOW_RISE_MAX_MLPM 300.0F ///< For Qd <= 300 mL/min (Diener 1000). #define SPENT_FILL_COMPLETE_DP_RISE_PSIG 0.5F ///< Minimum 100 ms spent pressure rise (current minus n-2) to count as a rise hit at low Qd. #define SPENT_FILL_COMPLETE_DP_RISE_HIGH_QD_PSIG 3.0F ///< Minimum spent pressure rise for Diener 2000 or Qd > 300 mL/min. @@ -64,6 +61,10 @@ #define BAL_CHAMBER_FILL_TIMEOUT_FACTOR 3.0F ///< Balancing Chamber fill timeout factor (300% of observed fill count) #define COMP_SLOPE -0.000376F ///< Balancing chamber temperature compensation slope factor #define COMP_INTERCEPT 1.007269F ///< Balancing chamber temperature compensation intercept factor +/// Bicarb (D10) pump speed from instantaneous mix volume: speed = 240 - sqrt(230400 - 96000*v)/2 +#define BC_BICARB_SPEED_OFFSET_MLPM 240.0F ///< Bicarb speed formula offset (mL/min). +#define BC_BICARB_SPEED_DISC_CONST 230400.0F ///< Bicarb speed formula discriminant constant. +#define BC_BICARB_SPEED_DISC_VOL_COEF 96000.0F ///< Bicarb speed formula volume coefficient. /// Payload record structure for balancing chamber switch only request typedef struct @@ -114,7 +115,7 @@ static F32 balancingError; ///< Balancing error that has been calculated during balancing chamber switching. //TODO: remove later once level sensor working -static U32 bicarbChamberPeriodicFillCounter; +static U32 bicarbChamberPeriodicFillCounter; // Balancing chamber state change tracker static BAL_CHAMBER_EXEC_STATE_T prevBalChamberState; ///< Balancing chamber Previous State tracking variable @@ -139,6 +140,8 @@ static void valveControlForBCState2FreshSideClose( void ); static void closeFreshSideValvesWhenFillComplete( void ); static void calculateBalancingChamberError( void ); +static F32 getBicarbConcentratePumpSpeedMlMin( F32 bicarbVolumeMl ); +static void startBalChamberConcPumpDosing( F32 acidVolume, F32 bicarbVolume ); /*********************************************************************//** * @brief @@ -206,6 +209,62 @@ /*********************************************************************//** * @brief + * The getBicarbConcentratePumpSpeedMlMin function computes D10 pump speed + * from the instantaneous bicarb mix volume: + * speed = 240 - sqrt(230400 - 96000*v) / 2 + * Result is clamped to [0, CONCENTRATE_PUMP_MAX_SPEED]. + * @details \b Inputs: bicarbVolumeMl + * @param bicarbVolumeMl Instantaneous bicarb mix volume (mL) + * @return Bicarb concentrate pump speed (mL/min) + *************************************************************************/ +static F32 getBicarbConcentratePumpSpeedMlMin( F32 bicarbVolumeMl ) +{ + F32 discriminant = BC_BICARB_SPEED_DISC_CONST - ( BC_BICARB_SPEED_DISC_VOL_COEF * bicarbVolumeMl ); + F32 result = 0.0F; + + if ( discriminant < 0.0F ) + { + discriminant = 0.0F; + } + + result = BC_BICARB_SPEED_OFFSET_MLPM - ( sqrtf( discriminant ) / 2.0F ); + + if ( result > CONCENTRATE_PUMP_MAX_SPEED ) + { + result = CONCENTRATE_PUMP_MAX_SPEED; + } + else if ( result < 0.0F ) + { + result = 0.0F; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The startBalChamberConcPumpDosing function starts acid and bicarb dosing. + * Acid (D11) runs at fixed 100 mL/min. Bicarb (D10) speed is computed from + * the instantaneous bicarb mix volume on every BC dose start. + * @details \b Inputs: acidVolume, bicarbVolume + * @details \b Outputs: concentrate pumps + * @param acidVolume Acid dose volume (mL) + * @param bicarbVolume Bicarb dose volume (mL) + * @return none + *************************************************************************/ +static void startBalChamberConcPumpDosing( F32 acidVolume, F32 bicarbVolume ) +{ + F32 acidSpeed = DOSING_ACID_CONCENTRATE_PUMP_SPEED; + F32 bicarbSpeed = getBicarbConcentratePumpSpeedMlMin( bicarbVolume ); + + setConcentratePumpTargetSpeed( D11_PUMP, acidSpeed, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, bicarbSpeed, bicarbVolume ); + requestConcentratePumpOn( D11_PUMP ); + requestConcentratePumpOn( D10_PUMP ); +} + +/*********************************************************************//** + * @brief * The transitionToBalChamberFill function prepares for transition to * balancing chamber fill/switching operations. * @details \b Inputs: none @@ -767,11 +826,7 @@ // Deliver dosing during generate dialysate mode if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { - // start acid and bicarb pump with the expected quantity - setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); - setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); - requestConcentratePumpOn( D11_PUMP ); - requestConcentratePumpOn( D10_PUMP ); + startBalChamberConcPumpDosing( acidVolume, bicarbVolume ); } state = BAL_CHAMBER_STATE1_BICARB_ACID_DOSING_CNTRL; @@ -1099,11 +1154,7 @@ // Deliver dosing during generate dialysate mode if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { - // start acid and bicarb pump with the expected quantity - setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); - setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); - requestConcentratePumpOn( D11_PUMP ); - requestConcentratePumpOn( D10_PUMP ); + startBalChamberConcPumpDosing( acidVolume, bicarbVolume ); } state = BAL_CHAMBER_STATE2_BICARB_ACID_DOSING_CNTRL;