Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1 -rea6ff77291eee02f351953b76c6720cf860c8be7 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 6311eb9b65fdeec7a285d25e07f3932ac0fb6cf1) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision ea6ff77291eee02f351953b76c6720cf860c8be7) @@ -25,6 +25,7 @@ #include "FPGA.h" #include "InternalADC.h" #include "OperationModes.h" +#include "PIControllers.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -117,8 +118,6 @@ DATA_DECL( F32, MeasuredBloodPumpMCSpeed, adcBloodPumpMCSpeedRPM, 0.0, 0.0 ); // measured blood pump motor controller speed DATA_DECL( F32, MeasuredBloodPumpMCCurrent, adcBloodPumpMCCurrentmA, 0.0, 0.0 );// measured blood pump motor controller current -static F32 bpFlowError = 0.0; // blood flow error -static F32 bpFlowErrorSum = 0.0; // blood flow error sum static U32 bpControlTimerCounter = 0; // determines when to perform control on blood flow static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; // holds flow samples for a rolling average @@ -164,6 +163,12 @@ // zero rolling flow average buffer resetBloodFlowMovingAverage(); + + // initialize blood flow PI controller + initializePIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, + BP_P_COEFFICIENT, BP_I_COEFFICIENT, + MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE, + BP_MIN_ERROR_SUM, BP_MAX_ERROR_SUM ); } /************************************************************************* @@ -192,9 +197,6 @@ bloodPumpDirection = 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 bloodPumpPWMDutyCyclePct = BP_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 - bpFlowError = 0.0; - bpFlowErrorSum = 0.0; switch ( bloodPumpState ) { @@ -250,9 +252,8 @@ stopBloodPump(); bloodPumpState = BLOOD_PUMP_OFF_STATE; bloodPumpPWMDutyCyclePct = 0.0; - bpFlowError = 0.0; - bpFlowErrorSum = 0.0; bpControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE ); } /************************************************************************* @@ -379,6 +380,7 @@ else if ( bloodPumpPWMDutyCyclePctSet >= bloodPumpPWMDutyCyclePct ) { resetBloodFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp up @@ -415,6 +417,7 @@ else if ( bloodPumpPWMDutyCyclePctSet <= bloodPumpPWMDutyCyclePct ) { resetBloodFlowMovingAverage(); + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp down @@ -442,30 +445,12 @@ BLOOD_PUMP_STATE_T result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; F32 tgtFlow = (F32)getTargetBloodFlowRate(); F32 actFlow = getMeasuredBloodFlowRate(); - F32 pTerm, iTerm; F32 newPWM; // control at set interval if ( ++bpControlTimerCounter >= BP_CONTROL_INTERVAL ) { - // compute P term - if ( MOTOR_DIR_FORWARD == bloodPumpDirectionSet ) - { - bpFlowError = tgtFlow - actFlow; - } - else - { - bpFlowError = (tgtFlow * -1.0) - (actFlow * -1.0); - } - pTerm = bpFlowError * BP_P_COEFFICIENT; - pTerm = RANGE( pTerm, BP_MIN_PWM_DC_DELTA, BP_MAX_PWM_DC_DELTA ); - // compute I term - bpFlowErrorSum += bpFlowError; - iTerm = RANGE( bpFlowErrorSum, BP_MIN_ERROR_SUM, BP_MAX_ERROR_SUM ); - iTerm *= BP_I_COEFFICIENT; - // compute new PWM duty cycle % for blood pump motor - newPWM = bloodPumpPWMDutyCyclePctSet + pTerm + iTerm; - newPWM = RANGE( newPWM, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); + newPWM = runPIController( PI_CONTROLLER_ID_BLOOD_FLOW, tgtFlow, actFlow ); bloodPumpPWMDutyCyclePctSet = newPWM; etpwmSetCmpA( etpwmREG1, (U32)FLOAT_TO_INT_WITH_ROUND( bloodPumpPWMDutyCyclePctSet * (F32)(etpwmREG1->TBPRD) ) ); bpControlTimerCounter = 0;