Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a -rf9b8b75c3686be892799b5446b955fd36ab49fa3 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision f9b8b75c3686be892799b5446b955fd36ab49fa3) @@ -51,6 +51,8 @@ #define DIP_HOME_RATE 50 ///< target pump speed (in estimate mL/min) for homing. #define DIP_HOME_TIMEOUT_MS 10000 ///< maximum time allowed for homing to complete (in ms). +#define DIP_SPEED_CALC_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the dialysate inlet pump speed is calculated. +#define DIP_HALL_EDGE_COUNTS_PER_REV 6 ///< number of hall sensor edge counts per motor revolution. #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 @@ -134,6 +136,10 @@ static BOOL dipStopAtHomePosition = FALSE; ///< stop dialysate inlet pump at next home position static U32 dipHomeStartTime = 0; ///< when did dialysate inlet pump home command begin? (in ms) +static U16 dipLastMotorHallSensorCount = 0; ///< last hall sensor count for the dialysate inlet pump motor +static MOTOR_DIR_T dipMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; ///< pump direction according to hall sensor count +static U32 dipMotorSpeedCalcTimerCtr = 0; ///< counter determines interval for calculating dialysate inlet pump motor speed from hall sensor count. + static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< holds flow samples for a rolling average static U32 flowReadingsIdx = 0; ///< index for next sample in rolling average array static F32 flowReadingsTotal = 0.0; ///< rolling total - used to calc average @@ -158,6 +164,8 @@ static void publishDialInFlowData( void ); static void resetDialInFlowMovingAverage( void ); static void filterDialInFlowReadings( F32 flow ); +static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ); +static void checkDialInPumpRotor( void ); static void checkDialInPumpDirection( void ); static void checkDialInPumpMCCurrent( void ); static DATA_GET_PROTOTYPE( U32, getPublishDialInFlowDataInterval ); @@ -338,21 +346,19 @@ filterDialInFlowReadings( dipFlow ); + // calculate dialysate inlet pump motor speed/direction from hall sensor count + updateDialInPumpSpeedAndDirectionFromHallSensors(); + + // check for home position, zero/low speed + checkDialInPumpRotor(); + // don't start enforcing checks until out of init/POST mode if ( getCurrentOperationMode() != MODE_INIT ) { checkDialInPumpDirection(); checkDialInPumpMCCurrent(); } - // if homing, check timeout - if ( ( TRUE == dipStopAtHomePosition ) && ( TRUE == didTimeout( dipHomeStartTime, DIP_HOME_TIMEOUT_MS ) ) ) - { - signalDialInPumpHardStop(); - dipStopAtHomePosition = FALSE; - // TODO - alarm??? - } - // publish dialIn flow data on interval publishDialInFlowData(); } @@ -814,6 +820,72 @@ /*********************************************************************//** * @brief + * The updateDialInPumpSpeedAndDirectionFromHallSensors function calculates \n + * the dialysate inlet pump motor speed and direction from hall sensor counter on \n + * a 1 second interval. + * @details + * Inputs : dipLastMotorHallSensorCount, dipMotorSpeedCalcTimerCtr, current count from FPGA + * Outputs : dipMotorDirectionFromHallSensors, dialInPumpSpeedRPM + * @return none + *************************************************************************/ +static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ) +{ + if ( ++dipMotorSpeedCalcTimerCtr >= DIP_SPEED_CALC_INTERVAL ) + { + U16 dipMotorHallSensorCount = getFPGADialInPumpHallSensorCount(); + U16 incDelta = ( dipMotorHallSensorCount >= dipLastMotorHallSensorCount ? dipMotorHallSensorCount - dipLastMotorHallSensorCount : ( 0x10000 - dipLastMotorHallSensorCount ) + dipMotorHallSensorCount ); + U16 decDelta = 0x10000 - incDelta; + U16 delta; + + // determine dialysate inlet pump speed/direction from delta hall sensor count since last interval + if ( incDelta < decDelta ) + { + dipMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; + delta = incDelta; + dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + } + else + { + dipMotorDirectionFromHallSensors = MOTOR_DIR_REVERSE; + delta = decDelta; + dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + } + + // update last count for next time + dipLastMotorHallSensorCount = dipMotorHallSensorCount; + dipMotorSpeedCalcTimerCtr = 0; + } +} + +/************************************************************************* + * @brief + * The checkDialInPumpRotor function checks the rotor for the dialysate inlet \n + * pump. If homing, this function will stop when hall sensor detected. If pump \n + * is off or running very slowly, rotor speed will be set to zero. + * @details + * Inputs : dipStopAtHomePosition, dipHomeStartTime, dipRotorRevStartTime + * Outputs : pump may be stopped if homing, dialInPumpRotorSpeedRPM may be set to zero. + * @return none + *************************************************************************/ +static void checkDialInPumpRotor( void ) +{ + // if homing, check timeout + if ( ( TRUE == dipStopAtHomePosition ) && ( TRUE == didTimeout( dipHomeStartTime, DIP_HOME_TIMEOUT_MS ) ) ) + { + signalDialInPumpHardStop(); + dipStopAtHomePosition = FALSE; + // TODO - alarm??? + } + + // if pump is stopped or running very slowly, set rotor speed to zero + if ( TRUE == didTimeout( dipRotorRevStartTime, DIP_HOME_TIMEOUT_MS ) ) + { + dialInPumpRotorSpeedRPM.data = 0.0; + } +} + +/*********************************************************************//** + * @brief * The checkDialInPumpDirection function checks the set direction vs. \n * the direction implied by the sign of the measured MC speed. * @details