Index: firmware/App/Controllers/MixingControl.c =================================================================== diff -u -r145fd716a856f864f39fb0f9884865f6e45b9256 -r313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59 --- firmware/App/Controllers/MixingControl.c (.../MixingControl.c) (revision 145fd716a856f864f39fb0f9884865f6e45b9256) +++ firmware/App/Controllers/MixingControl.c (.../MixingControl.c) (revision 313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59) @@ -69,8 +69,8 @@ #define MIX_NO_FEED_FORWARD 0.0F ///< Feed forward term for dialysate closed loop control -#define BICARB_MIX_CONTROL_INTERVAL ( 15 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the bicarb mix is controlled. -#define ACID_MIX_CONTROL_INTERVAL ( 9 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate mix is controlled. +#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_DEADBAND_CONTROL 15.0F ///< Bicarb dead band control #define ACID_DEADBAND_CONTROL 50.0F ///< Acid dead band control @@ -201,6 +201,7 @@ static void setBicarbMixVol( F32 targetValue ); static void setAcidMixVol( F32 targetValue ); +static void updatedConcentrateControlInterval( void ); static F32 getBicarbDeltaConductivity( void ); static F32 getBicarbTargetConductivity( void ); @@ -257,6 +258,9 @@ mixingControlBicarbVolume.ovInitData = 0.0F; mixingControlBicarbVolume.override = OVERRIDE_RESET; + lastAcidMixVolume = DEFAULT_ACID_VOLUME_ML; + lastBicarbMixVolume = DEFAULT_BICARB_VOLUME_ML; + mixingControlAcidVolumeKpGain.data = ACID_VOL_CONTROL_P_COEFFICIENT; mixingControlAcidVolumeKpGain.ovData = ACID_VOL_CONTROL_P_COEFFICIENT; mixingControlAcidVolumeKpGain.ovInitData = 0.0F; @@ -351,6 +355,8 @@ { if( getCurrentBalancingChamberExecState() > BAL_CHAMBER_STATE_IDLE ) { + updatedConcentrateControlInterval(); + // closed loop bicarb and acid mixing controller handleDialysateCompositionMixing(); } @@ -417,6 +423,32 @@ /*********************************************************************//** * @brief + * The updatedConcentrateControlInterval function sets bicarb Mix volume provided by the controller + * @details \b Inputs: none + * @details \b Outputs: mixingControlBicarbMixVolume + * @param targetValue bicarb Mix volume + * @return TRUE if successful, FALSE if not. + *************************************************************************/ +static void updatedConcentrateControlInterval( void ) +{ + F32 tdDialysateFlowRate = 0.0F; + F32 balChamberSwitchingFreq = 0.0F; + U32 balChamberSwitchingPeriod = 0; + + tdDialysateFlowRate = getTDDialysateFlowrate(); + + balChamberSwitchingFreq = tdDialysateFlowRate / 30.0; + balChamberSwitchingPeriod = ( SEC_PER_MIN ) / (U32)balChamberSwitchingFreq; + + if ( balChamberSwitchingPeriod > 0) + { + mixingControlAcidControlInterval.data = ACID_MIX_CONTROL_INTERVAL * balChamberSwitchingPeriod; + mixingControlBicarbControlInterval.data = BICARB_MIX_CONTROL_INTERVAL * balChamberSwitchingPeriod; + } +} + +/*********************************************************************//** + * @brief * The getBicarbDeltaConductivity function gets the delta target conductivity * @details \b Inputs: mixingControlBicarbDeltaConductivity * @details \b Outputs: none Index: firmware/App/Controllers/MixingControl.h =================================================================== diff -u -r145fd716a856f864f39fb0f9884865f6e45b9256 -r313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59 --- firmware/App/Controllers/MixingControl.h (.../MixingControl.h) (revision 145fd716a856f864f39fb0f9884865f6e45b9256) +++ firmware/App/Controllers/MixingControl.h (.../MixingControl.h) (revision 313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59) @@ -61,15 +61,16 @@ // ********** public function prototypes ********** +void initMixingControl( void ); void execMixingControl( void ); F32 getBicarbMixVol( void ); F32 getAcidMixVol( void ); BOOL testMixingControlDataPublishIntervalOverride( MESSAGE_T *message ); -BOOL testMixingControlAcidVolumeOverride( MESSAGE_T *message ); -BOOL testMixingControlBicarbVolumeOverride( MESSAGE_T *message ); +BOOL testMixingControlAcidMixVolumeOverride( MESSAGE_T *message ); +BOOL testMixingControlBicarbMixVolumeOverride( MESSAGE_T *message ); BOOL testMixingControlBicarbVolControlKpGainOverride( MESSAGE_T *message ); BOOL testMixingControlBicarbVolControlKiGainOverride( MESSAGE_T *message ); Index: firmware/App/Monitors/Conductivity.c =================================================================== diff -u -r145fd716a856f864f39fb0f9884865f6e45b9256 -r313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59 --- firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision 145fd716a856f864f39fb0f9884865f6e45b9256) +++ firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision 313fa2d93236d6aa9de1a7e8e65c8c908e6b0c59) @@ -17,12 +17,14 @@ #include // Used for calculating the polynomial calibration equation. #include // For memcpy +#include "BalancingChamber.h" #include "Conductivity.h" #include "MessageSupport.h" #include "Messaging.h" #include "ModeGenPermeate.h" #include "OperationModes.h" #include "TaskPriority.h" +#include "TDInterface.h" #include "Utilities.h" /** @@ -38,7 +40,7 @@ #define FP_CONDUCTIVITY_DATA_PUBLISH_COUNTER_START_COUNT 41 ///< FP Conductivity data publish counter start count. #define RO_DATA_PUBLISH_COUNTER_START_COUNT 42 ///< FP RO Data publish counter start count. #define RESISTANCE_DATA_PUBLISH_COUNTER_START_COUNT 43 ///< DD Resistance data publish counter start count. -#define CONDUCTIVITY_SAMPLE_FILTER_MS ( 210 ) ///< Filter conductivity data for given time. Currently set to have 5 samples over 3.5s ( 700ms sample rate ) +#define CONDUCTIVITY_SAMPLE_FILTER_MS ( 70 ) ///< Filter conductivity data for given time. Currently set to have 5 samples over 3.5s ( 700ms sample rate ) #define CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS ( 30 ) ///< Filter conductivity temperature data for given time. Currently set to have 5 samples over 3.5s ( 700ms sample rate ) #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. @@ -88,6 +90,7 @@ static F32 roRRTankFillAvg; ///< Average RO rejection ratio during permeate tank fill state. static U32 roRRSampleIntervalCounter; ///< RO rejection ratio sample collection timer counter. static U32 conductivityResistancePublishTimerCounter; ///< DD and FP Conductivity data publication counter. +static U32 conductivityFilterSize; ///< Active conductivity filter sample count. static OVERRIDE_U32_T conductivityResistanceDataPublishInterval; ///< DD and FP Conductivity sensors publish time interval override. // ********** private function prototypes ********** @@ -99,6 +102,8 @@ static void calcRORejectionRatio( void ); static void filterRORejectionRatioReadings( void ); static void broadcastResistanceData( void ); +static U32 getConductivityFilterSize( void ); +static void resetConductivityFilterReadings( void ); /*********************************************************************//** * @brief @@ -259,8 +264,15 @@ { CONDUCTIVITY_SENSORS_T sensor; F32 calculatedConductivity = 0.0F; + U32 activeFilterSize = getConductivityFilterSize(); BOOL freshData = FALSE; + if ( conductivityFilterSize != activeFilterSize ) + { + conductivityFilterSize = activeFilterSize; + resetConductivityFilterReadings(); + } + for ( sensor = FIRST_DD_COND_SENSOR; sensor < NUM_OF_CONDUCTIVITY_SENSORS; sensor++ ) { if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_9_HW ) == TRUE ) @@ -292,21 +304,81 @@ { freshData = FALSE; // TODO - calibrate - if ( filteredConductivityReadings[ sensor ].conductivityReadingsCount >= SIZE_OF_COND_ROLLING_AVG ) + if ( filteredConductivityReadings[ sensor ].conductivityReadingsCount >= conductivityFilterSize ) { filteredConductivityReadings[ sensor ].conductivityReadingsTotal -= filteredConductivityReadings[ sensor ].conductivityReadings[ filteredConductivityReadings[ sensor ].conductivityReadingsIdx ]; } filteredConductivityReadings[ sensor ].conductivityReadings[ filteredConductivityReadings[ sensor ].conductivityReadingsIdx ] = calculatedConductivity; filteredConductivityReadings[ sensor ].conductivityReadingsTotal += calculatedConductivity; - filteredConductivityReadings[ sensor ].conductivityReadingsIdx = INC_WRAP( filteredConductivityReadings[ sensor ].conductivityReadingsIdx, 0, SIZE_OF_COND_ROLLING_AVG - 1 ); - filteredConductivityReadings[ sensor ].conductivityReadingsCount = INC_CAP( filteredConductivityReadings[ sensor ].conductivityReadingsCount, SIZE_OF_COND_ROLLING_AVG ); + filteredConductivityReadings[ sensor ].conductivityReadingsIdx = INC_WRAP( filteredConductivityReadings[ sensor ].conductivityReadingsIdx, 0, conductivityFilterSize - 1 ); + filteredConductivityReadings[ sensor ].conductivityReadingsCount = INC_CAP( filteredConductivityReadings[ sensor ].conductivityReadingsCount, conductivityFilterSize ); filteredcurrentConductivityReadings[ sensor ].data = filteredConductivityReadings[ sensor ].conductivityReadingsTotal / (F32)filteredConductivityReadings[ sensor ].conductivityReadingsCount; } } } /*********************************************************************//** * @brief + * The getConductivityFilterSize function gets the active conductivity filter + * sample count based on the Qd balancing chamber switching period. + * @details \b Inputs: TD dialysate flow rate + * @details \b Outputs: none + * @return active conductivity filter sample count. + *************************************************************************/ +static U32 getConductivityFilterSize( void ) +{ + F32 tdDialysateFlowRate = getTDDialysateFlowrate(); + U32 result = SIZE_OF_COND_ROLLING_AVG; + + if ( tdDialysateFlowRate > NEARLY_ZERO ) + { + F32 balChamberSwitchingFreq = tdDialysateFlowRate / BAL_CHAMBER_FILL_VOLUME_ML; + F32 balChamberSwitchingPeriod = (F32)SEC_PER_MIN / balChamberSwitchingFreq; + + result = (U32)( (F32)SIZE_OF_COND_ROLLING_AVG * balChamberSwitchingPeriod ); + } + + if ( result < 1 ) + { + result = 1; + } + else if ( result > SIZE_OF_COND_ROLLING_AVG ) + { + result = SIZE_OF_COND_ROLLING_AVG; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The resetConductivityFilterReadings function clears conductivity rolling + * average data when the active filter window changes. + * @details \b Inputs: none + * @details \b Outputs: filteredConductivityReadings + * @return none + *************************************************************************/ +static void resetConductivityFilterReadings( void ) +{ + CONDUCTIVITY_SENSORS_T sensor; + + for ( sensor = FIRST_DD_COND_SENSOR; sensor < NUM_OF_CONDUCTIVITY_SENSORS; sensor++ ) + { + U32 readingIndex; + + for ( readingIndex = 0; readingIndex < SIZE_OF_COND_ROLLING_AVG; readingIndex++ ) + { + filteredConductivityReadings[ sensor ].conductivityReadings[ readingIndex ] = 0.0F; + } + + filteredConductivityReadings[ sensor ].conductivityReadingsIdx = 0; + filteredConductivityReadings[ sensor ].conductivityReadingsTotal = 0.0F; + filteredConductivityReadings[ sensor ].conductivityReadingsCount = 0; + } +} + +/*********************************************************************//** + * @brief * The getFilteredConductivitySensorTemperature function gets the filtered * temperature (in C) for a given conductivity sensor. * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT if given sensor is invalid.