Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -rb660c59e56cd7cd0123206e918aacc4225cca94b -r46e15981a836f5c96399fd684f06892c2c15cb6b --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision b660c59e56cd7cd0123206e918aacc4225cca94b) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 46e15981a836f5c96399fd684f06892c2c15cb6b) @@ -54,6 +54,7 @@ #define MAX_DIAL_OUT_FLOW_RATE 700 ///< 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. +#define MAX_DIAL_OUT_PUMP_PWM_CHANGE 0.05F ///< Maximum duty cycle change allowed. #define MAX_DIAL_OUT_PUMP_PWM_STEP_UP_CHANGE 0.01064F ///< Maximum duty cycle change when ramping up. #define MAX_DIAL_OUT_PUMP_PWM_STEP_DN_CHANGE 0.016F ///< Maximum duty cycle change when ramping down. #define MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE 0.90F ///< Controller will error if PWM duty cycle > 90%, so set max to 89%. @@ -846,10 +847,29 @@ offsetPWMDutyCyclePct += ( ufrErr * P_UF ); // Add PWM offset to DPi PWM mirror for our new DPo PWM - dialOutPumpPWMDutyCyclePctSet = getDialInPumpPWMDutyCyclePct( FALSE ) + offsetPWMDutyCyclePct; + dialOutPumpPWMDutyCyclePct = getDialInPumpPWMDutyCyclePct( FALSE ) + offsetPWMDutyCyclePct; + + // change in PWM duty cycle should not cross the defined threshold value, if so, Limit the change to max 5% for a single control interval + if ( fabs( dialOutPumpPWMDutyCyclePct - dialOutPumpPWMDutyCyclePctSet ) > MAX_DIAL_OUT_PUMP_PWM_CHANGE ) + { + if ( dialOutPumpPWMDutyCyclePctSet > dialOutPumpPWMDutyCyclePct ) + { + dialOutPumpPWMDutyCyclePctSet -= MAX_DIAL_OUT_PUMP_PWM_CHANGE; + } + else + { + dialOutPumpPWMDutyCyclePctSet += MAX_DIAL_OUT_PUMP_PWM_CHANGE; + } + } + else + { + dialOutPumpPWMDutyCyclePctSet = dialOutPumpPWMDutyCyclePct; + } + // Limit PWM range dialOutPumpPWMDutyCyclePctSet = MIN( dialOutPumpPWMDutyCyclePctSet, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); dialOutPumpPWMDutyCyclePctSet = MAX( dialOutPumpPWMDutyCyclePctSet, MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); + // Apply new PWM to DPo pump setDialOutPumpControlSignalPWM( dialOutPumpPWMDutyCyclePctSet ); } @@ -957,6 +977,7 @@ dialOutBroadCastVariables.ufCalcRate = ufMeasuredRate; dialOutBroadCastVariables.rotorHall = ( hallSensor > 0 ? 0 : 1 ); // 1=home, 0=not home dialOutBroadCastVariables.currentSetUFRate = getCurrentUFSetRate(); + dialOutBroadCastVariables.dialOutPumpState = (U32)dialOutPumpState; broadcastData( MSG_ID_DIALYSATE_OUT_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&dialOutBroadCastVariables, sizeof( DIAL_OUT_FLOW_DATA_T ) ); dialOutFlowDataPublicationTimerCounter = 0; Index: firmware/App/Controllers/DialOutFlow.h =================================================================== diff -u -rff9c8ebdcf0ee2188346cfaa27ff5c2027dcd0a8 -r46e15981a836f5c96399fd684f06892c2c15cb6b --- firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision ff9c8ebdcf0ee2188346cfaa27ff5c2027dcd0a8) +++ firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision 46e15981a836f5c96399fd684f06892c2c15cb6b) @@ -49,6 +49,7 @@ F32 ufCalcRate; ///< Latest calculated UF rate. U32 rotorHall; ///< Latest rotor hall sensor state (1=home, 0=not home) F32 currentSetUFRate; ///< Latest UF set rate. + U32 dialOutPumpState; ///< Current state of execution } DIAL_OUT_FLOW_DATA_T; #pragma pack(pop) Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r6fa37e66ea5aa6be96225821768c8cfd9be78a6a -r46e15981a836f5c96399fd684f06892c2c15cb6b --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 6fa37e66ea5aa6be96225821768c8cfd9be78a6a) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 46e15981a836f5c96399fd684f06892c2c15cb6b) @@ -297,47 +297,66 @@ /*********************************************************************//** * @brief - * The setDialysisParams function sets the dialysis treatment parameters. + * The setDialysisBloodPumpFlowRate function sets the blood pump flow rate parameter. * This function should be called prior to beginning dialysis treatment - * and when the user changes one or more parameters during treatment. + * and when the user changes the blood flow rate during treatment. * @details Inputs: none * @details Outputs: dialysis treatment parameters are set. * @param bPFlow target blood pump flow rate (in mL/min) + * @return none + *************************************************************************/ +void setDialysisBloodPumpFlowRate( U32 bPFlow ) +{ + setBloodFlowRate = bPFlow; + + // Make rate changes in real time if currently performing dialysis. + if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) + { + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } +#endif + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); + } +} + +/*********************************************************************//** + * @brief + * The setDialysisDialInFlowAndUFRate function sets the dialysis treatment parameters. + * This function should be called prior to beginning dialysis treatment + * and when the user changes any one of the parameters during treatment. + * @details Inputs: none + * @details Outputs: dialysis treatment parameters are set. * @param dPFlow target dialysate inlet pump flow rate (in mL/min) * @param maxUFVol maximum ultrafiltration volume (in mL) * @param uFRate target ultrafiltration rate (in mL/min) * @return none *************************************************************************/ -void setDialysisParams( U32 bPFlow, U32 dPFlow, F32 maxUFVol, F32 uFRate ) +void setDialysisDialInFlowAndUFRate( U32 dPFlow, F32 maxUFVol, F32 uFRate ) { - setBloodFlowRate = bPFlow; - setDialysateFlowRate = dPFlow; - setUFVolumeML = maxUFVol; - setUFRate = uFRate; + setDialysateFlowRate = dPFlow; + setUFVolumeML = maxUFVol; + setUFRate = uFRate; - // Make rate changes in real time if currently performing dialysis. - if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) - { - PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Make rate changes in real time if currently performing dialysis. + if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) + { + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) - { - mode = PUMP_CONTROL_MODE_OPEN_LOOP; - } + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); + setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) - { - mode = PUMP_CONTROL_MODE_OPEN_LOOP; - } -#endif - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); - - setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - } + setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + } } /*********************************************************************//** Index: firmware/App/Modes/Dialysis.h =================================================================== diff -u -r16b02389432724c1bd15e9ce58579bff95050a03 -r46e15981a836f5c96399fd684f06892c2c15cb6b --- firmware/App/Modes/Dialysis.h (.../Dialysis.h) (revision 16b02389432724c1bd15e9ce58579bff95050a03) +++ firmware/App/Modes/Dialysis.h (.../Dialysis.h) (revision 46e15981a836f5c96399fd684f06892c2c15cb6b) @@ -55,7 +55,8 @@ void transitionToDialysis( void ); void execDialysis( void ); -void setDialysisParams( U32 bPFlow, U32 dPFlow, F32 maxUFVol, F32 uFRate ); +void setDialysisBloodPumpFlowRate( U32 bPFlow ); +void setDialysisDialInFlowAndUFRate( U32 dPFlow, F32 maxUFVol, F32 uFRate ); void stopDialysis( void ); void startHeparinPump( void ); Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rf47dd3b39499eee03d3e93236335c087b4ad71fb -r46e15981a836f5c96399fd684f06892c2c15cb6b --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision f47dd3b39499eee03d3e93236335c087b4ad71fb) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 46e15981a836f5c96399fd684f06892c2c15cb6b) @@ -738,8 +738,9 @@ { lastTreatmentTimeStamp = getMSTimerCount(); // Kick dialysis sub-mode off - setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), - presMaxUFVolumeML, presUFRate ); + setDialysisBloodPumpFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ); + setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); + if ( presUFRate > 0.0 ) { sendTreatmentLogEventData( UF_START_RESUME_EVENT, 0.0, presUFRate ); @@ -1037,7 +1038,7 @@ presTreatmentTimeSecs = treatmentTime * SEC_PER_MIN; setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, ( presTreatmentTimeSecs / SEC_PER_MIN ) ); - setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); + setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); } else @@ -1221,8 +1222,7 @@ presUFRate = pendingUFRateChange; signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); } - setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), - presMaxUFVolumeML, presUFRate ); + setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); // If UF paused, resume with new settings if ( ( TREATMENT_DIALYSIS_STATE == currentTreatmentState ) && @@ -1281,18 +1281,25 @@ ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) { result = TRUE; - sendTreatmentLogEventData( BLOOD_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), bloodRate ); - sendTreatmentLogEventData( DIALYSATE_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), dialRate ); - if ( ( bloodRate != (U32)getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ) || - ( dialRate != (U32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ) ) + // handle blood pump flow rate change + if ( bloodRate != (U32)getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ) { + sendTreatmentLogEventData( BLOOD_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), bloodRate ); signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + // Set to new rate + setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, bloodRate ); + setDialysisBloodPumpFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ); } - // Set to new rates - setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, bloodRate ); - setTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW, dialRate ); - setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), - presMaxUFVolumeML, presUFRate ); + + // Handle dialysate flow rate changes + if ( dialRate != (U32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ) + { + sendTreatmentLogEventData( DIALYSATE_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), dialRate ); + signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + // Set to new rate + setTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW, dialRate ); + setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); + } } else {