Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -rc67def50892f9a7c2f1f22985b5351465a8f6773 -r1a685471524555a374854c0c9ec8e208e71fe2df --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision c67def50892f9a7c2f1f22985b5351465a8f6773) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 1a685471524555a374854c0c9ec8e208e71fe2df) @@ -38,7 +38,8 @@ // ********** private definitions ********** -#define DIAL_OUT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate outlet pump data is published on the CAN bus. +/// Interval (ms/task time) at which the dialysate outlet pump data is published on the CAN bus. +#define DIAL_OUT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) #define MAX_DIAL_OUT_FLOW_RATE 650 ///< Maximum dialysate outlet pump flow rate in mL/min. #define MIN_DIAL_OUT_FLOW_RATE 100 ///< Minimum dialysate outlet pump flow rate in mL/min. @@ -61,9 +62,10 @@ #define DOP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< maximum motor speed (RPM) while motor is commanded off. #define DOP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< maximum difference in speed between motor and rotor (in rotor RPM). #define DOP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< maximum difference in speed between measured and commanded RPM. -#define DOP_OFF_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) for motor off error condition. -#define DOP_MOTOR_SPEED_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) motor speed error condition. -#define DOP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) rotor speed error condition. +#define DOP_OFF_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) for motor off error condition. +#define DOP_MOTOR_SPEED_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) motor speed error condition. +#define DOP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) rotor speed error condition. +#define DOP_DIRECTION_ERROR_PERSIST (250 / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) pump direction error condition. #define DOP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. #define DOP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running. @@ -78,12 +80,13 @@ /*** setDialOutFlowRxTotalVolumeAndRxTime ***/ -#define DOP_REV_PER_LITER 150.24 ///< Rotor revolutions per liter. +#define DOP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter. #define DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DOP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to pump motor RPM. #define DOP_GEAR_RATIO 32.0 ///< Pump motor to pump gear ratio. #define DOP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00028 ///< ~28 DPo motor RPM = 1% PWM duty cycle. #define DOP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. -#define DOP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DOP_GEAR_RATIO * DOP_MOTOR_RPM_TO_PWM_DC_FACTOR + DOP_PWM_ZERO_OFFSET ) ///< Macro converts a flow rate to an estimated PWM duty cycle %. +/// Macro converts a flow rate to an estimated PWM duty cycle %. +#define DOP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DOP_GEAR_RATIO * DOP_MOTOR_RPM_TO_PWM_DC_FACTOR + DOP_PWM_ZERO_OFFSET ) /// Enumeration of dialysate outlet pump controller states. typedef enum DialOutPump_States @@ -147,12 +150,12 @@ static U32 dopHomeStartTime = 0; ///< when did dialysate outlet pump home command begin? (in ms) static U16 dopLastMotorHallSensorCount = 0; ///< last hall sensor count for the dialysate outlet pump motor -static MOTOR_DIR_T dopMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; ///< pump direction according to hall sensor count static U32 dopMotorSpeedCalcTimerCtr = 0; ///< counter determines interval for calculating dialysate outlet pump motor speed from hall sensor count. static U32 errorDialOutMotorOffPersistTimerCtr = 0; ///< persistence timer counter for motor off check error condition. static U32 errorDialOutMotorSpeedPersistTimerCtr = 0; ///< persistence timer counter for motor speed error condition. static U32 errorDialOutRotorSpeedPersistTimerCtr = 0; ///< persistence timer counter for rotor speed error condition. +static U32 errorDialOutPumpDirectionPersistTimerCtr = 0; ///< persistence timer counter for pump direction error condition. static DIAL_OUT_PUMP_SELF_TEST_STATE_T dialOutPumpSelfTestState = DIAL_OUT_PUMP_SELF_TEST_STATE_START; ///< Current state of the dialysate outlet pump self-test state machine. static U32 dialOutPumpSelfTestTimerCount = 0; ///< Timer counter for time reference during self-test. @@ -374,6 +377,19 @@ /*********************************************************************//** * @brief + * The isDialOutPumpRunning function returns whether the dialysate outlet + * pump is currently running or not. + * @details Inputs: isDialOutPumpOn + * @details Outputs: none + * @return isDialOutPumpOn + *************************************************************************/ +BOOL isDialOutPumpRunning( void ) +{ + return isDialOutPumpOn; +} + +/*********************************************************************//** + * @brief * The setDialOutUFVolumes function sets the ultrafiltration reference and * measured total volumes (in mL). * @details Inputs: none @@ -511,7 +527,7 @@ DIAL_OUT_PUMP_STATE_T result = DIAL_OUT_PUMP_RAMPING_UP_STATE; // have we been asked to stop the dialOut pump? - if ( dialOutPumpPWMDutyCyclePct < NEARLY_ZERO ) + if ( dialOutPumpPWMDutyCyclePct < (MAX_DIAL_OUT_PUMP_PWM_STEP_DN_CHANGE + DOP_PWM_ZERO_OFFSET) ) { // start ramp down to stop dialOutPumpPWMDutyCyclePctSet -= MAX_DIAL_OUT_PUMP_PWM_STEP_DN_CHANGE; @@ -554,7 +570,7 @@ DIAL_OUT_PUMP_STATE_T result = DIAL_OUT_PUMP_RAMPING_DOWN_STATE; // have we essentially reached zero speed - if ( dialOutPumpPWMDutyCyclePctSet < (MAX_DIAL_OUT_PUMP_PWM_STEP_UP_CHANGE + DOP_PWM_ZERO_OFFSET) ) + if ( dialOutPumpPWMDutyCyclePctSet < (MAX_DIAL_OUT_PUMP_PWM_STEP_DN_CHANGE + DOP_PWM_ZERO_OFFSET) ) { stopDialOutPump(); result = DIAL_OUT_PUMP_OFF_STATE; @@ -740,13 +756,11 @@ // determine dialysate outlet pump speed/direction from delta hall sensor count since last interval if ( incDelta < decDelta ) { - dopMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; delta = incDelta; dialOutPumpSpeedRPM.data = ( (F32)delta / (F32)DOP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; } else { - dopMotorDirectionFromHallSensors = MOTOR_DIR_REVERSE; delta = decDelta; dialOutPumpSpeedRPM.data = ( (F32)delta / (F32)DOP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; } @@ -793,19 +807,42 @@ *************************************************************************/ static void checkDialOutPumpDirection( void ) { - MOTOR_DIR_T dopMCDir; - if ( DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE == dialOutPumpState ) { - // check set direction vs. direction from hall sensors or sign of motor controller speed + MOTOR_DIR_T dopMCDir, dopDir; + dopMCDir = ( getMeasuredDialOutPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); - if ( ( dialOutPumpDirectionSet != dopMCDir ) || ( dialOutPumpDirectionSet != dopMotorDirectionFromHallSensors ) ) + dopDir = ( getMeasuredDialOutPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); + + // check set direction vs. direction from hall sensors + if ( dialOutPumpDirectionSet != dopDir ) { + if ( ++errorDialOutPumpDirectionPersistTimerCtr >= DOP_DIRECTION_ERROR_PERSIST ) + { #ifndef DISABLE_PUMP_DIRECTION_CHECKS - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, (U32)dialOutPumpDirectionSet, (U32)dopMotorDirectionFromHallSensors ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, (U32)dialOutPumpDirectionSet, (U32)dopDir ) #endif + } } + // check set direction vs. direction from sign of motor controller speed + else if ( dialOutPumpDirectionSet != dopMCDir ) + { + if ( ++errorDialOutPumpDirectionPersistTimerCtr >= DOP_DIRECTION_ERROR_PERSIST ) + { +#ifndef DISABLE_PUMP_DIRECTION_CHECKS + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, (U32)dialOutPumpDirectionSet, (U32)dopMCDir ) +#endif + } + } + else + { + errorDialOutPumpDirectionPersistTimerCtr = 0; + } } + else + { + errorDialOutPumpDirectionPersistTimerCtr = 0; + } } /*********************************************************************//**