Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r070554b23739bf16ea2bf9528ebabda1ce0ffeb3 -r8e53754325653805a454de6d82c0c8ca90e068a0 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 070554b23739bf16ea2bf9528ebabda1ce0ffeb3) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 8e53754325653805a454de6d82c0c8ca90e068a0) @@ -46,10 +46,15 @@ #define BP_MAX_PWM_DC_DELTA 0.01 // prevents large steps in PWM duty cycle #define BP_MIN_PWM_DC_DELTA -0.01 +#define BP_MAX_CURR_WHEN_STOPPED_MA 150.0 // motor controller current should not exceed this when pump should be stopped +#define BP_MIN_CURR_WHEN_RUNNING_MA 150.0 // motor controller current should always exceed this when pump should be running +#define BP_MAX_CURR_WHEN_RUNNING_MA 1000.0 // motor controller current should not exceed this when pump should be running +#define BP_MAX_CURR_ERROR_DURATION_MS 500 // motor controller current errors persisting beyond this duration will trigger an alarm + #define BP_SPEED_ADC_TO_RPM_FACTOR 1.375 // conversion factor from ADC counts to RPM for blood pump motor #define BP_CURRENT_ADC_TO_MA_FACTOR 2.65 // conversion factor from ADC counts to mA for blood pump motor -#define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR (124.0 / 1000.0)// 124 pump revolutions = 1 liter or 1,000 mL +#define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR (124.0 / ML_PER_LITER)// 124 pump revolutions = 1 liter or 1,000 mL #define BP_GEAR_RATIO 32.0 // blood pump motor to blood pump gear ratio #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0003125 // ~32 BP motor RPM = 1% PWM duty cycle #define BP_PWM_ZERO_OFFSET 0.1 // 10% PWM duty cycle = zero speed @@ -111,6 +116,8 @@ static U32 flowReadingsIdx = 0; // index for next sample in rolling average array static F32 flowReadingsTotal = 0.0; // rolling total - used to calc average +static U32 bpCurrErrorDurationCtr = 0; // used for tracking persistence of bp current errors + static BLOOD_FLOW_SELF_TEST_STATE_T bloodPumpSelfTestState = BLOOD_FLOW_SELF_TEST_STATE_START; // current blood pump self test state static U32 bloodPumpSelfTestTimerCount = 0; // timer counter for blood pump self test @@ -232,6 +239,7 @@ U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); F32 bpFlow = getFPGABloodFlow(); // TODO - change to avg. blood flow when available from FPGA + MOTOR_DIR_T bpMCDir; adcBloodPumpSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpRPM)) * BP_SPEED_ADC_TO_RPM_FACTOR; adcBloodPumpCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpmA)) * BP_CURRENT_ADC_TO_MA_FACTOR; @@ -242,6 +250,50 @@ flowReadingsIdx = INC_WRAP( flowReadingsIdx, 0, SIZE_OF_ROLLING_AVG-1 ); measuredBloodFlowRate.data = flowReadingsTotal / (F32)SIZE_OF_ROLLING_AVG; + if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) + { + // check set direction vs. direction from sign of motor controller speed + bpMCDir = ( getMeasuredBloodPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); + if ( bloodPumpDirectionSet != bpMCDir ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, (U32)bloodPumpDirectionSet, (U32)bpMCDir ) + } + } + + // check motor controller current thresholds as appropriate + if ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) + { + if ( getMeasuredBloodPumpCurrent() > BP_MAX_CURR_WHEN_STOPPED_MA ) + { + bpCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( bpCurrErrorDurationCtr > BP_MAX_CURR_ERROR_DURATION_MS ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, getMeasuredBloodPumpCurrent() ); + } + } + else + { + bpCurrErrorDurationCtr = 0; + } + } + else // pump s/b running + { + F32 bpCurr = getMeasuredBloodPumpCurrent(); + + if ( ( bpCurr < BP_MIN_CURR_WHEN_RUNNING_MA ) || ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ) ) + { + bpCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( bpCurrErrorDurationCtr > BP_MAX_CURR_ERROR_DURATION_MS ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, getMeasuredBloodPumpCurrent() ); + } + } + else + { + bpCurrErrorDurationCtr = 0; + } + } + // publish blood flow data on interval if ( ++bloodFlowDataPublicationTimerCounter > getPublishBloodFlowDataInterval() ) {