Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r85bfe5051e4d2bf67be39d394f96c075b4e52836 -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 85bfe5051e4d2bf67be39d394f96c075b4e52836) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -26,6 +26,7 @@ #include "FPGA.h" #include "InternalADC.h" #include "OperationModes.h" +#include "PIControllers.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -118,8 +119,6 @@ DATA_DECL( F32, MeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor controller speed DATA_DECL( F32, MeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA, 0.0, 0.0 );// measured dialIn pump motor controller current -static F32 dipFlowError = 0.0; // dialIn flow error -static F32 dipFlowErrorSum = 0.0; // dialIn flow error sum static U32 dipControlTimerCounter = 0; // determines when to perform control on dialIn flow static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; // holds flow samples for a rolling average @@ -165,6 +164,12 @@ // zero rolling flow average buffer resetDialInFlowMovingAverage(); + + // initialize dialysate inlet flow PI controller + initializePIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, + DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, + MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE, + DIP_MIN_ERROR_SUM, DIP_MAX_ERROR_SUM ); } /************************************************************************* @@ -193,9 +198,6 @@ dialInPumpDirection = dir; // set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we'll control to flow when ramp completed dialInPumpPWMDutyCyclePct = DIP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - // reset flow control stats - dipFlowError = 0.0; - dipFlowErrorSum = 0.0; switch ( dialInPumpState ) { @@ -251,9 +253,8 @@ stopDialInPump(); dialInPumpState = DIAL_IN_PUMP_OFF_STATE; dialInPumpPWMDutyCyclePct = 0.0; - dipFlowError = 0.0; - dipFlowErrorSum = 0.0; dipControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); } /************************************************************************* @@ -380,6 +381,7 @@ else if ( dialInPumpPWMDutyCyclePctSet >= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp up @@ -416,6 +418,7 @@ else if ( dialInPumpPWMDutyCyclePctSet <= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp down @@ -443,30 +446,12 @@ DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; F32 tgtFlow = (F32)getTargetDialInFlowRate(); F32 actFlow = getMeasuredDialInFlowRate(); - F32 pTerm, iTerm; F32 newPWM; // control at set interval if ( ++dipControlTimerCounter >= DIP_CONTROL_INTERVAL ) { - // compute P term - if ( MOTOR_DIR_FORWARD == dialInPumpDirectionSet ) - { - dipFlowError = tgtFlow - actFlow; - } - else - { - dipFlowError = (tgtFlow * -1.0) - (actFlow * -1.0); - } - pTerm = dipFlowError * DIP_P_COEFFICIENT; - pTerm = RANGE( pTerm, DIP_MIN_PWM_DC_DELTA, DIP_MAX_PWM_DC_DELTA ); - // compute I term - dipFlowErrorSum += dipFlowError; - iTerm = RANGE( dipFlowErrorSum, DIP_MIN_ERROR_SUM, DIP_MAX_ERROR_SUM ); - iTerm *= DIP_I_COEFFICIENT; - // compute new PWM duty cycle % for dialIn pump motor - newPWM = dialInPumpPWMDutyCyclePctSet + pTerm + iTerm; - newPWM = RANGE( newPWM, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); dialInPumpPWMDutyCyclePctSet = newPWM; etpwmSetCmpA( etpwmREG1, (U32)FLOAT_TO_INT_WITH_ROUND( dialInPumpPWMDutyCyclePctSet * (F32)(etpwmREG1->TBPRD) ) ); dipControlTimerCounter = 0;