Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r6eb873c4bc96fb22e85ac23aeee1c37e5366d731 -r96a23b8fe38dda9442cd6f052aeb3eadca198e4b --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 6eb873c4bc96fb22e85ac23aeee1c37e5366d731) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 96a23b8fe38dda9442cd6f052aeb3eadca198e4b) @@ -21,16 +21,17 @@ #include "gio.h" #include "mibspi.h" +#include "DialInFlow.h" #include "FPGA.h" #include "InternalADC.h" #include "NVDataMgmt.h" #include "OperationModes.h" +#include "PersistentAlarm.h" #include "PIControllers.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "Timers.h" -#include "DialInFlow.h" /** * @addtogroup DialysateInletFlow @@ -39,16 +40,17 @@ // ********** private definitions ********** -#define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the dialIn flow data is published on the CAN bus +/// interval (ms/task time) at which the dialIn flow data is published on the CAN bus. +#define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) #define MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE 0.0133 ///< max duty cycle change when ramping up ~ 200 mL/min/s. #define MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE 0.02 ///< max duty cycle change when ramping down ~ 300 mL/min/s. -#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.88 ///< controller will error if PWM duty cycle > 90%, so set max to 88% -#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.12 ///< controller will error if PWM duty cycle < 10%, so set min to 12% +#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.88 ///< controller will error if PWM duty cycle > 90%, so set max to 88%. +#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.12 ///< controller will error if PWM duty cycle < 10%, so set min to 12%. #define DIP_CONTROL_INTERVAL ( 10000 / TASK_GENERAL_INTERVAL ) ///< interval (ms/task time) at which the dialIn pump is controlled -#define DIP_P_COEFFICIENT 0.00035 ///< P term for dialIn pump control -#define DIP_I_COEFFICIENT 0.00035 ///< I term for dialIn pump control +#define DIP_P_COEFFICIENT 0.00035 ///< P term for dialIn pump control. +#define DIP_I_COEFFICIENT 0.00035 ///< I term for dialIn pump control. #define DIP_HOME_RATE 100 ///< target pump speed (in estimate mL/min) for homing. #define DIP_HOME_TIMEOUT_MS 10000 ///< maximum time allowed for homing to complete (in ms). @@ -65,27 +67,35 @@ #define DIP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< persist time (task intervals) rotor speed error condition. -#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 -#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 ///< motor controller current should not exceed this when pump should be running -#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 ///< motor controller current errors persisting beyond this duration will trigger an alarm +#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. +#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 ///< motor controller current should not exceed this when pump should be running. +#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 ///< motor controller current errors persisting beyond this duration will trigger an alarm. -#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< conversion factor from ADC counts to RPM for dialIn pump motor -#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< conversion factor from ADC counts to mA for dialIn pump motor +#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< conversion factor from ADC counts to RPM for dialIn pump motor. +#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< conversion factor from ADC counts to mA for dialIn pump motor. -#define DIP_REV_PER_LITER 150.24 ///< rotor revolutions per liter -#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) ///< -#define DIP_GEAR_RATIO 32.0 ///< dialIn pump motor to dialIn pump gear ratio -#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00028 ///< ~28 BP motor RPM = 1% PWM duty cycle -#define DIP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed -#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) ///< +#define DIP_REV_PER_LITER 150.24 ///< rotor revolutions per liter. +/// Macro converts flow rate to motor RPM. +#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) +#define DIP_GEAR_RATIO 32.0 ///< dialIn pump motor to dialIn pump gear ratio. +#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00028 ///< ~28 BP motor RPM = 1% PWM duty cycle. +#define DIP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. +/// Macro converts flow rate to estimate PWM needed to achieve it. +#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) -#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 ///< BP analog signals are 0-3V (while int. ADC ref V may be different) +#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 ///< BP analog signals are 0-3V (while int. ADC ref V may be different). #define DIAL_IN_PUMP_ADC_ZERO 1998 ///< Mid-point (zero) for ADC readings. -#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) ///< Macro converts a 12-bit ADC reading to a signed 16-bit value. - -#define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 10 ) ///< measured dialIn flow is filtered w/ moving average - +///< Macro converts a 12-bit ADC reading to a signed 16-bit value. +#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) + +/// measured dialIn flow is filtered w/ moving average. +#define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 10 ) + +/// dialysate flow sensor signal strength low alarm persistence. +#define FLOW_SIG_STRGTH_ALARM_PERSIST ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 5 ) +#define MIN_FLOW_SIG_STRENGTH 90.0 ///< Minimum flow sensor signal strength. + /// Enumeration of dialysate inlet pump states. typedef enum DialInPump_States { @@ -210,6 +220,11 @@ 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 ); + + // initialize persistent alarm for flow sensor signal strength too low + initPersistentAlarm( PERSISTENT_ALARM_DIALYSATE_FLOW_SIGNAL_STRENGTH, + ALARM_ID_DIALYSATE_FLOW_SIGNAL_STRENGTH_TOO_LOW, + FALSE, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); } /*********************************************************************//** @@ -370,6 +385,7 @@ *************************************************************************/ void execDialInFlowMonitor( void ) { + HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); F32 dipFlow = ( getFPGADialysateFlow() * dialInFlowCalGain ) + dialInFlowCalOffset; @@ -384,7 +400,7 @@ updateDialInPumpSpeedAndDirectionFromHallSensors(); // don't start enforcing checks until out of init/POST mode - if ( getCurrentOperationMode() != MODE_INIT ) + if ( opMode != MODE_INIT ) { // check pump direction checkDialInPumpDirection(); @@ -397,6 +413,16 @@ checkDialInPumpRotor(); } + // check flow sensor signal strength when appropriate TODO - in pre-treatment, must be far enough along for fluid to be in tubing + if ( MODE_TREA == opMode || + ( MODE_PRET == opMode && FALSE ) ) + { + F32 sigStrength = getMeasuredDialInFlowSignalStrength(); + BOOL outOfRange = ( sigStrength < MIN_FLOW_SIG_STRENGTH ? TRUE : FALSE ); + + checkPersistentAlarm( PERSISTENT_ALARM_DIALYSATE_FLOW_SIGNAL_STRENGTH, outOfRange, sigStrength ); + } + // publish dialIn flow data on interval publishDialInFlowData(); }