Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r987e90fb9a14be603c7ccf4a7595a9dfd21e87a4 -r3e6a23f30e6a48db1aa6490388cc2179236888c0 --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 987e90fb9a14be603c7ccf4a7595a9dfd21e87a4) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 3e6a23f30e6a48db1aa6490388cc2179236888c0) @@ -70,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 stabilized due to fill complete. +static BOOL isPressureStabilizedDuringFill; ///< Flag indicating that the pressure is stablized 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. @@ -84,12 +84,17 @@ static F32 lastTdDialysateFlowrate; ///< Previous TD dialysate flow rate static F32 freshDialPressure; ///< Fresh side dialysate pressure static F32 spentDialPressure; ///< Spent side dialysate pressure +static BOOL isBalChamberSwitchingActive; ///< Flag indicating balancing chamber switching is active or not. +static BOOL isBalChamberSwitchingOnRequested; ///< Flag indicating that a request was made to activate balancing chamber switching. +static BOOL isBalChamberSwitchingOffRequested; ///< Flag indicating that a request was made to deactivate balancing chamber switching. + +//TODO: remove later once level sensor working +static U32 bicarbChamberPeriodicFillCounter; ///< Counter for checking the timeout for drybicart chamber fill request. + static U32 currentBalChamberFillCounter; ///< Counter (in task interval) to monitor the timing spent for the spent side fill operation. 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; -//TODO: remove later once level sensor working -static U32 bicarbChamberPeriodicFillCounter; +static BOOL isSpentFillComplete; ///< Flag indicating spent side fill complete. // ********** private function prototypes ********** @@ -100,6 +105,7 @@ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillStart( void ); static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2ValvesClose( void ); static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillEnd(void); +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberStateIdle( void ); static void publishBalChamberData( void ); static U32 getBalChamberDataPublishInterval( void ); static void checkSpentFillComplete( F32 spentDialPressure ); @@ -113,7 +119,7 @@ *************************************************************************/ void initBalanceChamber( void ) { - balChamberExecState = BAL_CHAMBER_STATE_START; + balChamberExecState = BAL_CHAMBER_STATE_IDLE; balChamberSWState = BAL_CHAMBER_SW_STATE1; balChamberSwitchingFreq.data = 0.0F; balChamberSwitchingFreq.ovData = 0.0F; @@ -145,12 +151,17 @@ isPressureDroppedDuringFill = FALSE; freshDialPressure = 0.0F; spentDialPressure = 0.0F; + isBalChamberSwitchingActive = FALSE; + isBalChamberSwitchingOnRequested = FALSE; + isBalChamberSwitchingOffRequested = FALSE; + + //TODO:remove once level sensor working + bicarbChamberPeriodicFillCounter = 0; + currentBalChamberFillCounter = 0; balChamberFillTimeoutCount = 0; diffSpentFillCompleteCount = 0; isSpentFillComplete = FALSE; - //TODO:remove once level sensor working - bicarbChamberPeriodicFillCounter = 0; } /*********************************************************************//** @@ -239,10 +250,11 @@ } } + // execute current balancing chamber exec state switch ( balChamberExecState ) { - case BAL_CHAMBER_STATE_START: - balChamberExecState = BAL_CHAMBER_STATE1_FILL_START; + case BAL_CHAMBER_STATE_IDLE: + balChamberExecState = handleBalChamberStateIdle(); break; case BAL_CHAMBER_STATE1_FILL_START: @@ -279,7 +291,7 @@ default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BAL_CHAMBER_INVALID_EXEC_STATE, balChamberExecState ) - balChamberExecState = BAL_CHAMBER_STATE_START; + balChamberExecState = BAL_CHAMBER_STATE_IDLE; break; } @@ -291,6 +303,26 @@ /*********************************************************************//** * @brief + * The requestBalChamberSwitching function activates or deactivates balancing chamber switching. + * @details \b Inputs: none + * @details \b Outputs: isBalChamberSwitchingOnRequested, isBalChamberSwitchingOffRequested + * @param activate - TRUE to activate and FALSE to deactivate. + * @return none. + *************************************************************************/ +void requestBalChamberSwitching( BOOL activate ) +{ + if ( TRUE == activate ) + { + isBalChamberSwitchingOnRequested = TRUE; + } + else + { + isBalChamberSwitchingOffRequested = TRUE; + } +} + +/*********************************************************************//** + * @brief * The valveControlForBCState1FillStart function actuates the valve combination * for state 1 fill/drain process. * @details \b Inputs: none @@ -465,6 +497,17 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + } + else + { + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD99AverageTemperature() ); + } + // Check fresh dialysate pressure in range or BC switch only flag set or BC pressure alarms are disabled if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) @@ -659,6 +702,22 @@ state = BAL_CHAMBER_STATE2_FILL_START; } + // Keep Clearing the On request flag in case an On request was made while the switching is active + isBalChamberSwitchingOnRequested = FALSE; + + // Check if a request made was to deactivate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOffRequested ) + { + //Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOffRequested = FALSE; + + // Clear the flag to indicate that balancing chamber switching is inactive + isBalChamberSwitchingActive = FALSE; + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } + return state; } @@ -689,6 +748,17 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD4AverageTemperature() ); + } + else + { + //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp + setHeaterTargetTemperature( D45_HEAT, getD99AverageTemperature() ); + } + // Check fresh dialysate pressure in range if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) @@ -839,11 +909,57 @@ isFirstCycleBCSwitchingCompleted = TRUE; } + // Keep Clearing the On request flag in case an On request was made while the switching is active + isBalChamberSwitchingOnRequested = FALSE; + + // Check if a request made was to deactivate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOffRequested ) + { + // Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOffRequested = FALSE; + + // Clear flag to indicate that balancing chamber switching is inactive + isBalChamberSwitchingActive = FALSE; + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } + return state; } /*********************************************************************//** * @brief + * The handleBalChamberStateIdle function handles balancing chamber idle state. + * @details \b Inputs: isBalChamberSwitchingOnRequested + * @details \b Outputs: isBalChamberSwitchingActive + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberStateIdle( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE_IDLE; + + // Keep Clearing the off request flag in case an off request was made while we were already in the idle state + isBalChamberSwitchingOffRequested = FALSE; + + // Check if a request made was to activate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOnRequested ) + { + //Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOnRequested = FALSE; + + // Set flag to indicate that balancing chamber switching is active + isBalChamberSwitchingActive = TRUE; + + // Move to the start state1 + state = BAL_CHAMBER_STATE1_FILL_START; + } + + return state; +} + +/*********************************************************************//** + * @brief * The checkSpentFillComplete function checks the pressure difference for * spent side fill completion and adjusts the D48 pump speed to align the * fill timing close to the switching period time. @@ -1050,6 +1166,7 @@ data.currentBalChamberSwitchingCounter = currentBalChamberFillCounter; data.isPressureStabilizedDuringFill = isPressureStabilizedDuringFill; data.balChamberSWOnlyState = balanceChamberSwitchingOnly; + data.isBalChamberSwitchingActive = isBalChamberSwitchingActive; broadcastData( MSG_ID_DD_BAL_CHAMBER_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( BAL_CHAMBER_DATA_T ) ); @@ -1137,7 +1254,6 @@ * chamber switching only without dosing delivery and pressure check condition. * @details \b Inputs: tester logged in * @details \b Outputs: tdDialysateFlowrate,balanceChamberSwitchingOnly - * pendingBalanceChamberSwOnlyRequest * @param message set message from Dialin which includes the balancing chamber * to start/stop switching and update switching rate based on the flow rate. * @return TRUE if set request is successful, FALSE if not @@ -1146,7 +1262,7 @@ { BOOL result = FALSE; - // Verify tester has logged in with DD + // Verify tester has logged in with TD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u -r987e90fb9a14be603c7ccf4a7595a9dfd21e87a4 -r3e6a23f30e6a48db1aa6490388cc2179236888c0 --- firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 987e90fb9a14be603c7ccf4a7595a9dfd21e87a4) +++ firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 3e6a23f30e6a48db1aa6490388cc2179236888c0) @@ -7,8 +7,8 @@ * * @file ConcentratePumps.c * -* @author (last) Vinayakam Mani -* @date (last) 11-Feb-2026 +* @author (last) Sameer Kalliadan Poyil +* @date (last) 03-Feb-2026 * * @author (original) Vinayakam Mani * @date (original) 19-Sep-2024 @@ -36,12 +36,12 @@ #define CONCENTRATE_PUMP_REVERSE_DIR 0x0 ///< Concentrate pump reverse direction configuration. #define CONCENTRATE_PUMP_RAMP_SPEED_INCREMENT 10.0F ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. -#define CONCENTRATE_PUMP_MIN_SPEED 0.0F ///< Minimum speed for concentrate pump in mL per min. -#define CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_ON_PCT 0.0075F ///< Concentrate pump speed out of range tolerance when on in percentage. +#define CONCENTRATE_PUMP_MIN_SPEED 3.0F ///< Minimum speed for concentrate pump in mL per min. +#define CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_ON_PCT 0.01F ///< Concentrate pump speed out of range tolerance when on in percentage. #define CONCENTRATE_PUMP_CLEANING_SPD_OUT_OF_RANGE_TOL_PCT 0.05F ///< Concentrate pump cleaning mode speed out of range tolerance when on in percentage. #define CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_SLOW_MLPM 0.5F ///< Concentrate pump speed out of range tolerance when slow in mL/min. #define CONCENTRATE_PUMP_LOW_SPEED_THRESHOLD_MLPM 5.0F ///< Concentrate pump low speed threshold in mL/min. -#define CONCENTRATE_PUMP_ZERO_FLOW_RATE 0xFFFFFFFF ///< Pulse width value when zero flow rate or pump is off. +#define CONCENTRATE_PUMP_ZERO_FLOW_RATE 0xFFFFFFFF ///< Pulse width value when zero flow rate or pump is off #define CONCENTRATE_PUMP_VOLUME_PER_REV_DIENER 0.4F ///< Volume output every revolution (mL). #define CONCENTRATE_PUMP_VOLUME_PER_REV 0.1F ///< Volume output every revolution (mL). @@ -62,8 +62,7 @@ #define CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is monitored. #define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 100 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. -#define CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Concentrate pumps speed out of range timeout in milliseconds. -#define UF_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< UF pump speed out of range timeout in milliseconds. +#define CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Concentrate pumps speed out of range timeout in milliseconds. #define NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK 1 ///< Number of acid and bicarb non-volatile data to check. #define DATA_PUBLISH_COUNTER_START_COUNT 0 ///< Data publish counter start count. @@ -108,7 +107,7 @@ CONCENTRATE_PUMP_STATE_T execState; ///< Concentrate pump execute current state. BOOL hasTurnOnPumpsBeenRequested; ///< Flag indicates a request to turn concentrate pumps on. F32 currentPumpSpeed; ///< Current controlled concentrate pumps' speed (mL/min). - U32 togglePeriodCount; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). + U16 togglePeriodCount; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). U08 direction; ///< Concentrate pump motor direction. U08 controlSet; ///< Concentrate pump control set. (Used in DVT) F32 pulseWidthUS; ///< Concentrate pump pulse width in microseconds. @@ -223,7 +222,7 @@ initPersistentAlarm( ALARM_ID_DD_D11_PUMP_SPEED_CONTROL_ERROR, 0, CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DD_D10_PUMP_SPEED_CONTROL_ERROR, 0, CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_DD_D76_PUMP_SPEED_CONTROL_ERROR, 0, UF_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DD_D76_PUMP_SPEED_CONTROL_ERROR, 0, CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DD_CONC_PUMP_HALL_SENSOR_OUT_OF_RANGE, CONCENTRATE_PUMP_HALL_SENSORS_OUT_OF_RANGE_TIME_MS, CONCENTRATE_PUMP_HALL_SENSORS_OUT_OF_RANGE_TIME_MS ); initPersistentAlarm( ALARM_ID_DD_CONCENTRATE_PUMP_FAULT, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD ); } @@ -577,11 +576,22 @@ } /* - * If 0.0 <= speed <= 200 set it - * If speed < 0.0 set to 0 - * else speed > 200 set to 200 + * If 3.0 <= speed <= 60 set it + * If speed < 3.0 set to 0 + * else speed > 60 set to 60 */ - pumpTargetSpeed[ pumpId ].data = RANGE(targetSpeed_ml_min, CONCENTRATE_PUMP_MIN_SPEED, CONCENTRATE_PUMP_MAX_SPEED ); + if ( ( CONCENTRATE_PUMP_MIN_SPEED <= targetSpeed_ml_min ) && ( targetSpeed_ml_min <= CONCENTRATE_PUMP_MAX_SPEED ) ) + { + pumpTargetSpeed[ pumpId ].data = targetSpeed_ml_min; + } + else if ( targetSpeed_ml_min < CONCENTRATE_PUMP_MIN_SPEED ) + { + pumpTargetSpeed[ pumpId ].data = 0.0; + } + else + { + pumpTargetSpeed[ pumpId ].data = DOSING_CONCENTRATE_PUMP_SPEED; + } } else { @@ -734,13 +744,13 @@ * @param pumpId concentrate pump id to get target revolution count * @return the target revolution count for the given concentrate pump *************************************************************************/ -U16 getConcPumpTargetRevolutionCount( CONCENTRATE_PUMPS_T pumpId ) +U32 getConcPumpTargetRevolutionCount( CONCENTRATE_PUMPS_T pumpId ) { - U16 result = 0; + U32 result = 0; if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) { - result = (U16)getU32OverrideValue( &pumpTargetRevCnt[ pumpId ] ); + result = getU32OverrideValue( &pumpTargetRevCnt[ pumpId ] ); } else { @@ -760,13 +770,13 @@ * @param pumpId concentrate pump id to get current measured revolution count * @return the current revolution count for the given concentrate pump *************************************************************************/ -U16 getConcPumpCurrentMeasuredRevolutionCount( CONCENTRATE_PUMPS_T pumpId ) +U32 getConcPumpCurrentMeasuredRevolutionCount( CONCENTRATE_PUMPS_T pumpId ) { - BOOL result = FALSE; + U32 result = 0; if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) { - result = (U16)getU32OverrideValue( &pumpMesauredRevCnt[ pumpId ] ); + result = getU32OverrideValue( &pumpMesauredRevCnt[ pumpId ] ); } else { @@ -862,7 +872,7 @@ { setFPGAD76PumpSetStepSpeed( CONCENTRATE_PUMP_ZERO_FLOW_RATE ); } - +#if 0 // Park concentrate pump too if requested if ( TRUE == parkPump ) { @@ -883,6 +893,7 @@ } concentratePumps[ pumpId ].isConcPumpParkInProgress = TRUE; } +#endif } /*********************************************************************//** @@ -1047,7 +1058,7 @@ timePerStep = CONCENTRATE_PUMP_VOLUME_PER_REV_DIENER / ( concentratePumps[ pumpId ].currentPumpSpeed * CONCENTRATE_PUMP_STEP_PER_REV ); stepPeriodCounts = timePerStep / ( CONCENTRATE_PUMP_STEP_PERIOD_RESOLUTION * CONCENTRATE_PUMP_MICRO_STEPS_PER_STEP ); - concentratePumps[ pumpId ].togglePeriodCount = (U32)( stepPeriodCounts + FLOAT_TO_INT_ROUNDUP_OFFSET ); + concentratePumps[ pumpId ].togglePeriodCount = (U16)( stepPeriodCounts + FLOAT_TO_INT_ROUNDUP_OFFSET ); } else { @@ -1087,7 +1098,7 @@ static void calcMeasuredPumpsSpeed( void ) { CONCENTRATE_PUMPS_T pumpId; - U32 pulseWidthCount = 0; + U16 pulseWidthCount = 0; F32 pulseWidthInMicroSeconds = 0.0F; BOOL isPulseWidthOut = FALSE; CONCENTRATE_PUMPS_T pumpInAlarm = CONCENTRATEPUMPS_FIRST; @@ -1255,10 +1266,10 @@ data.d10_PumpCurrentSetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == d10_PumpDirection ? d10_PumpSetSpeed * -1.0F : d10_PumpSetSpeed ); data.d10_PumpMeasuredSpeed = getMeasuredPumpSpeedMLPM( D10_PUMP ); data.d10_PumpTargetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == d10_PumpDirection ? d10_PumpTgtSpeed * -1.0F : d10_PumpTgtSpeed ); - data.d11_PumpTargetRevCount = (U32)getConcPumpTargetRevolutionCount( D11_PUMP ); - data.d11_PumpMeasuredRevCount= (U32)getConcPumpCurrentMeasuredRevolutionCount( D11_PUMP ); - data.d10_PumpTargetRevCount = (U32)getConcPumpTargetRevolutionCount( D10_PUMP ); - data.d10_PumpMeasuredRevCount= (U32)getConcPumpCurrentMeasuredRevolutionCount( D10_PUMP ); + data.d11_PumpTargetRevCount = getConcPumpTargetRevolutionCount( D11_PUMP ); + data.d11_PumpMeasuredRevCount= getConcPumpCurrentMeasuredRevolutionCount( D11_PUMP ); + data.d10_PumpTargetRevCount = getConcPumpTargetRevolutionCount( D10_PUMP ); + data.d10_PumpMeasuredRevCount= getConcPumpCurrentMeasuredRevolutionCount( D10_PUMP ); data.d11_PumpState = concentratePumps[ D11_PUMP ].execState; data.d10_PumpState = concentratePumps[ D10_PUMP ].execState; data.d11_PumpPulseUS = concentratePumps[ D11_PUMP ].pulseWidthUS; @@ -1402,7 +1413,6 @@ BOOL testConcentratePumpStartStopOverride( MESSAGE_T *message ) { BOOL result = FALSE; - BOOL speedRangeCheck = FALSE; // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) @@ -1416,10 +1426,10 @@ if ( (CONCENTRATE_PUMPS_T)payload.pumpID < NUM_OF_CONCENTRATE_PUMPS ) { - speedRangeCheck = ( ( payload.speed >= CONCENTRATE_PUMP_MIN_SPEED ) && ( payload.speed <= CONCENTRATE_PUMP_MAX_SPEED )? TRUE : FALSE ); - // Handle start command - if ( ( TRUE == payload.startStop ) && ( TRUE == speedRangeCheck ) && ( payload.volume > 0.0 ) ) + if ( ( TRUE == payload.startStop ) && + ( ( payload.speed >= CONCENTRATE_PUMP_MIN_SPEED ) && ( payload.speed <= DOSING_CONCENTRATE_PUMP_SPEED ) ) && + ( payload.volume > 0.0 ) ) { setConcentratePumpTargetSpeed( (CONCENTRATE_PUMPS_T)payload.pumpID, payload.speed, payload.volume ); requestConcentratePumpOn ( (CONCENTRATE_PUMPS_T)payload.pumpID );