Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r9a9d04b84f4345fca87fb14d26f09d497b08aae8 -ra74a984a7059f75d86ad87d6d9499bd8f94cc976 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 9a9d04b84f4345fca87fb14d26f09d497b08aae8) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision a74a984a7059f75d86ad87d6d9499bd8f94cc976) @@ -47,8 +47,6 @@ #define DIP_CONTROL_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) // interval (ms/task time) at which the dialIn pump is controlled #define DIP_P_COEFFICIENT 0.00005 // P term for dialIn pump control #define DIP_I_COEFFICIENT 0.00015 // I term for dialIn pump control -#define DIP_MAX_PWM_DC_DELTA 0.01 // prevents large steps in PWM duty cycle -#define DIP_MIN_PWM_DC_DELTA -0.01 #define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 // motor controller current should not exceed this when pump should be stopped #define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 // motor controller current should always exceed this when pump should be running @@ -101,13 +99,15 @@ // ********** private data ********** -static DIAL_IN_PUMP_STATE_T dialInPumpState = DIAL_IN_PUMP_OFF_STATE; // current state of dialIn flow controller state machine -static U32 dialInFlowDataPublicationTimerCounter = 5; // used to schedule dialIn flow data publication to CAN bus -static BOOL isDialInPumpOn = FALSE; // dialIn pump is currently running -static F32 dialInPumpPWMDutyCyclePct = 0.0; // initial dialIn pump PWM duty cycle -static F32 dialInPumpPWMDutyCyclePctSet = 0.0; // currently set dialIn pump PWM duty cycle -static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; // requested dialIn flow direction -static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; // currently set dialIn flow direction +static DIAL_IN_PUMP_STATE_T dialInPumpState = DIAL_IN_PUMP_OFF_STATE; // current state of dialIn flow controller state machine +static U32 dialInFlowDataPublicationTimerCounter = 5; // used to schedule dialIn flow data publication to CAN bus +static BOOL isDialInPumpOn = FALSE; // dialIn pump is currently running +static F32 dialInPumpPWMDutyCyclePct = 0.0; // initial dialIn pump PWM duty cycle +static F32 dialInPumpPWMDutyCyclePctSet = 0.0; // currently set dialIn pump PWM duty cycle +static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; // requested dialIn flow direction +static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; // currently set dialIn flow direction +static PUMP_CONTROL_MODE_T dialInPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested dialIn pump control mode. +static PUMP_CONTROL_MODE_T dialInPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP;///< currently set dialIn pump control mode. DATA_DECL( U32, DialInFlowDataPub, dialInFlowDataPublishInterval, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL ); // interval (in ms) at which to publish dialIn flow data to CAN bus DATA_DECL( S32, TargetDialInFlowRate, targetDialInFlowRate, 0, 0 ); // requested dialIn flow rate @@ -179,9 +179,10 @@ * Outputs : targetDialInFlowRate, dialInPumpdirection, dialInPumpPWMDutyCyclePct * @param flowRate : new target dialIn flow rate * @param dir : new dialIn flow direction + * @param mode : new control mode * @return TRUE if new flow rate & dir are set, FALSE if not *************************************************************************/ -BOOL setDialInPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir ) +BOOL setDialInPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ) { BOOL result = FALSE; @@ -194,6 +195,7 @@ resetDialInFlowMovingAverage(); targetDialInFlowRate.data = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); dialInPumpDirection = dir; + dialInPumpControlMode = mode; // 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%) @@ -377,7 +379,14 @@ else if ( dialInPumpPWMDutyCyclePctSet >= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); - resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); + dialInPumpControlModeSet = dialInPumpControlMode; + // if open loop mode, set PWM to requested duty cycle where it will stay during control state + if ( dialInPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + { + dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePct ); + } result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp up @@ -414,7 +423,14 @@ else if ( dialInPumpPWMDutyCyclePctSet <= dialInPumpPWMDutyCyclePct ) { resetDialInFlowMovingAverage(); - resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); + dialInPumpControlModeSet = dialInPumpControlMode; + // if open loop mode, set PWM to requested duty cycle where it will stay during control state + if ( dialInPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + { + dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePct ); + } result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; } // continue ramp down @@ -440,16 +456,20 @@ static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ) { DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; - F32 tgtFlow = (F32)getTargetDialInFlowRate(); - F32 actFlow = getMeasuredDialInFlowRate(); - F32 newPWM; // control at set interval if ( ++dipControlTimerCounter >= DIP_CONTROL_INTERVAL ) { - newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); - dialInPumpPWMDutyCyclePctSet = newPWM; - setDialInPumpControlSignalPWM( newPWM ); + if ( dialInPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) + { + F32 tgtFlow = (F32)getTargetDialInFlowRate(); + F32 actFlow = getMeasuredDialInFlowRate(); + F32 newPWM; + + newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); + dialInPumpPWMDutyCyclePctSet = newPWM; + setDialInPumpControlSignalPWM( newPWM ); + } dipControlTimerCounter = 0; } @@ -640,11 +660,11 @@ F32 measMCCurr = getMeasuredDialInPumpMCCurrent(); F32 pumpPWMPctDutyCycle = dialInPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; #ifdef DEBUG_ENABLED - // TODO - temporary debug code - remove later - char debugFlowStr[ 256 ]; - - sprintf( debugFlowStr, "Dial. Set Pt:%5d, Meas. Flow:%5d, Speed:%5d RPM, Current:%5d mA, PWM:%5d \n", flowStPt, (S32)measFlow, (S32)measMCSpd, (S32)measMCCurr, (S32)pumpPWMPctDutyCycle ); - sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); +// // TODO - temporary debug code - remove later +// char debugFlowStr[ 256 ]; +// +// sprintf( debugFlowStr, "Dial. Set Pt:%5d, Meas. Flow:%5d, Speed:%5d RPM, Current:%5d mA, PWM:%5d \n", flowStPt, (S32)measFlow, (S32)measMCSpd, (S32)measMCCurr, (S32)pumpPWMPctDutyCycle ); +// sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); #endif broadcastDialInFlowData( flowStPt, measFlow, measRotSpd, measSpd, measMCSpd, measMCCurr, pumpPWMPctDutyCycle ); dialInFlowDataPublicationTimerCounter = 0;