Index: firmware/App/Controllers/MixingControl.c =================================================================== diff -u -r313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59 -r43ebe58702128e865210533f9e6deaf13f99d262 --- firmware/App/Controllers/MixingControl.c (.../MixingControl.c) (revision 313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59) +++ firmware/App/Controllers/MixingControl.c (.../MixingControl.c) (revision 43ebe58702128e865210533f9e6deaf13f99d262) @@ -8,7 +8,7 @@ * @file MixingControl.c * * @author (last) Sameer Kalliadan Poyil -* @date (last) 16-Jun-2026 +* @date (last) 25-Jun-2026 * * @author (original) Sameer Kalliadan Poyil * @date (original) 15-Jun-2026 @@ -48,7 +48,7 @@ // drybicarb mixing #define BICARB_VOL_CONTROL_P_COEFFICIENT ( 0.00008484F * 2 ) ///< Bicarb proportional gain (kp) #define BICARB_VOL_CONTROL_I_COEFFICIENT ( 0.00033936F / 4 ) ///< Bicarb integral gain. (ki) -#define MIN_BICARB_VOLUME_ML 0.868686869 ///< Minimum bicarb volume in mL +#define MIN_BICARB_VOLUME_ML 0.4F ///< Minimum bicarb volume in mL #define MAX_BICARB_VOLUME_ML 1.8F ///< Maximum bicarb volume in mL #define ACID_VOL_CONTROL_P_COEFFICIENT ( 0.00000997F / 2 ) ///< Acid proportional gain (kp) @@ -59,7 +59,7 @@ #define BICARB_TARGET_CONDUCTIVITY 2714.0F ///< Target bicarb conductivity #define BICARB_DELTA_CONDUCTIVITY 500.0F ///< Delta bicarb conductivity -#define DIALYSATE_TARGET_CONDUCTIVITY 3734.87F ///< Target dialysate conductivity +#define DIALYSATE_TARGET_CONDUCTIVITY 13613.8F ///< Target dialysate conductivity for 1K #define DIALYSATE_DELTA_CONDUCTIVITY 700.0F ///< Delta dialysate conductivity // this is for reference only , it can be removed later @@ -69,8 +69,8 @@ #define MIX_NO_FEED_FORWARD 0.0F ///< Feed forward term for dialysate closed loop control -#define BICARB_MIX_CONTROL_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the bicarb mix is controlled. -#define ACID_MIX_CONTROL_INTERVAL ( 5 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate mix is controlled. +#define BICARB_MIX_CONTROL_INTERVAL_MULTIPLIER ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the bicarb mix is controlled. +#define ACID_MIX_CONTROL_INTERVAL_MULTIPLIER ( 5 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate mix is controlled. #define BICARB_DEADBAND_CONTROL 15.0F ///< Bicarb dead band control #define ACID_DEADBAND_CONTROL 50.0F ///< Acid dead band control @@ -316,18 +316,28 @@ mixingControlTargetAdjBicarbSettings.ovInitData = 0.0F; mixingControlTargetAdjBicarbSettings.override = OVERRIDE_RESET; - mixingControlBicarbControlInterval.data = BICARB_MIX_CONTROL_INTERVAL; - mixingControlBicarbControlInterval.ovData = BICARB_MIX_CONTROL_INTERVAL; + mixingControlBicarbControlInterval.data = BICARB_MIX_CONTROL_INTERVAL_MULTIPLIER; + mixingControlBicarbControlInterval.ovData = BICARB_MIX_CONTROL_INTERVAL_MULTIPLIER; mixingControlBicarbControlInterval.ovInitData = 0; mixingControlBicarbControlInterval.override = OVERRIDE_RESET; - mixingControlAcidControlInterval.data = ACID_MIX_CONTROL_INTERVAL; - mixingControlAcidControlInterval.ovData = ACID_MIX_CONTROL_INTERVAL; + mixingControlAcidControlInterval.data = ACID_MIX_CONTROL_INTERVAL_MULTIPLIER; + mixingControlAcidControlInterval.ovData = ACID_MIX_CONTROL_INTERVAL_MULTIPLIER; mixingControlAcidControlInterval.ovInitData = 0; mixingControlAcidControlInterval.override = OVERRIDE_RESET; mixingControlDataPublicationTimerCounter = 0; + lastBicarbMixVolume = 0; + lastAcidMixVolume = 0; + initializePIController( PI_CONTROLLER_ID_BICARB_VOL, 0.0F,\ + getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ + MIN_BICARB_VOLUME_ML, MAX_BICARB_VOLUME_ML, FALSE, MIX_NO_FEED_FORWARD ); + + initializePIController( PI_CONTROLLER_ID_ACID_VOL, 0.0F, \ + getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ + MIN_ACID_VOLUME_ML, MAX_ACID_VOLUME_ML, FALSE, MIX_NO_FEED_FORWARD ); + } /*********************************************************************//** @@ -353,7 +363,7 @@ *************************************************************************/ void execMixingControl( void ) { - if( getCurrentBalancingChamberExecState() > BAL_CHAMBER_STATE_IDLE ) + if ( getCurrentBalancingChamberExecState() > BAL_CHAMBER_STATE_IDLE ) { updatedConcentrateControlInterval(); @@ -423,7 +433,8 @@ /*********************************************************************//** * @brief - * The updatedConcentrateControlInterval function sets bicarb Mix volume provided by the controller + * The updatedConcentrateControlInterval function sets both acid and bicarb + * Mix volume provided by the controller * @details \b Inputs: none * @details \b Outputs: mixingControlBicarbMixVolume * @param targetValue bicarb Mix volume @@ -440,10 +451,13 @@ balChamberSwitchingFreq = tdDialysateFlowRate / 30.0; balChamberSwitchingPeriod = ( SEC_PER_MIN ) / (U32)balChamberSwitchingFreq; + // For acid control period, we are using 3 cycles of balancing chamber switching period (for ex: At Qd = 600, switching period = 3sec, so acid control interval = 3*3 = 9sec + // For bicarb control period, we are using 5 cycles of balancing chamber switching period (for ex: At Qd = 600, switching period = 3sec, so bicarb control interval = 3*5 = 15sec + if ( balChamberSwitchingPeriod > 0) { - mixingControlAcidControlInterval.data = ACID_MIX_CONTROL_INTERVAL * balChamberSwitchingPeriod; - mixingControlBicarbControlInterval.data = BICARB_MIX_CONTROL_INTERVAL * balChamberSwitchingPeriod; + mixingControlAcidControlInterval.data = ACID_MIX_CONTROL_INTERVAL_MULTIPLIER * balChamberSwitchingPeriod; + mixingControlBicarbControlInterval.data = BICARB_MIX_CONTROL_INTERVAL_MULTIPLIER * balChamberSwitchingPeriod; } } @@ -757,16 +771,18 @@ PI_CONTROLLER_SIGNALS_DATA debugBicarbControl; F32 measuredBicarbConductivity = getFilteredConductivity( D17_COND ); F32 bicarbConductivity = getBicarbTargetConductivity();//getBicarbConductivityPre(); + //TODO: ALARM if measuredDialysateConductivity or bicarbConductivity is or both 0 if ( fabs ( bicarbConductivity - measuredBicarbConductivity ) > BICARB_DEADBAND_CONTROL ) { - bicarbMixVol = runPIController( PI_CONTROLLER_ID_BICARB_VOL, getBicarbConductivityPre() /*getBicarbTargetConductivity()*/, measuredBicarbConductivity ); - //Set bicarb mix vol only if its above dead band threshold, else use the previous set vlaue + bicarbMixVol = runPIController( PI_CONTROLLER_ID_BICARB_VOL, bicarbConductivity, measuredBicarbConductivity ); + //Set bicarb mix vol only if its above dead band threshold, else use the previous set value + // Note: bicarb volume will impact the D10 pump , if volume is set to 0 , then D10 doesn't run setBicarbMixVol( bicarbMixVol ); } else { - //use the previous value + //use the previous value, this is for debug lastBicarbMixVolume = getBicarbMixVol(); } @@ -789,16 +805,18 @@ F32 measuredDialysateConductivity = getFilteredConductivity( D27_COND ); F32 DialysateConductivity = getDialysateTargetConductivity();//getTotalConductivity(); PI_CONTROLLER_SIGNALS_DATA debugAcidControl; + //TODO: ALARM if measuredDialysateConductivity or DialysateConductivity is or both 0 if ( fabs ( DialysateConductivity - measuredDialysateConductivity ) > ACID_DEADBAND_CONTROL ) { acidMixVol = runPIController( PI_CONTROLLER_ID_ACID_VOL, DialysateConductivity, measuredDialysateConductivity ); // set acid mix volume if its above dead band threshold , else use previous set value + // Note: if acid volume is set as 0, then D11 pump doesn't run setAcidMixVol( acidMixVol ); } else { - // use the previous value + // use the previous value, this is for debug lastAcidMixVolume = getAcidMixVol(); } @@ -873,7 +891,7 @@ data.currentBicarbMixVolume = getBicarbMixVol(); data.lastBicarbMixVolume = lastBicarbMixVolume; data.currentAcidMixVolume = getAcidMixVol(); - data.currentAcidMixVolume = lastAcidMixVolume; + data.lastAcidMixVolume = lastAcidMixVolume; //TODO :broadcast theretical pre and post conductivity @@ -1119,7 +1137,7 @@ *************************************************************************/ BOOL testMixingControlBicarbControlIntervalOverride( MESSAGE_T *message ) { - BOOL result = u32Override( message, &mixingControlBicarbControlInterval, 0, BICARB_MIX_CONTROL_INTERVAL ); + BOOL result = u32Override( message, &mixingControlBicarbControlInterval, 0, BICARB_MIX_CONTROL_INTERVAL_MULTIPLIER ); return result; } @@ -1136,7 +1154,7 @@ *************************************************************************/ BOOL testMixingControlAcidControlIntervalOverride( MESSAGE_T *message ) { - BOOL result = u32Override( message, &mixingControlAcidControlInterval, 0, BICARB_MIX_CONTROL_INTERVAL ); + BOOL result = u32Override( message, &mixingControlAcidControlInterval, 0, ACID_MIX_CONTROL_INTERVAL_MULTIPLIER ); return result; }