Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -rd0a2037b16f76e661dc02296e039f099ce5d9ea8 -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision d0a2037b16f76e661dc02296e039f099ce5d9ea8) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -7,8 +7,8 @@ * * @file BalancingChamber.c * -* @author (last) Jashwant Gantyada -* @date (last) 13-Mar-2026 +* @author (last) Dara Navaei +* @date (last) 18-Mar-2026 * * @author (original) Vinayakam Mani * @date (original) 28-Jan-2025 @@ -52,6 +52,7 @@ #define SPENT_DIFF_COUNT_ZERO 0 ///< Zero count difference for spent side fill comparing target count #define D48_SPEED_ADJUST_FACTOR 0.5F ///< D48 speed adjustment factor ( 50% of speed adjustment = 0.5) #define D48_SPEED_RANGE_LIMIT 0.25F ///< D48 speed adjustment range check limit ( D48 speed can vary +/-25% of initial calculated speed) +#define BICARB_CHAMBER_PERIODIC_FILL_TIME ( 1 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) ///< Periodic bicarb chamber fill request 60 sec x 20 = 1200 #define BAL_CHAMBER_FILL_TIMEOUT_FACTOR 1.5 ///< Balancing Chamber fill timeout factor (150% of observed fill count) /// Payload record structure for balancing chamber switch only request @@ -69,7 +70,7 @@ static U32 balChamberValveClosePeriod; ///< Close balancing chamber valves with the defined time prior switching state. static U32 currentBalChamberSwitchingCounter; ///< Counter (in task interval) to monitor the timing spent during balancing chamber fill/drain operation. static BOOL isBalChamberFillInProgress; ///< Flag indicating balancing chamber fill/drain is in progress. -static BOOL isPressureStabilizedDuringFill; ///< Flag indicating that the pressure is stablized due to fill complete. +static BOOL isPressureStabilizedDuringFill; ///< Flag indicating that the pressure is stabilized due to fill complete. static BAL_CHAMBER_SW_STATE_T balChamberSWState; ///< Current balancing chamber switching state ( state 1 or state 2). static U32 balChamberDataPublicationTimerCounter; ///< Used to schedule balancing chamber data publication to CAN bus. static U32 balChamberFillPressureDropCounter; ///< Counter to check balancing chamber valves opened and there by pressure drop is seen. @@ -87,6 +88,8 @@ static U32 balChamberFillTimeoutCount; ///< Timeout count (in task interval) to detect BC fill timeout. static S32 diffSpentFillCompleteCount; ///< Difference between spent target fill to actual fill count static BOOL isSpentFillComplete; ///< Flag indicating spent side fill complete. +//TODO: remove later once level sensor working +static U32 bicarbChamberPeriodicFillCounter; // ********** private function prototypes ********** @@ -146,6 +149,8 @@ balChamberFillTimeoutCount = 0; diffSpentFillCompleteCount = 0; isSpentFillComplete = FALSE; + //TODO:remove once level sensor working + bicarbChamberPeriodicFillCounter = 0; } /*********************************************************************//** @@ -217,7 +222,23 @@ currentBalChamberSwitchingCounter += 1; currentBalChamberFillCounter += 1; - // execute current balancing chamber exec state + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE && balChamberExecState > BAL_CHAMBER_STATE_IDLE) + { + // Increment counter for dry bicarb chamber fill + bicarbChamberPeriodicFillCounter += 1; + // Fill bicarb chamber once every 60secs. + if ( bicarbChamberPeriodicFillCounter >= BICARB_CHAMBER_PERIODIC_FILL_TIME ) + { + if ( FALSE == setBicarbChamberFillRequested() ) + { + // TODO + //drybicart state machines are combined and so this is not an issue in future + //set alarm ? + } + bicarbChamberPeriodicFillCounter = 0; + } + } + switch ( balChamberExecState ) { case BAL_CHAMBER_STATE_START: @@ -469,8 +490,8 @@ if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { // start acid and bicarb pump with the expected quantity - setConcentratePumpTargetSpeed( D11_PUMP, CONCENTRATE_PUMP_MAX_SPEED, acidVolume ); - setConcentratePumpTargetSpeed( D10_PUMP, CONCENTRATE_PUMP_MAX_SPEED, bicarbVolume ); + setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); requestConcentratePumpOn( D11_PUMP ); requestConcentratePumpOn( D10_PUMP ); } @@ -704,8 +725,8 @@ if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { // start acid and bicarb pump with the expected quantity - setConcentratePumpTargetSpeed( D11_PUMP, CONCENTRATE_PUMP_MAX_SPEED, acidVolume ); - setConcentratePumpTargetSpeed( D10_PUMP, CONCENTRATE_PUMP_MAX_SPEED, bicarbVolume ); + setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); requestConcentratePumpOn( D11_PUMP ); requestConcentratePumpOn( D10_PUMP ); } @@ -1147,7 +1168,7 @@ { BOOL result = FALSE; - // Verify tester has logged in with TD + // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid Index: firmware/App/Controllers/ConcentratePumps.h =================================================================== diff -u -rd210786d6c7d75bb0b4d9e18efc40a01d85123fe -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision d210786d6c7d75bb0b4d9e18efc40a01d85123fe) +++ firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -32,7 +32,7 @@ // ********** public definitions ********** // For 150 RPM, Diener pump delivers 60ml/min #define CONCENTRATE_PUMP_MAX_SPEED 200.0F ///< Maximum Diener pump speed for concentrate pump in mL/min -#define DOSING_CONCENTRATE_PUMP_SPEED 60.0F ///< Diener pump speed for acid and bicarb dosing pump speed in mL/min +#define DOSING_CONCENTRATE_PUMP_SPEED 100.0F ///< Diener pump speed for acid and bicarb dosing pump speed in mL/min #define DRAIN_BICART_PUMP_SPEED 200.0F ///< Diener pump speed for cartridge drains at maximum speed in mL/min #define DEFAULT_ACID_VOLUME_ML 0.67F ///< Acid concentrate volume in ml. Index: firmware/App/Controllers/DryBiCart.c =================================================================== diff -u -rd210786d6c7d75bb0b4d9e18efc40a01d85123fe -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Controllers/DryBiCart.c (.../DryBiCart.c) (revision d210786d6c7d75bb0b4d9e18efc40a01d85123fe) +++ firmware/App/Controllers/DryBiCart.c (.../DryBiCart.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -26,10 +26,12 @@ #include "Messaging.h" #include "ModeGenDialysate.h" #include "OperationModes.h" +#include "PIControllers.h" #include "PressureSensor.h" #include "PersistentAlarm.h" #include "Pressure.h" #include "TaskGeneral.h" +#include "TemperatureSensors.h" #include "Timers.h" #include "Valves.h" @@ -46,8 +48,11 @@ #define DRY_BICART_FILL_DURATION_MIN_MS (2 * MS_PER_SECOND) ///< Minimum fill duration to be met to end the fill cycle. #define DRY_BICART_FILL_COMPLETE_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to reset the request flag after fill complete #define DRY_BICART_FILL_DURATION_DIFF_MS 750 ///< Fill duration difference between last and current fill cycle. -#define DRY_BICART_FILL_COMPLETE_PRESSURE 15.0F ///< Maximum pressure reached to indicate the dry bicart fill being completed. -#define DRY_BICART_FILL_INITIATE_PRESSURE 5.0F ///< Minimum pressure required to initiate the dry bicart fill process. +#define DRY_BICART_FILL_COMPLETE_PRESSURE 12.0F ///< Maximum pressure reached to indicate the dry bicart fill being completed. +#define DRY_BICART_FILL_INITIATE_PRESSURE 7.5F ///< Minimum pressure required to initiate the dry bicart fill process. +#define DRY_BICART_FILL_COMPLETE_SUPPLY_PRESSURE 7.0F ///< Maximum pressure reached to indicate the dry bicart fill being completed. +#define DRY_BICART_FILL_INITIATE_SUPPLY_PRESSURE 5.0F ///< Minimum pressure required to initiate the dry bicart fill process. + #define DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT 10 ///< Default max fill cycle allowed for dry bicart fill/mix with water. #define DRY_BICART_MAX_FILL_CYCLE_CNT 30 ///< Max fill cycle allowed (by override) for dry bicart fill/mix with water. // Dry Bicart Fill Vent @@ -56,9 +61,9 @@ #define DRY_BICART_FILL_VENT_COMPLETE_PRESSURE 1.5F ///< Pressure reached to indicate the dry bicart venting being completed. // Bicarb chamber fill/Supply -#define DRY_BICART_SUPPLY_VALVE_D80_OPEN_TIME_MS ( 3 * MS_PER_SECOND ) ///< Max time allowed for supply (opening D80 valve) during bicarb chamber (F) fill. +#define DRY_BICART_SUPPLY_VALVE_D80_OPEN_TIME_MS ( ( 3 * MS_PER_SECOND ) ) ///< Max time allowed for supply (opening D80 valve) during bicarb chamber (F) fill. #define DRY_BICART_SUPPLY_VENT_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to vent dry bicart gas before actuating Bicarb chamber(F) venting. -#define DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ( 3 * MS_PER_SECOND ) ///< Max time to vent both dry bicart and Chamber F. +#define DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ( 1.2 * MS_PER_SECOND ) ///< Max time to vent both dry bicart and Chamber F. // Dry Bicart Drain #define LARGE_DRY_BICART_MAX_DRAIN_TIME_MS ( 8 * SEC_PER_MIN * MS_PER_SECOND ) ///< Max drain time for large dry bicart in ms. @@ -69,6 +74,46 @@ #define DRY_BICART_DRAIN_COND_ZERO_THRESH 0.05F ///< Zero conductivity threshold #define DRY_BICART_DRAIN_COND_STABLE_SAMPLES 10U ///< Debounce samples (10*50ms=500ms) +// drybicarb mixing +#define DEFAULT_ACID_VOLUME_ML 0.67F ///< Acid concentrate volume in ml. +#define DEFAULT_BICARB_VOLUME_ML 1.15F ///< Bicarb concentrate volume in ml. + +#define KP_SCALE_FACTOR 1 +#define KI_SCALE_FACTOR 1 + +#define BICARB_VOL_CONTROL_P_COEFFICIENT 0.00008484//0.0002121//0.00008484//( 0.0002121 / KP_SCALE_FACTOR )//0.000065F ///< Propotional gain (kp) +#define BICARB_VOL_CONTROL_I_COEFFICIENT 0.00033936//0.0002121//0.00033936//( 0.0003121 * KI_SCALE_FACTOR )//0.00022F ///< Integral gain. (ki) +#define MIN_BICARB_VOLUME_MLPM 0.868686869 ///< Minimum target bicarb in mL/min. +#define MAX_BICARB_VOLUME_MLPM 1.8 ///< Maximum target bicarb volume in mL/min. + +#define ACID_VOL_CONTROL_P_COEFFICIENT 0.00000997//0.000024925F//0.000065F ///< Propotional gain (kp) +#define ACID_VOL_CONTROL_I_COEFFICIENT 0.00003988//0.000014925F//0.00022F ///< Integral gain. (ki) +#define MIN_ACID_VOLUME_MLPM 0.653333333 // 0.2 ///< Minimum target acid volume in mL/min. +#define MAX_ACID_VOLUME_MLPM 0.70 ///< Maximum target acid volume in mL/min. + + +#define STD_BICARB_DOSING 1.146666667F ///< Standard bicarb dosing volume +#define STD_ACID_DOSING 0.666666667F ///< Standard acid dosing volume + +#define DRY_BICARB_TARGET_CONDUCTIVITY 2714.0F ///< Target bicarb conductivity +#define DRY_BICARB_DELTA_CONDUCTIVITY 500.0F ///< Delta bicarb conductivity + +#define DRY_ACID_BICARB_TARGET_CONDUCTIVITY 13734.87F ///< Target acid bicarb mix conductivity +#define DRY_ACID_BICARB_DELTA_CONDUCTIVITY 700.0F ///< Delta acid bicarb mix conductivity + +#define ACID_TYPE_1K_2_5_CA 11192.55F ///< standard acid conductivity for 1K +#define ACID_TYPE_2K_2_5_CA 11313.62F ///< standard acid conductivity for 2K +#define ACID_TYPE_3K_2_5_CA 11435.68F ///< standard acid conductivity for 3K + +#define MIN_BICARB_CONDUCTIVITY 2000 ///< Minimum Bicarb conductivity limit +#define MAX_BICARB_CONDUCTIVITY 4000 ///< Maximum Bicarb conductivity limit + +#define DOSING_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control + +#define DOSE_CONTROL_INTERVAL_MS ( 15 * MS_PER_SECOND ) ///< Dialysate dosing control interval in ms +#define DOSE_CONTROL_INTERVAL ( DOSE_CONTROL_INTERVAL_MS /\ + TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate dose is controlled. + /// Payload record structure for dry bicart fill request typedef struct { @@ -85,6 +130,31 @@ NUM_OF_DRY_BICART_OPERATION ///< Number of dry bicart operation } DRY_BICART_OPERATION_T; +/// Enumeration of dialysate Mixing id. +typedef enum DialysateMixingID +{ + BICARB_MIX_ID = 0, ///< Bicarb mixing id + DIALYSATE_MIX_ID_FIRST = BICARB_MIX_ID, ///< First dialysate mixing in list + ACID_MIX_ID, ///< Acid mix id + NUM_OF_DIALYSATE_MIXING_ID ///< Number of dialysate mix ids +} DIALYSATE_MIXING_ID_T; + +/// Enumeration of dialysate Mixing states. +typedef enum DialysateMixing_States +{ + DIALYSATE_MIXING_OPEN_LOOP_STATE = 0, ///< Dialysate open loop state + DIALYSATE_MIXING_RAMP_UP_STATE, ///< Dialysate mixing ramp up state + DIALYSATE_MIXING_CONTROL_TO_TARGET_STATE, ///< Dialysate mixing control to target state + NUM_OF_DIALYSATE_MIXING_STATES ///< Number of dialysate mixingstates +} DIALYSATE_MIXING_STATE_T; + +/// Dialysate Mixing state machine data structure +typedef struct +{ + U32 controlTimerCounter; ///< Timer counter to perform control on dialysate dose. + DIALYSATE_MIXING_STATE_T dialysateMixingState; ///< Current state of dialysate mixing controller state machine. +} DIALYSATE_DOSE_DATA_T; + // ********** private data ********** static DRY_BICART_FILL_EXEC_STATE_T dryBiCartFillExecState; ///< Current state of dry bicart fill executive state machine. @@ -117,6 +187,30 @@ static DRY_BICART_OPERATION_T dryBicartStartRequest; ///< Dry bicart operation, fill or supply or drain request +// drybicart mixing +static OVERRIDE_F32_T dryBiCartAcidDoseVolume; ///< Acid concentrate volume in ml ( overrideable). +static OVERRIDE_F32_T dryBiCartBicarbDoseVolume; ///< Bicarb concentrate volume in ml ( overrideable). + +static OVERRIDE_F32_T dryBiCartAcidDoseVolumeKpGain; ///< Acid kp gain. +static OVERRIDE_F32_T dryBiCartAcidDoseVolumeKiGain; ///< Acid ki gain. + +static OVERRIDE_F32_T dryBiCartBicarbDoseVolumeKpGain; ///< Bicarb kp gain +static OVERRIDE_F32_T dryBiCartBicarbDoseVolumeKiGain; ///< Acid ki gain. + +static DIALYSATE_DOSE_DATA_T dialysateMix[ NUM_OF_DIALYSATE_MIXING_ID ]; ///< Array of dialysate mixing data structure. + +static OVERRIDE_F32_T dryBiCartBicarbTargetConductivity; ///< Target bicarb conductivity +static OVERRIDE_F32_T dryBiCartBicarbDeltaConductivity; ///< Target delta conductivity + +static OVERRIDE_F32_T dryBiCartAcidBicarbMixTargetConductivity; ///< Acid bicarb mix conductivity +static OVERRIDE_F32_T dryBiCartAcidBicarbMixDeltaConductivity; ///< Acid bicarb delta conductivity + +static PI_CONTROLLER_SIGNALS_DATA bicarbControlSignals; ///< Bicarb closed loop control signal data +static PI_CONTROLLER_SIGNALS_DATA acidControlSignals; ///< Acid closed loop control signal data + +//For testing +static F32 pIControlSignal[ NUM_OF_CONTROLLER_SIGNAL ]; + // ********** private function prototypes ********** static void updateDrybicartOperation(void); @@ -142,6 +236,12 @@ static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainState( void ); static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainDurationCheckState( void ); static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainEndState( void ); + +// dosing control loop +static DIALYSATE_MIXING_STATE_T handleDialysateOpenLoopState( DIALYSATE_MIXING_ID_T doseId ); +static DIALYSATE_MIXING_STATE_T handleDialysateDoseRampToTargetState( DIALYSATE_MIXING_ID_T doseId ); +static DIALYSATE_MIXING_STATE_T handleDialysateDoseControlToTargetState( DIALYSATE_MIXING_ID_T doseId ); + // publish the status static void publishDryBicartData( void ); static U32 getDryBicartFillDataPublishInterval( void ); @@ -156,52 +256,122 @@ *************************************************************************/ void initDryBiCart( void ) { - dryBiCartFillExecState = DRY_BICART_START_STATE; - bicarbChamberFillExecState = BICARB_CHAMBER_START_STATE; - dryBiCartDrainExecState = DRY_BICART_DRAIN_START_STATE; - dryBicartStartRequest = DRY_BICART_IDLE; + DIALYSATE_MIXING_ID_T mixId; - dryBiCartDataPublishInterval.data = DRY_BICART_DATA_PUBLISH_INTERVAL; - dryBiCartDataPublishInterval.ovData = DRY_BICART_DATA_PUBLISH_INTERVAL; - dryBiCartDataPublishInterval.ovInitData = 0; - dryBiCartDataPublishInterval.override = OVERRIDE_RESET; + dryBiCartFillExecState = DRY_BICART_START_STATE; + bicarbChamberFillExecState = BICARB_CHAMBER_START_STATE; + dryBiCartDrainExecState = DRY_BICART_DRAIN_START_STATE; + dryBicartStartRequest = DRY_BICART_IDLE; - biCartMaxFillCycleCount.data = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; - biCartMaxFillCycleCount.ovData = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; - biCartMaxFillCycleCount.ovInitData = 0; - biCartMaxFillCycleCount.override = OVERRIDE_RESET; + for ( mixId = DIALYSATE_MIX_ID_FIRST; mixId < NUM_OF_DIALYSATE_MIXING_ID; mixId++ ) + { + dialysateMix[ mixId ].dialysateMixingState = DIALYSATE_MIXING_OPEN_LOOP_STATE; + dialysateMix[ mixId ].controlTimerCounter = 0; + } - dryBiCartFillRequested.data = FALSE; - dryBiCartFillRequested.ovData = FALSE; - dryBiCartFillRequested.ovInitData = FALSE; - dryBiCartFillRequested.override = OVERRIDE_RESET; + dryBiCartDataPublishInterval.data = DRY_BICART_DATA_PUBLISH_INTERVAL; + dryBiCartDataPublishInterval.ovData = DRY_BICART_DATA_PUBLISH_INTERVAL; + dryBiCartDataPublishInterval.ovInitData = 0; + dryBiCartDataPublishInterval.override = OVERRIDE_RESET; - dryBiCartDrainRequested.data = FALSE; - dryBiCartDrainRequested.ovData = FALSE; - dryBiCartDrainRequested.ovInitData = FALSE; - dryBiCartDrainRequested.override = OVERRIDE_RESET; + biCartMaxFillCycleCount.data = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; + biCartMaxFillCycleCount.ovData = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; + biCartMaxFillCycleCount.ovInitData = 0; + biCartMaxFillCycleCount.override = OVERRIDE_RESET; - bicarbChamberFillRequested.data = FALSE; - bicarbChamberFillRequested.ovData = FALSE; - bicarbChamberFillRequested.ovInitData = FALSE; - bicarbChamberFillRequested.override = OVERRIDE_RESET; + dryBiCartFillRequested.data = FALSE; + dryBiCartFillRequested.ovData = FALSE; + dryBiCartFillRequested.ovInitData = FALSE; + dryBiCartFillRequested.override = OVERRIDE_RESET; - dryBiCartType.data = FALSE; - dryBiCartType.ovData = FALSE; - dryBiCartType.ovInitData = 0; - dryBiCartType.override = OVERRIDE_RESET; + dryBiCartDrainRequested.data = FALSE; + dryBiCartDrainRequested.ovData = FALSE; + dryBiCartDrainRequested.ovInitData = FALSE; + dryBiCartDrainRequested.override = OVERRIDE_RESET; - dryBiCartFillStartTime = 0; - lastFillDurationInMS = 0; - currentFillDurationInMS = 0; - dryBiCartDataPublicationTimerCounter = 0; - biCartFillCycleCounter = 0; - dryBiCarbSupplyStartTime = 0; - dryBiCarbSypplyVentStartTime = 0; - dryBiCartDrainStartTime = 0; - dryBiCartDrainLastCondSampleTime = 0; - dryBiCartDrainCondStableCount = 0; - dryBiCartDrainTimePeriod = 0; + bicarbChamberFillRequested.data = FALSE; + bicarbChamberFillRequested.ovData = FALSE; + bicarbChamberFillRequested.ovInitData = FALSE; + bicarbChamberFillRequested.override = OVERRIDE_RESET; + + dryBiCartType.data = FALSE; + dryBiCartType.ovData = FALSE; + dryBiCartType.ovInitData = 0; + dryBiCartType.override = OVERRIDE_RESET; + + dryBiCartAcidDoseVolume.data = DEFAULT_ACID_VOLUME_ML; + dryBiCartAcidDoseVolume.ovData = DEFAULT_ACID_VOLUME_ML; + dryBiCartAcidDoseVolume.ovInitData = 0.0F; + dryBiCartAcidDoseVolume.override = OVERRIDE_RESET; + + dryBiCartBicarbDoseVolume.data = DEFAULT_BICARB_VOLUME_ML; + dryBiCartBicarbDoseVolume.ovData = DEFAULT_BICARB_VOLUME_ML; + dryBiCartBicarbDoseVolume.ovInitData = 0.0F; + dryBiCartBicarbDoseVolume.override = OVERRIDE_RESET; + + dryBiCartAcidDoseVolumeKpGain.data = ACID_VOL_CONTROL_P_COEFFICIENT; + dryBiCartAcidDoseVolumeKpGain.ovData = ACID_VOL_CONTROL_P_COEFFICIENT; + dryBiCartAcidDoseVolumeKpGain.ovInitData = 0.0F; + dryBiCartAcidDoseVolumeKpGain.override = OVERRIDE_RESET; + + dryBiCartAcidDoseVolumeKiGain.data = ACID_VOL_CONTROL_I_COEFFICIENT; + dryBiCartAcidDoseVolumeKiGain.ovData = ACID_VOL_CONTROL_I_COEFFICIENT; + dryBiCartAcidDoseVolumeKiGain.ovInitData = 0.0F; + dryBiCartAcidDoseVolumeKiGain.override = OVERRIDE_RESET; + + dryBiCartBicarbDoseVolumeKpGain.data = BICARB_VOL_CONTROL_P_COEFFICIENT; + dryBiCartBicarbDoseVolumeKpGain.ovData = BICARB_VOL_CONTROL_P_COEFFICIENT; + dryBiCartBicarbDoseVolumeKpGain.ovInitData = 0.0F; + dryBiCartBicarbDoseVolumeKpGain.override = OVERRIDE_RESET; + + dryBiCartBicarbDoseVolumeKiGain.data = BICARB_VOL_CONTROL_I_COEFFICIENT; + dryBiCartBicarbDoseVolumeKiGain.ovData = BICARB_VOL_CONTROL_I_COEFFICIENT; + dryBiCartBicarbDoseVolumeKiGain.ovInitData = 0.0F; + dryBiCartBicarbDoseVolumeKiGain.override = OVERRIDE_RESET; + + dryBiCartBicarbTargetConductivity.data = DRY_BICARB_TARGET_CONDUCTIVITY; + dryBiCartBicarbTargetConductivity.ovData = DRY_BICARB_TARGET_CONDUCTIVITY; + dryBiCartBicarbTargetConductivity.ovInitData = 0.0F; + dryBiCartBicarbTargetConductivity.override = OVERRIDE_RESET; + + dryBiCartBicarbDeltaConductivity.data = DRY_BICARB_DELTA_CONDUCTIVITY; + dryBiCartBicarbDeltaConductivity.ovData = DRY_BICARB_DELTA_CONDUCTIVITY; + dryBiCartBicarbDeltaConductivity.ovInitData = 0.0F; + dryBiCartBicarbDeltaConductivity.override = OVERRIDE_RESET; + + dryBiCartAcidBicarbMixTargetConductivity.data = DRY_ACID_BICARB_TARGET_CONDUCTIVITY; + dryBiCartAcidBicarbMixTargetConductivity.ovData = DRY_ACID_BICARB_TARGET_CONDUCTIVITY; + dryBiCartAcidBicarbMixTargetConductivity.ovInitData = 0.0F; + dryBiCartAcidBicarbMixTargetConductivity.override = OVERRIDE_RESET; + + dryBiCartAcidBicarbMixDeltaConductivity.data = DRY_ACID_BICARB_DELTA_CONDUCTIVITY; + dryBiCartAcidBicarbMixDeltaConductivity.ovData = DRY_ACID_BICARB_DELTA_CONDUCTIVITY; + dryBiCartAcidBicarbMixDeltaConductivity.ovInitData = 0.0F; + dryBiCartAcidBicarbMixDeltaConductivity.override = OVERRIDE_RESET; + + dryBiCartFillStartTime = 0; + lastFillDurationInMS = 0; + currentFillDurationInMS = 0; + dryBiCartDataPublicationTimerCounter = 0; + biCartFillCycleCounter = 0; + dryBiCarbSupplyStartTime = 0; + dryBiCarbSypplyVentStartTime = 0; + dryBiCartDrainStartTime = 0; + dryBiCartDrainLastCondSampleTime = 0; + dryBiCartDrainCondStableCount = 0; + dryBiCartDrainTimePeriod = 0; + + initializePIController(PI_CONTROLLER_ID_BICARB_VOL, 0.0F,\ + getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ + MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + + resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); + + initializePIController(PI_CONTROLLER_ID_ACID_VOL, 0.0F, \ + getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ + MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + + resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); } /*********************************************************************//** @@ -219,6 +389,43 @@ /*********************************************************************//** * @brief + * The execDialysateCompositionMixingController function executes the dialysate mixing controller. + * @details \b Inputs: dialysateDosingState + * @details \b Outputs: dialysateDosingState + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid dialysate dosing + * state machine found. + * @return none + *************************************************************************/ +void execDialysateCompositionMixingController( void ) +{ + DIALYSATE_MIXING_ID_T mixId; + + for ( mixId = DIALYSATE_MIX_ID_FIRST; mixId < NUM_OF_DIALYSATE_MIXING_ID; mixId++ ) + { + switch ( dialysateMix[ mixId ].dialysateMixingState ) + { + case DIALYSATE_MIXING_OPEN_LOOP_STATE: + dialysateMix[ mixId ].dialysateMixingState = handleDialysateOpenLoopState( mixId ); + break; + + case DIALYSATE_MIXING_RAMP_UP_STATE: + dialysateMix[ mixId ].dialysateMixingState = handleDialysateDoseRampToTargetState( mixId ); + break; + + case DIALYSATE_MIXING_CONTROL_TO_TARGET_STATE: + dialysateMix[ mixId ].dialysateMixingState = handleDialysateDoseControlToTargetState( mixId ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSATE_DOSE_EXEC_INVALID_STATE, mixId ) + dialysateMix[ mixId ].dialysateMixingState = DIALYSATE_MIXING_OPEN_LOOP_STATE; + break; + } + } +} + +/*********************************************************************//** + * @brief * The execDryBicart function executes the set of dry bicarbonate cartridge fill, * bicarbonate chamber fill and bicarbonate cartridge drain related state machines one at time * @details \b Inputs: dryBicartStartRequest @@ -229,6 +436,12 @@ { updateDrybicartOperation(); + if( getCurrentBalancingChamberExecState() > BAL_CHAMBER_STATE_IDLE ) + { + // closed loop bicarb and acid dosing controller + execDialysateCompositionMixingController(); + } + // top level state machine selection DRY_BICART_OPERATION_T dryBicartState = dryBicartStartRequest; U32 dryBicartSubstate; @@ -263,6 +476,7 @@ break; } + (void)dryBicartSubstate; // Publish dry bicart data publishDryBicartData(); } @@ -279,6 +493,8 @@ *************************************************************************/ U32 execDryBicartFillMode( void ) { + hydChamberWaterInletControl(); + // execute drybicart fill state machine switch ( dryBiCartFillExecState ) { @@ -413,6 +629,234 @@ /*********************************************************************//** * @brief + * The setBicarbDoseVol function sets bicarb dose volume provided by the controller + * @details \b Inputs: none + * @details \b Outputs: dryBiCartBicarbDoseVolume + * @param targetValue bicarb dose volume + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +void setBicarbDoseVol( F32 targetValue ) +{ + dryBiCartBicarbDoseVolume.data = targetValue; +} + +/*********************************************************************//** + * @brief + * TThe getBicarbDoseVol function gets the bicarb dose volume provided by the controller + * @details \b Inputs: dryBiCartBicarbDoseVolume + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getBicarbDoseVol( void ) +{ + F32 result = dryBiCartBicarbDoseVolume.data; + + if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolume.override ) + { + result = dryBiCartBicarbDoseVolume.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setAcidDoseVol function sets acid dose volume provided by the controller + * flag value to be True. + * @details \b Inputs: none + * @details \b Outputs: dryBiCartAcidDoseVolume + * @param targetValue acid dose volume + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +void setAcidDoseVol( F32 targetValue ) +{ + dryBiCartAcidDoseVolume.data = targetValue; +} + +/*********************************************************************//** + * @brief + * The getBicarbAcidDoseVol function gets acid dose volume provided by the controller + * flag values + * @details \b Inputs: dryBiCartAcidDoseVolume + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getAcidDoseVol( void ) +{ + F32 result = dryBiCartAcidDoseVolume.data; + + if ( OVERRIDE_KEY == dryBiCartAcidDoseVolume.override ) + { + result = dryBiCartAcidDoseVolume.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getBicarbDeltaConductivity function gets the delta target conductivity + * @details \b Inputs: dryBiCartBicarbDeltaConductivity + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getBicarbDeltaConductivity( void ) +{ + F32 result = dryBiCartBicarbDeltaConductivity.data; + + if ( OVERRIDE_KEY == dryBiCartBicarbDeltaConductivity.override ) + { + result = dryBiCartBicarbDeltaConductivity.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getBicarbTargetConductivity function gets the target conductivity + * @details \b Inputs: dryBiCartBicarbTargetConductivity + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getBicarbTargetConductivity( void ) +{ + F32 result = dryBiCartBicarbTargetConductivity.data; + + if ( OVERRIDE_KEY == dryBiCartBicarbTargetConductivity.override ) + { + result = dryBiCartBicarbTargetConductivity.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAcidBicarbDeltaConductivity function gets the acid bicarb delta target conductivity + * flag values + * @details \b Inputs: dryBiCartAcidBicarbMixDeltaConductivity + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getAcidBicarbDeltaConductivity( void ) +{ + F32 result = dryBiCartAcidBicarbMixDeltaConductivity.data; + + if ( OVERRIDE_KEY == dryBiCartAcidBicarbMixDeltaConductivity.override ) + { + result = dryBiCartAcidBicarbMixDeltaConductivity.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAcidBicarbTargetConductivity function gets the acid bicarb delta target conductivity + * flag values + * @details \b Inputs: dryBiCartAcidBicarbMixTargetConductivity + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getAcidBicarbTargetConductivity( void ) +{ + F32 result = dryBiCartAcidBicarbMixTargetConductivity.data; + + if ( OVERRIDE_KEY == dryBiCartAcidBicarbMixTargetConductivity.override ) + { + result = dryBiCartAcidBicarbMixTargetConductivity.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getBicarbKpGainCoefficient function gets the Kp Gain for closed loop + * bicarb dose volume control + * flag values + * @details \b Inputs: dryBiCartBicarbDoseVolumeKpGain + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getBicarbKpGainCoefficient( void ) +{ + F32 result = dryBiCartBicarbDoseVolumeKpGain.data; + + if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolumeKpGain.override ) + { + result = dryBiCartBicarbDoseVolumeKpGain.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getBicarbKiGainCoefficient function gets the Kp Gain for closed loop + * bicarb dose volume control + * flag values + * @details \b Inputs: dryBiCartBicarbDoseVolumeKiGain + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getBicarbKiGainCoefficient( void ) +{ + F32 result = dryBiCartBicarbDoseVolumeKiGain.data; + + if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolumeKiGain.override ) + { + result = dryBiCartBicarbDoseVolumeKiGain.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAcidKpGainCoefficient function gets the Kp Gain for closed loop + * acid dose volume control + * flag values + * @details \b Inputs: dryBiCartAcidDoseVolumeKpGain + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getAcidKpGainCoefficient( void ) +{ + F32 result = dryBiCartAcidDoseVolumeKpGain.data; + + if ( OVERRIDE_KEY == dryBiCartAcidDoseVolumeKpGain.override ) + { + result = dryBiCartAcidDoseVolumeKpGain.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAcidKiGainCoefficient function gets the Ki Gain for closed loop + * acid dose volume control + * flag values + * @details \b Inputs: dryBiCartAcidDoseVolumeKiGain + * @details \b Outputs: none + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +F32 getAcidKiGainCoefficient( void ) +{ + F32 result = dryBiCartAcidDoseVolumeKiGain.data; + + if ( OVERRIDE_KEY == dryBiCartAcidDoseVolumeKiGain.override ) + { + result = dryBiCartAcidDoseVolumeKiGain.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief * The setBicarbChamberFillRequested function sets the chmaberFillRequest * flag value to be True. * @details \b Inputs: dryBiCartFillRequested, dryBiCartDrainRequested @@ -555,6 +999,160 @@ /*********************************************************************//** * @brief + * The handleDialysateOpenLoopState function handles the dialysate open loop state of + * the dialysate dose controller state machine. + * @details \b Inputs: D17_COND, D29_COND + * @details \b Outputs: none + * @param doseId dialysate dose id to run the dialysate dose + * @return next state for the controller state machine + *************************************************************************/ +static DIALYSATE_MIXING_STATE_T handleDialysateOpenLoopState( DIALYSATE_MIXING_ID_T mixId ) +{ + DIALYSATE_MIXING_STATE_T result = DIALYSATE_MIXING_OPEN_LOOP_STATE; + + if ( BICARB_MIX_ID == mixId ) + { +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + F32 measuredBicarbConductivity = getFilteredConductivity( D17_COND ); +#else + F32 measuredBicarbConductivity = getFilteredConductivity( D17_COND ); +#endif + // if measured conductivity crossed (targetConductivity- deltaConuctivity) , switch to closed loop + if ( measuredBicarbConductivity >= ( getBicarbTargetConductivity() - getBicarbDeltaConductivity() ) ) + { + result = DIALYSATE_MIXING_RAMP_UP_STATE; + } + } + else if ( ACID_MIX_ID == mixId ) + { +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + F32 measuredAcidBicarbMixConductivity = getFilteredConductivity( D27_COND ); +#else + F32 measuredAcidBicarbMixConductivity = getFilteredConductivity( D27_COND ); +#endif + // if measured conductivity crossed (targetConductivity- deltaConuctivity) , switch to closed loop + if ( measuredAcidBicarbMixConductivity >= ( getAcidBicarbTargetConductivity() - getAcidBicarbDeltaConductivity() ) ) + { + result = DIALYSATE_MIXING_RAMP_UP_STATE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDialysatePumpRampToTargetState function handles the dialysate ramp to target state of + * the dialysate dose controller state machine. + * @details \b Inputs: none + * @details \b Outputs: none + * @param doseId dose id to + * @return next state for the controller state machine + *************************************************************************/ +static DIALYSATE_MIXING_STATE_T handleDialysateDoseRampToTargetState( DIALYSATE_MIXING_ID_T mixId ) +{ + DIALYSATE_MIXING_STATE_T state = DIALYSATE_MIXING_RAMP_UP_STATE; + + //if ( TRUE == stepDialysatePumpToTargetSpeed( pumpId ) ) + { + if ( BICARB_MIX_ID == mixId ) + { + resetPIController( PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD ); + + state = DIALYSATE_MIXING_CONTROL_TO_TARGET_STATE; + } + else if ( ACID_MIX_ID == mixId ) + { + resetPIController( PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD ); + + state = DIALYSATE_MIXING_CONTROL_TO_TARGET_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDialysatePumpControlToTargetState function handles the control to + * target state of the dialysate dose controller state machine.. + * @details \b Inputs: D17_COND, D29_COND, controlTimerCounter + * @details \b Outputs:none + * @return next state of the controller state machine + *************************************************************************/ +static DIALYSATE_MIXING_STATE_T handleDialysateDoseControlToTargetState( DIALYSATE_MIXING_ID_T mixId ) +{ + DIALYSATE_MIXING_STATE_T state = DIALYSATE_MIXING_CONTROL_TO_TARGET_STATE; + + // control at set minimum interval or interval is expired and balance chamber fill is complete + if ( ( ( ++dialysateMix[ mixId ].controlTimerCounter >= DOSE_CONTROL_INTERVAL ) ) ) + { + dialysateMix[ mixId ].controlTimerCounter = 0; + + // Control happen only when balancing chamber fill is complete. + //if ( FALSE == getBalancingChamberFillinProgressStatus() ) + { + // Control based on the measured and target conductivity + if ( BICARB_MIX_ID == mixId ) + { + PI_CONTROLLER_SIGNALS_DATA debugBicarbControl; + F32 measuredBicarbConductivity; + //U32 i; + +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + easuredBicarbConductivity = getFilteredConductivity( D17_COND ); +#else + measuredBicarbConductivity = getFilteredConductivity( D17_COND ); +#endif + F32 bicarbDoseVol = runPIController(PI_CONTROLLER_ID_BICARB_VOL, getBicarbTargetConductivity(), measuredBicarbConductivity); + //Set bicarb dosing vol + setBicarbDoseVol( bicarbDoseVol ); + //U32 i; + +#if 0 + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_BICARB_VOL, (PI_CONTROLLER_SIGNALS_ID)i ); + } +#endif + debugBicarbControl = getDebugPIControllerSignals( PI_CONTROLLER_ID_BICARB_VOL ); + + memcpy((void*)&bicarbControlSignals, (void*)&debugBicarbControl, sizeof(PI_CONTROLLER_SIGNALS_DATA)); + } + // ACID dose + else if ( ACID_MIX_ID == mixId ) + { + F32 measuredAcidBicarbMixConductivity; + //U32 i; + PI_CONTROLLER_SIGNALS_DATA debugAcidControl; + +#ifdef __TEENSY_CONDUCTIVITY_DRIVER__ + measuredAcidBicarbMixConductivity = getFilteredConductivity( D27_COND ); +#else + measuredAcidBicarbMixConductivity = getFilteredConductivity( D27_COND ); +#endif + F32 acidDoseVol = runPIController(PI_CONTROLLER_ID_ACID_VOL, getAcidBicarbTargetConductivity(), measuredAcidBicarbMixConductivity); + //Set acid dosing vol + setAcidDoseVol( acidDoseVol ); + //U32 i; + +#if 0 + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_ACID_VOL, (PI_CONTROLLER_SIGNALS_ID)i ); + } +#endif + debugAcidControl = getDebugPIControllerSignals( PI_CONTROLLER_ID_ACID_VOL ); + memcpy((void*)&acidControlSignals, (void*)&debugAcidControl, sizeof(PI_CONTROLLER_SIGNALS_DATA)); + } + } + } + + return state; +} + +/*********************************************************************//** + * @brief * The updateDrybicartOperation function initiates the water fill, bicarbonate supply or bicarbonate drain * operation * @details \b Inputs: none @@ -896,13 +1494,13 @@ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCheckLevelState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_CHECK_LEVEL_STATE; - LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); + LEVEL_STATE_T bicarbChamberLevel = getBicarbChamberLevelStatus(); // TODO: Confirm D80 open on chamber low or end of balancing chamber switching? // TODO: Enable the below code once level sensor is working //if ( LEVEL_STATE_LOW == bicarbChamberLevel ) - //{ - if ( getBalancingChamberFillinProgressStatus() == FALSE ) + { + // if ( getBalancingChamberFillinProgressStatus() == FALSE ) { // Open the Bicarb chamber inlet valve setValveState( D80_VALV, VALVE_STATE_OPEN ); @@ -912,7 +1510,8 @@ state = BICARB_CHAMBER_FILL_STATE; } - //} + } + // TODO: alarm return state; } @@ -929,7 +1528,7 @@ { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_FILL_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); - LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); + LEVEL_STATE_T bicarbChamberLevel = getBicarbChamberLevelStatus(); // Once level reached, close the valve if ( LEVEL_STATE_HIGH == bicarbChamberLevel ) @@ -938,11 +1537,15 @@ state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; } // Open water inlet valve to fill the bicart - else if ( d66Pressure <= DRY_BICART_FILL_INITIATE_PRESSURE ) + else if ( d66Pressure <= DRY_BICART_FILL_INITIATE_SUPPLY_PRESSURE ) { setValveState( D65_VALV, VALVE_STATE_OPEN ); state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; } + else + { + state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; + } return state; } @@ -959,10 +1562,10 @@ { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); - LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); + LEVEL_STATE_T bicarbChamberLevel = getBicarbChamberLevelStatus(); // Once level reached, close the valve - if ( ( LEVEL_STATE_HIGH == bicarbChamberLevel ) || + if ( ( LEVEL_STATE_HIGH == bicarbChamberLevel ) || ( TRUE == didTimeout( dryBiCarbSupplyStartTime, DRY_BICART_SUPPLY_VALVE_D80_OPEN_TIME_MS ) ) ) { setValveState( D65_VALV, VALVE_STATE_CLOSED ); @@ -971,9 +1574,12 @@ dryBiCarbSypplyVentStartTime = getMSTimerCount(); state = BICARB_SUPPLY_VENT_START_STATE; } - + else if ( d66Pressure <= DRY_BICART_FILL_INITIATE_SUPPLY_PRESSURE ) + { + setValveState( D65_VALV, VALVE_STATE_OPEN ); + } // Close water inlet valve as fill is complete. - if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_PRESSURE ) + else if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_SUPPLY_PRESSURE ) { setValveState( D65_VALV, VALVE_STATE_CLOSED ); } @@ -1002,6 +1608,7 @@ if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ) ) { //Vent chamber F after 3 sec + setValveState( D85_VALV, VALVE_STATE_CLOSED ); setValveState( D64_VALV, VALVE_STATE_OPEN ); dryBiCarbSypplyVentStartTime = getMSTimerCount(); state = BICARB_SUPPLY_VENT_END_STATE; @@ -1023,11 +1630,11 @@ BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_SUPPLY_VENT_END_STATE; // close bicart vent and chamber f vent after 3 sec - if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ) ) + if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_TIME_MS ) ) { setValveState( D85_VALV, VALVE_STATE_CLOSED ); setValveState( D64_VALV, VALVE_STATE_CLOSED); - + bicarbChamberFillRequested.data = FALSE; // for this request override also cleared bicarbChamberFillRequested.ovData = FALSE; @@ -1229,16 +1836,32 @@ data.dryBiCartFillExecState = (U32)dryBiCartFillExecState; data.bicarbChamberFillExecState = (U32)bicarbChamberFillExecState; + // TODO : temporarily disabled. restore it after testing +#if 0 data.dryBiCartDrainExecState = (U32)dryBiCartDrainExecState; data.dryBiCartFillCycleCounter = biCartFillCycleCounter; data.dryBiCartMaxFillCycleCount = getU32OverrideValue( &biCartMaxFillCycleCount ); data.dryBiCartFillRequest = getU32OverrideValue( &dryBiCartFillRequested ); data.bicarbChamberFillRequest = getU32OverrideValue( &bicarbChamberFillRequested ); data.dryBiCartDrainRequest = getU32OverrideValue( &dryBiCartDrainRequested ); data.dryBiCartLastFillTime = lastFillDurationInMS; - data.dryBiCartCurrentFillTime = currentFillDurationInMS; + data.dryBiCartCurrentFillTime = currentFillDurationInMS; data.dryBiCartType = getU32OverrideValue( &dryBiCartType ); data.dryBiCartDrainTimePeriod = dryBiCartDrainTimePeriod; +#endif + + // TODO: remove after feature testing + memcpy( &data.dryBiCartBicarbDosingControl, &bicarbControlSignals, sizeof( PI_CONTROLLER_SIGNALS_DATA ) ); + // TODO: remove after feature testing + memcpy( &data.dryBiCartAcidDosingControl , &acidControlSignals , sizeof( PI_CONTROLLER_SIGNALS_DATA ) ); + + data.dryBiCartAcidDoseVolume = getAcidDoseVol(); + data.dryBiCartBicarbDoseVolume = getBicarbDoseVol(); + + // TODO: remove after feature testing + data.dryBiCartBicarbDosingKPgain = getBicarbKpGainCoefficient(); + // TODO: remove after feature testing + data.dryBiCartBicarbDosingKIgain = getBicarbKiGainCoefficient(); broadcastData( MSG_ID_DD_DRY_BICART_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( DRY_BICART_DATA_T ) ); @@ -1352,4 +1975,196 @@ return result; } +/*********************************************************************//** + * @brief + * The testAcidDoseVolumeOverride function sets the override value + * of the acid concentrate dosing volume. + * @details Inputs: dryBiCartAcidDoseVolume + * @details Outputs: dryBiCartAcidDoseVolume + * @param message Override message from Dialin which includes the override + * value to override the acid concentrate dosing volume. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartAcidDoseVolumeOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartAcidDoseVolume ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testBicarbDoseVolumeOverride function sets the override value + * of the bicarb concentrate dosing volume. + * @details Inputs: dryBiCartBicarbDoseVolume + * @details Outputs: dryBiCartBicarbDoseVolume + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate dosing volume. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartBicarbDoseVolumeOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartBicarbDoseVolume ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartBicarbKpGainBicarbDoseVolumeOverride function sets the override value + * of the Kp gain coefficient for closed loop bicarb dosing volume control + * @details Inputs: dryBiCartBicarbDoseVolumeKpGain + * @details Outputs: dryBiCartBicarbDoseVolumeKpGain + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate dosing volume kp gain. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartBicarbDoseVolControlKpGainOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartBicarbDoseVolumeKpGain ); + + initializePIController(PI_CONTROLLER_ID_BICARB_VOL, MIN_BICARB_VOLUME_MLPM,\ + getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ + MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + + resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartBicarbKiGainBicarbDoseVolumeOverride function sets the override value + * of the Ki gain coefficient for closed loop bicarb concentrate dosing volume control + * @details Inputs: dryBiCartBicarbDoseVolumeKiGain + * @details Outputs: dryBiCartBicarbDoseVolumeKiGain + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate dosing volume ki gain. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartBicarbDoseVolControlKiGainOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartBicarbDoseVolumeKiGain ); + + initializePIController(PI_CONTROLLER_ID_BICARB_VOL, MIN_BICARB_VOLUME_MLPM,\ + getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ + MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartBicarbKpGainBicarbDoseVolumeOverride function sets the override value + * of the Kp gain coefficient for closed loop acid concentrate dosing volume control + * @details Inputs: dryBiCartAcidDoseVolumeKpGain + * @details Outputs: dryBiCartAcidDoseVolumeKpGain + * @param message Override message from Dialin which includes the override + * value to override the acid concentrate dosing volume kp gain. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartAcidDoseVolControlKpGainOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartAcidDoseVolumeKpGain ); + + initializePIController(PI_CONTROLLER_ID_ACID_VOL, MIN_ACID_VOLUME_MLPM, \ + getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ + MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartBicarbKiGainBicarbDoseVolumeOverride function sets the override value + * of the Ki gain coefficient for closed loop acid concentrate dosing volume control + * @details Inputs: dryBiCartAcidDoseVolumeKiGain + * @details Outputs: dryBiCartAcidDoseVolumeKiGain + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate dosing volume ki gain. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartAcidDoseVolControlKiGainOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartAcidDoseVolumeKiGain ); + + initializePIController(PI_CONTROLLER_ID_ACID_VOL, MIN_ACID_VOLUME_MLPM, \ + getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ + MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); + resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartTargetConductivityOverride function sets the override value + * of target conductivity for closed loop control + * @details Inputs: dryBiCartTargetConductivity + * @details Outputs: dryBiCartTargetConductivity + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate target conductivity. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartTargetConductivityOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartBicarbTargetConductivity ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartDeltaConductivityOverride function sets the override value + * of delta target conductivity for closed loop control + * @details Inputs: dryBiCartDeltaConductivity + * @details Outputs: dryBiCartDeltaConductivity + * @param message Override message from Dialin which includes the override + * value to override the bicarb concentrate delta target conductivity. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartDeltaConductivityOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartBicarbDeltaConductivity ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartAcidBicarbTargetConductivityOverride function sets the override value + * of acid bicarb mix target conductivity for closed loop control + * @details Inputs: dryBiCartAcidBicarbMixTargetConductivity + * @details Outputs: dryBiCartAcidBicarbMixTargetConductivity + * @param message Override message from Dialin which includes the override + * value to override the acid bicarb mix target conductivity. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartAcidBicarbTargetConductivityOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartAcidBicarbMixTargetConductivity ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testDryBiCartAcidBicarbDeltaConductivityOverride function sets the override value + * of delta target conductivity for acid bicarb mix closed loop control + * @details Inputs: dryBiCartDeltaConductivity + * + * @details Outputs: dryBiCartDeltaConductivity + * @param message Override message from Dialin which includes the override + * value to override the acid bicarb mix target delta conductivity. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testDryBiCartAcidBicarbDeltaConductivityOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &dryBiCartAcidBicarbMixDeltaConductivity ); + + return result; +} + /**@}*/ Index: firmware/App/Controllers/DryBiCart.h =================================================================== diff -u -rd210786d6c7d75bb0b4d9e18efc40a01d85123fe -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Controllers/DryBiCart.h (.../DryBiCart.h) (revision d210786d6c7d75bb0b4d9e18efc40a01d85123fe) +++ firmware/App/Controllers/DryBiCart.h (.../DryBiCart.h) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -18,6 +18,7 @@ #ifndef __DRY_BICART_H__ #define __DRY_BICART_H__ +#include "PIControllers.h" #include "DDCommon.h" #include "DDDefs.h" @@ -32,11 +33,14 @@ // ********** public definitions ********** +//#pragma pack(push, 1) /// dry bicart data structure typedef struct { U32 dryBiCartFillExecState; ///< Dry bicart execution state U32 bicarbChamberFillExecState; ///< Bicarb chamber Fill execution state + //TODO: restore it after testing complete +#if 0 U32 dryBiCartDrainExecState; ///< Dry bicart drain execution state U32 dryBiCartFillCycleCounter; ///< Dry bicart fill cycle counter U32 dryBiCartMaxFillCycleCount; ///< Dry bicart fill cycle max count @@ -47,8 +51,22 @@ U32 dryBiCartCurrentFillTime; ///< Dry bicart current fill duration in milli second U32 dryBiCartType; ///< Dry bicart type (small-0/large-1) U32 dryBiCartDrainTimePeriod; ///< Dry bicart drain time based on catridge type (small/large) +#endif + // TODO: remove after closed loops stabilized + PI_CONTROLLER_SIGNALS_DATA dryBiCartBicarbDosingControl; ///< Dry bicart bicarb dosing closed loop control signals data + PI_CONTROLLER_SIGNALS_DATA dryBiCartAcidDosingControl; ///< Dry bicart acid dosing closed loop control signals data + + F32 dryBiCartAcidDoseVolume; ///< Dry bicart acid dose volume + F32 dryBiCartBicarbDoseVolume; ///< Dry bicart bicarb dose volume + + F32 dryBiCartBicarbDosingKPgain; ///< Dry bicart bicarb dosing control kp gain + F32 dryBiCartBicarbDosingKIgain; ///< Dry bicart bicarb dosing control ki gain + //F32 dryBiCartAcidDosingKPgain; ///< Dry bicart acid dosing control kp gain + //F32 dryBiCartAcidDosingKIgain; ///< Dry bicart acid dosing control ki gain } DRY_BICART_DATA_T; +//#pragma pack(pop) + // ********** public function prototypes ********** void initDryBiCart( void ); @@ -61,6 +79,26 @@ BOOL setBicartFillRequested( void ); BOOL setBicartDrainRequested( void ); +F32 getAcidBicarbTargetConductivity( void ); +F32 getAcidBicarbDeltaConductivity( void ); + +F32 getBicarbTargetConductivity( void ); +F32 getBicarbDeltaConductivity( void ); + +//void setBicarb( F32 targetValue ); +//F32 getBicarb( void ); +void setBicarbDoseVol( F32 targetValue ); +F32 getBicarbDoseVol( void ); + +F32 getAcidDoseVol( void ); +void setAcidDoseVol( F32 targetValue ); + +F32 getBicarbKpGainCoefficient( void ); +F32 getBicarbKiGainCoefficient( void ); + +F32 getAcidKpGainCoefficient( void ); +F32 getAcidKiGainCoefficient( void ); + DRY_BICART_FILL_EXEC_STATE_T getCurrentDryBiCartFillExecState( void ); BOOL testDryBiCartDataPublishIntervalOverride( MESSAGE_T *message ); @@ -70,6 +108,21 @@ BOOL testDryBiCartDrainRequestOverride( MESSAGE_T *message ); BOOL testDryBiCartTypeOverride( MESSAGE_T *message ); +BOOL testDryBiCartAcidDoseVolumeOverride( MESSAGE_T *message ); +BOOL testDryBiCartBicarbDoseVolumeOverride( MESSAGE_T *message ); + +BOOL testDryBiCartBicarbDoseVolControlKpGainOverride( MESSAGE_T *message ); +BOOL testDryBiCartBicarbDoseVolControlKiGainOverride( MESSAGE_T *message ); + +BOOL testDryBiCartAcidDoseVolControlKpGainOverride( MESSAGE_T *message ); +BOOL testDryBiCartAcidDoseVolControlKiGainOverride( MESSAGE_T *message ); + +BOOL testDryBiCartTargetConductivityOverride( MESSAGE_T *message ); +BOOL testDryBiCartDeltaConductivityOverride( MESSAGE_T *message ); + +BOOL testDryBiCartAcidBicarbDeltaConductivityOverride( MESSAGE_T *message ); +BOOL testDryBiCartAcidBicarbTargetConductivityOverride( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/App/Monitors/Conductivity.c =================================================================== diff -u -r46a42611591cb92eef5f20c8d39964d406c5c8cc -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision 46a42611591cb92eef5f20c8d39964d406c5c8cc) +++ firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -33,19 +33,20 @@ // ********** private definitions ********** #define COND_SENSOR_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. +#define COND_SENSOR_UPDATE_INTERVAL ( 700 / TASK_PRIORITY_INTERVAL ) ///< Time in task intervals for new sensor data #define DATA_PUBLISH_COUNTER_START_COUNT 40 ///< Data publish counter start count. -#define CONDUCTIVITY_SAMPLE_FILTER_MS ( 500 ) ///< Filter conductivity data for given time -#define CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS ( 500 ) ///< Filter conductivity temperature data for given time -#define SIZE_OF_FLOW_ROLLING_AVG ( CONDUCTIVITY_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity moving average sample count. -#define SIZE_OF_FLOW_TEMP_ROLLING_AVG ( CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity temprature moving average sample count. +#define CONDUCTIVITY_SAMPLE_FILTER_MS ( 30 ) ///< Filter conductivity data for given time +#define CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS ( 30 ) ///< Filter conductivity temperature data for given time +#define SIZE_OF_COND_ROLLING_AVG ( CONDUCTIVITY_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity moving average sample count. +#define SIZE_OF_COND_TEMP_ROLLING_AVG ( CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity temprature moving average sample count. #define RO_RR_MOVING_AVG_NUM_OF_SAMPLES 30 ///< RO rejection ratio moving average number of samples. #define FRACTION_TO_PERCENT_CONVERSION_FACTOR 100.0F ///< RO rejection ratio factor to percentage conversion factor value #define RO_RR_SAMPLE_COLLECTION_INTERVAL 10 ///< Collect RO rejection ratio sample for every 10th time in priority task /// Filter conductivity readings record. typedef struct { - F32 conductivityReadings[ SIZE_OF_FLOW_ROLLING_AVG ]; ///< Holds conductivity sample rolling average. + F32 conductivityReadings[ SIZE_OF_COND_ROLLING_AVG ]; ///< Holds conductivity sample rolling average. U32 conductivityReadingsIdx; ///< Index for next sample in rolling average array. F32 conductivityReadingsTotal; ///< Rolling total - used to calc average. U32 conductivityReadingsCount; ///< Number of samples in rolling average buffer @@ -54,7 +55,7 @@ /// Filter conductivity sensor temperature readings record. typedef struct { - F32 conductivityTempReadings[ SIZE_OF_FLOW_ROLLING_AVG ]; ///< Holds conductivity sample rolling average. + F32 conductivityTempReadings[ SIZE_OF_COND_TEMP_ROLLING_AVG ]; ///< Holds conductivity sample rolling average. U32 conductivityTempReadingsIdx; ///< Index for next sample in rolling average array. F32 conductivityTempReadingsTotal; ///< Rolling total - used to calc average. U32 conductivityTempReadingsCount; ///< Number of samples in rolling average buffer @@ -81,6 +82,10 @@ static U32 roRRCount; ///< RO rejection ratio Number of samples in average buffer. static F32 roRRTankFillAvg; ///< Average RO rejection ratio during permeate tank fill state. static U32 roRRSampleIntervalCounter; ///< RO rejection ratio sample collection timer counter. +static U32 condtempDataCollectionTimeInterval; ///< Conductivity Temperature data collection time interval in task counts. +static U32 condtempSampleIntervalCounter; ///< Conductivity Temperature sensor sample collection timer counter. +static U32 condDataCollectionTimeInterval; ///< Conductivity data collection time interval in task counts. +static U32 condSampleIntervalCounter; ///< Conductivity sensor sample collection timer counter. // ********** private function prototypes ********** @@ -122,6 +127,8 @@ roRRAvg.ovInitData = 0.0F; roRRAvg.override = OVERRIDE_RESET; roRRSampleIntervalCounter = 0; + condtempDataCollectionTimeInterval= COND_SENSOR_UPDATE_INTERVAL; + condtempSampleIntervalCounter = 0; memset( &roRRSamples, 0, sizeof( roRRSamples ) ); @@ -329,7 +336,6 @@ for ( sensor = FIRST_DD_COND_SENSOR; sensor < NUM_OF_CONDUCTIVITY_SENSORS; sensor++ ) { - #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ if (sensor != D74_COND ) { @@ -342,6 +348,7 @@ #else rawTemp = getConductivityTemperatureValue( sensor ); #endif + // TODO - calibrate if ( filteredConductivityTemperatureReadings[sensor].conductivityTempReadingsCount >= SIZE_OF_FLOW_ROLLING_AVG ) @@ -488,8 +495,10 @@ data.d17Cond = getFilteredConductivity( D17_COND ); data.d27Cond = getFilteredConductivity( D27_COND ); - data.d29Cond = getFilteredConductivity( D29_COND ); - data.d43Cond = getFilteredConductivity( D43_COND ); + data.d29Cond = getConductivity( D17_COND ); + data.d43Cond = getConductivity( D27_COND ); + // data.d29Cond = getFilteredConductivity( D29_COND ); + // data.d43Cond = getFilteredConductivity( D43_COND ); data.d74Cond = getFilteredConductivity( D74_COND ); ddConductivityPublishTimerCounter = 0; Index: firmware/App/Monitors/Level.c =================================================================== diff -u -r046bc2b62cf942b7e846fa5bff698b94238edf24 -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Monitors/Level.c (.../Level.c) (revision 046bc2b62cf942b7e846fa5bff698b94238edf24) +++ firmware/App/Monitors/Level.c (.../Level.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -136,7 +136,7 @@ case D63_LEVL: if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) ) { - currentLevelStatus = ( LEVEL_SENSOR_VALUE_LOW == getFPGAD63LevelSensor() ) ? LEVEL_STATE_LOW : LEVEL_STATE_HIGH; + currentLevelStatus = ( LEVEL_SENSOR_VALUE_LOW == getFPGAD63LevelSensor() ) ? LEVEL_STATE_HIGH : LEVEL_STATE_LOW; } else { @@ -147,7 +147,7 @@ case D98_LEVL: if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) ) { - currentLevelStatus = ( LEVEL_SENSOR_VALUE_LOW == getFPGAD98LevelSensor() ) ? LEVEL_STATE_LOW : LEVEL_STATE_HIGH; + currentLevelStatus = ( LEVEL_SENSOR_VALUE_LOW == getFPGAD98LevelSensor() ) ? LEVEL_STATE_HIGH : LEVEL_STATE_LOW; } else { @@ -468,9 +468,10 @@ LEVEL_STATE_T getBicarbChamberLevelStatus( void ) { LEVEL_STATE_T status = LEVEL_STATE_ILLEGAL; - LEVEL_STATE_T upperlevel = getLevelStatus( D63_LEVL ); - LEVEL_STATE_T lowerlevel = getLevelStatus( D98_LEVL ); + LEVEL_STATE_T upperlevel = getLevelStatus( D98_LEVL ); + LEVEL_STATE_T lowerlevel = getLevelStatus( D63_LEVL ); + if ( ( lowerlevel == LEVEL_STATE_LOW ) && ( upperlevel == LEVEL_STATE_LOW ) ) { status = LEVEL_STATE_LOW; Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r046bc2b62cf942b7e846fa5bff698b94238edf24 -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 046bc2b62cf942b7e846fa5bff698b94238edf24) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -153,6 +153,8 @@ SW_FAULT_ID_BICARB_CHAMBER_FILL_INVALID_EXEC_STATE = 122, SW_FAULT_ID_DRY_BICART_DRAIN_INVALID_EXEC_STATE = 123, SW_FAULT_ID_INVALID_RINSE_PUMP = 124, + SW_FAULT_ID_PI_CTRL_INVALID_FEED_FORWARD_LIMIT = 125, + SW_FAULT_ID_DIALYSATE_DOSE_EXEC_INVALID_STATE = 126, NUM_OF_SW_FAULT_IDS } DD_SW_FAULT_ID_T; Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -rb2e7c9194acd84783d2bbad64c5720410493e199 -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision b2e7c9194acd84783d2bbad64c5720410493e199) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -3092,7 +3092,7 @@ #if 1 // Remove when Beta 1.9 is obsolete if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) == TRUE ) { - result = ( fpgaSensorReadings.fpgaConductiveLevelStatus & FPGA_D63_LEVEL_BIT ); + result = ( fpgaSensorReadings.fpgaConductiveLevelStatus & FPGA_D63_LEVEL_BIT ) >> 1; } else { @@ -3120,7 +3120,7 @@ #if 1 // Remove when Beta 1.9 is obsolete if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) == TRUE ) { - result = ( fpgaSensorReadings.fpgaConductiveLevelStatus & FPGA_D98_LEVEL_BIT ); + result = ( fpgaSensorReadings.fpgaConductiveLevelStatus & FPGA_D98_LEVEL_BIT ) >> 2; } else { Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rd0a2037b16f76e661dc02296e039f099ce5d9ea8 -rd5c94536929ded738e5c8d139d8c46b1d3e035ef --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision d0a2037b16f76e661dc02296e039f099ce5d9ea8) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision d5c94536929ded738e5c8d139d8c46b1d3e035ef) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Michael Garthwaite -* @date (last) 10-Feb-2026 +* @author (last) Sameer Kalliadan Poyil +* @date (last) 06-Mar-2026 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 @@ -260,6 +260,12 @@ { MSG_ID_DD_RINSE_PUMP_PWM_PERCENT_OVERRIDE_REQUEST, &testRinsePumpPWMPercentOverride }, { MSG_ID_DD_RINSE_PUMP_TURN_ON_OFF_REQUEST, &testRinsePumpTurnOnOffRequest }, { MSG_ID_FP_SET_START_STOP_OVERRIDE_REQUEST, &testSetGeneratePermeateSignal }, + { MSG_ID_DD_DRY_BICART_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testDryBiCartDataPublishIntervalOverride }, + { MSG_ID_DD_DRY_BICART_FILL_CYCLE_MAX_OVERRIDE_REQUEST, &testDryBiCartFillCycleMaxCountOverride }, + { MSG_ID_DD_DRY_BICART_FILL_REQUEST_OVERRIDE_REQUEST, &testDryBiCartFillRequestOverride }, + { MSG_ID_DD_BICARB_CHAMBER_FILL_REQUEST_OVERRIDE_REQUEST, &testBiCarbChamberFillRequestOverride }, + { MSG_ID_DD_BICART_DRAIN_REQUEST_OVERRIDE_REQUEST, &testDryBiCartDrainRequestOverride }, + { MSG_ID_DD_BICART_CARTRIDGE_SELECT_OVERRIDE_REQUEST, &testDryBiCartTypeOverride }, { MSG_ID_FP_RO_REJECTION_RATIO_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRORejectionRatioDataPublishIntervalOverride }, { MSG_ID_FP_RO_FILTERED_REJECTION_RATIO_OVERRIDE_REQUEST, &testRORejectionRatioFilteredOverride }, { MSG_ID_FP_SET_TEST_CONFIGURATION, &testSetTestConfiguration }, @@ -278,16 +284,9 @@ { MSG_ID_FP_DEF_PRE_GEN_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testPreGenPermeateDefDataPublishIntervalOverride}, { MSG_ID_FP_DEF_GEN_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testGenPermeateDefDataPublishIntervalOverride}, { MSG_ID_FP_DEF_STATUS_REQUEST, &testGetFPDefeaturedStatus }, - { MSG_ID_DD_DRY_BICART_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testDryBiCartDataPublishIntervalOverride }, - { MSG_ID_DD_DRY_BICART_FILL_CYCLE_MAX_OVERRIDE_REQUEST, &testDryBiCartFillCycleMaxCountOverride }, - { MSG_ID_DD_DRY_BICART_FILL_REQUEST_OVERRIDE_REQUEST, &testDryBiCartFillRequestOverride }, - { MSG_ID_FP_RO_FILTERED_REJECTION_RATIO_OVERRIDE_REQUEST, &testRORejectionRatioFilteredOverride }, - { MSG_ID_DD_BICART_DRAIN_REQUEST_OVERRIDE_REQUEST, &testDryBiCartDrainRequestOverride }, - { MSG_ID_DD_BICART_CARTRIDGE_SELECT_OVERRIDE_REQUEST, &testDryBiCartTypeOverride }, { MSG_ID_DD_BICARB_DOSE_VOL_CONTROL_KP_GAIN_COEFF_OVERRIDE_REQUEST, &testDryBiCartBicarbDoseVolControlKpGainOverride }, { MSG_ID_DD_BICARB_DOSE_VOL_CONTROL_KI_GAIN_COEFF_OVERRIDE_REQUEST, &testDryBiCartBicarbDoseVolControlKiGainOverride }, - { MSG_ID_DD_ACID_DOSE_VOL_CONTROL_KP_GAIN_COEFF_OVERRIDE_REQUEST, &testDryBiCartAcidDoseVolControlKpGainOverride }, { MSG_ID_DD_ACID_DOSE_VOL_CONTROL_KI_GAIN_COEFF_OVERRIDE_REQUEST, &testDryBiCartAcidDoseVolControlKiGainOverride }, };