Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r0931b50383943421f0c0b85dcda738bb8b006a16 -rbd241ef5231a9869adaf7bb5ed166135beb2c0fb --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 0931b50383943421f0c0b85dcda738bb8b006a16) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision bd241ef5231a9869adaf7bb5ed166135beb2c0fb) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file SyringePump.c * * @author (last) Sean Nash -* @date (last) 13-Aug-2021 +* @date (last) 15-Nov-2021 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -38,7 +38,7 @@ /// Default publication interval for syringe pump data. #define SYRINGE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) -#define BD_SYRINGE_ID_RADIUS_CM ( 1.402 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. +#define BD_SYRINGE_ID_RADIUS_CM ( 1.4427 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. /// Milliliters per mm of syringe plunger travel. #define SYRINGE_ML_PER_MM ( ( BD_SYRINGE_ID_RADIUS_CM * BD_SYRINGE_ID_RADIUS_CM ) * PI * 0.1 ) #define SYRINGE_MM_PER_REV 0.635 ///< Travel (in mm) per revolution. @@ -57,7 +57,7 @@ /// Number of micro steps per mL. #define SYRINGE_MICRO_STEPS_PER_ML ( ( SYRINGE_MICRO_STEPS_PER_REV / SYRINGE_MM_PER_REV ) / SYRINGE_ML_PER_MM ) -#define MIN_HEPARIN_CONTINUOUS_RATE 0.1 ///< Minimum continuous Heparin flow rate (in mL/hr). +#define MIN_HEPARIN_CONTINUOUS_RATE 0.2 ///< Minimum continuous Heparin flow rate (in mL/hr). #define MAX_HEPARIN_CONTINUOUS_RATE 1.0 ///< Maximum continuous Heparin flow rate (in mL/hr). #define MIN_HEPARIN_BOLUS_RATE 1.2 ///< Minimum Heparin bolus flow rate (in mL/hr). #define MAX_HEPARIN_BOLUS_RATE 24.0 ///< Maximum Heparin bolus flow rate (in mL/hr). @@ -69,7 +69,7 @@ #define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 2000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. #define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. -#define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 500 ///< Alarm persistence period (in ms) for syringe pump off check alarms. +#define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. #define SYRINGE_PUMP_OCCLUSION_ALARM_PERSISTENCE 30 ///< Alarm persistence period (in ms) for syringe pump occlusion alarms. #define SYRINGE_PUMP_ADC_READ_PERSISTENCE 100 ///< Syringe pump ADC stale read alarm persistence time (in ms). @@ -91,7 +91,7 @@ #define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow 5 percent over target before alarming on over travel. /// Expected position of empty in relation to home postion. -#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 11.0 ) // TODO - get syringe volume from home to empty (11 mL is placeholder) +#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) /// Minimum retract position. @@ -1280,22 +1280,21 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_SEEK_STATE; BOOL stopPump = FALSE; + S32 pos = getSyringePumpPosition(); + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; + F32 txVolume = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); + F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_MICRO_STEPS_PER_ML; // Handle ramp up rampSyringePump(); - // Is plunger contact detected? - if ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) + // Is plunger contact detected or insufficient Heparin volume detected? + if ( ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) || ( syringeVol < txVolume ) ) { - S32 pos = getSyringePumpPosition(); - F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); - U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); - U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; - F32 txVolume = bolusVol + ( hepDurHr * contRate ); - F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_MICRO_STEPS_PER_ML; - stopPump = TRUE; syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; @@ -1557,6 +1556,7 @@ { S32 pos = getSyringePumpPosition(); + // If near empty position, assume syringe is empty if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) { heparinDeliveryState = HEPARIN_STATE_EMPTY; @@ -1769,12 +1769,12 @@ *************************************************************************/ static void calcStepperToggleTimeForTargetRate( F32 rate ) { - double temp; + F64 temp; F32 conv; // Convert given rate to stepper toggle period - temp = (double)rate * SYRINGE_MICRO_STEPS_PER_ML; // = uSteps/hr - temp /= (double)( MIN_PER_HOUR * SEC_PER_MIN); // = uSteps/sec + temp = (F64)rate * SYRINGE_MICRO_STEPS_PER_ML; // = uSteps/hr + temp /= (F64)( MIN_PER_HOUR * SEC_PER_MIN); // = uSteps/sec temp /= MICRO_SECONDS_PER_SECOND; // = uSteps/uSec conv = (F32)temp * SYRINGE_TOGGLES_PER_STEP; // = toggles/uSec conv = 1.0 / conv; // = uSec/toggle @@ -1803,7 +1803,7 @@ U32 nextIdx = INC_WRAP( syringePumpMotorSpeedCalcIdx, 0, SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN - 1 ); S32 countsPerSec = pos - syringePumpLastPositions[ syringePumpMotorSpeedCalcIdx ]; // Calc delta between pos 1 second ago and pos now S32 countsPerHr = countsPerSec * ( MIN_PER_HOUR * SEC_PER_MIN); - F32 mLPerHr = (F32)((double)countsPerHr / (double)SYRINGE_ENCODER_COUNTS_PER_ML); + F32 mLPerHr = (F32)((F64)countsPerHr / (F64)SYRINGE_ENCODER_COUNTS_PER_ML); // Set latest measured rate syringePumpMeasRate.data = mLPerHr;