Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -rccfd15568f1e3d304320c2babb2fd4bcf0413304 -r8bd1ae47aa13a843aa8abd6321ddc050deacb4a6 --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision ccfd15568f1e3d304320c2babb2fd4bcf0413304) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 8bd1ae47aa13a843aa8abd6321ddc050deacb4a6) @@ -85,15 +85,14 @@ #define DOP_SPEED_ADC_TO_RPM_FACTOR 1.751752 ///< Conversion factor from ADC counts to RPM for dialysate outlet pump motor. #define DOP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000193 ///< ~52 BP motor RPM = 1% PWM duty cycle -#define UF_PWM_DC_PCT_PER_ML_PER_MIN 0.004 ///< Estimated DPo PWM duty cycle amount per each mL/min of ultrafiltration desired. #define DOP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< Conversion factor from ADC counts to mA for dialysate outlet pump motor. #define DOP_ADC_FULL_SCALE_V 3.0 ///< DPo analog signals are 0-3V (while int. ADC ref V may be different). #define DOP_ADC_ZERO 1998 ///< Mid-point (zero) for ADC readings. #define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DOP_ADC_ZERO ) ///< Macro converts a 12-bit ADC reading to a signed 16-bit value. /*** setDialOutFlowRxTotalVolumeAndRxTime ***/ -#define DOP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter. +#define DOP_REV_PER_LITER 144.7 ///< Rotor revolutions per liter. #define DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DOP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to pump motor RPM. #define DOP_GEAR_RATIO 32.0 ///< Pump motor to pump gear ratio. #define DOP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. @@ -151,6 +150,10 @@ static OVERRIDE_F32_T dialOutPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate outlet pump motor controller current. static OVERRIDE_F32_T dialOutPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate outlet pump rotor speed. static OVERRIDE_F32_T dialOutPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate outlet pump motor speed. +#if 1 // TODO - remove test code +static F32 ufMeasuredRate = 0.0; +static F32 prevMeasuredVolumes[2] = { 0.0, 0.0 }; +#endif static U32 dopControlTimerCounter = 0; ///< Timer counter to determine when to control dialysate outlet pump. static U32 dopCurrErrorDurationCtr = 0; ///< Timer counter for motor current error persistence. @@ -515,7 +518,7 @@ } else { // Closed loop UF control is only controlling offset from DPi PWM - resetPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, (F32)( (S32)lastGivenRate - getTargetDialInFlowRate() ) * UF_PWM_DC_PCT_PER_ML_PER_MIN ); + resetPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, dialOutPumpPWMDutyCyclePctSet - getDialInPumpPWMDutyCyclePct( TRUE ) ); } dialOutPumpControlModeSet = dialOutPumpControlMode; setDialOutPumpControlSignalPWM( dialOutPumpPWMDutyCyclePctSet ); @@ -560,7 +563,7 @@ } else { // Closed loop UF control is only controlling offset from DPi PWM - resetPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, (F32)( (S32)lastGivenRate - getTargetDialInFlowRate() ) * UF_PWM_DC_PCT_PER_ML_PER_MIN ); + resetPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, dialOutPumpPWMDutyCyclePctSet - getDialInPumpPWMDutyCyclePct( TRUE ) ); } dialOutPumpControlModeSet = dialOutPumpControlMode; setDialOutPumpControlSignalPWM( dialOutPumpPWMDutyCyclePctSet ); @@ -598,10 +601,16 @@ F32 totVol = getTotalMeasuredUFVolumeInMl(); F32 offsetPWMDutyCyclePct; +#if 1 // TODO - remove test code + ufMeasuredRate = ( totVol - prevMeasuredVolumes[1] ) * 6.0; // calculate UF rate based on change in volume over last 10 seconds + prevMeasuredVolumes[1] = prevMeasuredVolumes[0]; // update last 2 volumes for next time + prevMeasuredVolumes[0] = totVol; +#endif + // Get new PWM offset from PI controller offsetPWMDutyCyclePct = runPIController( PI_CONTROLLER_ID_ULTRAFILTRATION, refVol, totVol ); // Add PWM offset to DPi PWM mirror for our new DPo PWM - dialOutPumpPWMDutyCyclePctSet = getDialInPumpPWMDutyCyclePct() + offsetPWMDutyCyclePct; + dialOutPumpPWMDutyCyclePctSet = getDialInPumpPWMDutyCyclePct( FALSE ) + offsetPWMDutyCyclePct; // Limit PWM range dialOutPumpPWMDutyCyclePctSet = MIN( dialOutPumpPWMDutyCyclePctSet, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); dialOutPumpPWMDutyCyclePctSet = MAX( dialOutPumpPWMDutyCyclePctSet, MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); @@ -703,12 +712,16 @@ dialOutBroadCastVariables.refUFVolMl = getTotalTargetDialOutUFVolumeInMl(); dialOutBroadCastVariables.measUFVolMl = getTotalMeasuredUFVolumeInMl(); dialOutBroadCastVariables.measRotSpdRPM = getMeasuredDialOutPumpRotorSpeed(); +#if 1 // TODO - remove test code + dialOutBroadCastVariables.measSpdRPM = ufMeasuredRate; +#else dialOutBroadCastVariables.measSpdRPM = getMeasuredDialOutPumpSpeed(); +#endif dialOutBroadCastVariables.measMCSpdRPM = getMeasuredDialOutPumpMCSpeed(); dialOutBroadCastVariables.measMCCurrmA = getMeasuredDialOutPumpMCCurrent(); dialOutBroadCastVariables.setPWMpct = dialOutPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; - broadcastDialOutFlowData( &dialOutBroadCastVariables); + broadcastData( MSG_ID_DIALYSATE_OUT_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&dialOutBroadCastVariables, sizeof( DIAL_OUT_FLOW_DATA_T ) ); dialOutFlowDataPublicationTimerCounter = 0; } }