Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r96b5f969bbba7b44593c85c8ac003be0a2d87151 -r3012a339084bbb5fa796d41680bc0c48bdc9f691 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 96b5f969bbba7b44593c85c8ac003be0a2d87151) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 3012a339084bbb5fa796d41680bc0c48bdc9f691) @@ -944,17 +944,13 @@ { BOOL status = FALSE; - // Check if the requested drain pump RPM is within range - if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) + // Check if the user is logged in + if ( TRUE == isTestingActivated() ) { - // Check if the user is logged in - if ( TRUE == isTestingActivated() ) - { - drainPumpMeasuredRPM.ovData = value; - drainPumpMeasuredRPM.override = OVERRIDE_KEY; - drainPumpMeasuredRPM.ovInitData = drainPumpMeasuredRPM.data; - status = TRUE; - } + drainPumpMeasuredRPM.ovData = value; + drainPumpMeasuredRPM.override = OVERRIDE_KEY; + drainPumpMeasuredRPM.ovInitData = drainPumpMeasuredRPM.data; + status = TRUE; } return status; Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r353cb96644812b6278a5b2d98c1b7946a5c47d6e -r3012a339084bbb5fa796d41680bc0c48bdc9f691 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 353cb96644812b6278a5b2d98c1b7946a5c47d6e) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 3012a339084bbb5fa796d41680bc0c48bdc9f691) @@ -91,7 +91,8 @@ BOOL startHeaterSignal; ///< Heater start indication flag. BOOL isHeaterOn; ///< Heater on/off status flag. OVERRIDE_F32_T dutyCycle; ///< Heater duty cycle. - F32 targetFlowLPM; ///< Heater target flow in L/min. + F32 targetFlowLPM; ///< Heater target flow in L/min. + F32 nomTargetFlowLPM; ///< Heater nominal target flow in L/min. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. F32 heaterEstGain; ///< Heater estimation gain during the run. F32 calculatedTemperatureC; ///< Heater calculated temperature. @@ -150,6 +151,7 @@ heatersStatus[ heater ].dutyCycle.ovInitData = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ heater ].dutyCycle.override = 0; heatersStatus[ heater ].targetFlowLPM = 0.0F; + heatersStatus[ heater ].nomTargetFlowLPM = 0.0F; heatersStatus[ heater ].hasTargetTempChanged = FALSE; heatersStatus[ heater ].heaterEstGain = HEATERS_NEUTRAL_EST_GAIN; heatersStatus[ heater ].controlIntervalCounter = 0; @@ -516,47 +518,48 @@ HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; DG_HEATERS_T heater = DG_PRIMARY_HEATER; F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); - F32 targetFlow = 0.0F; + F32 targetFlowLPM = 0.0F; F32 dutyCycle = 0.0F; F32 targetTemperature = heatersStatus[ heater ].targetTempC; DG_OP_MODE_T opMode = getCurrentOperationMode(); if ( DG_MODE_FILL == opMode ) { // If the previous average fill flow rate is 0, use the nominal target RO flow from the RO pump - targetFlow = ( getAvgFillFlowRateLPM() - 0.0F > NEARLY_ZERO ? getAvgFillFlowRateLPM() : getTargetROPumpFlowRateLPM() ); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, TRUE ); - state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; + targetFlowLPM = ( getAvgFillFlowRateLPM() - 0.0F > NEARLY_ZERO ? getAvgFillFlowRateLPM() : getTargetROPumpFlowRateLPM() ); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlowLPM, TRUE ); + state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_GENE == opMode ) || ( DG_MODE_DRAI == opMode ) ) { targetTemperature += DELTA_TEMPERATURE_TIME_COSNTANT_C; - targetFlow = getTargetROPumpFlowRateLPM(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); + targetFlowLPM = getTargetROPumpFlowRateLPM(); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlowLPM, FALSE ); state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_HEAT == opMode ) || ( DG_MODE_CHEM == opMode ) ) { // If the mode is any of the disinfects, specially heat, use the target flow rate instead of the avg. flow // Most of the times the heater should be running at 100% duty cycle since the target temperature is far from // the inlet temperature - targetFlow = getTargetROPumpFlowRateLPM(); + targetFlowLPM = getTargetROPumpFlowRateLPM(); inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlowLPM, FALSE ); state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; } else { // Calculate the energy equation and set the duty cycle // This is for other modes (i.e. standby or service) - targetFlow = getTargetROPumpFlowRateLPM(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); - state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; + targetFlowLPM = getTargetROPumpFlowRateLPM(); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlowLPM, FALSE ); + state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } // Update the calculated target temperature and flow heatersStatus[ DG_PRIMARY_HEATER ].calculatedTemperatureC = targetTemperature; - heatersStatus[ DG_PRIMARY_HEATER ].targetFlowLPM = targetFlow; + heatersStatus[ DG_PRIMARY_HEATER ].targetFlowLPM = targetFlowLPM; + heatersStatus[ DG_PRIMARY_HEATER ].nomTargetFlowLPM = getTargetROPumpFlowRateLPM(); setHeaterDutyCycle( heater, dutyCycle ); return state; @@ -589,7 +592,6 @@ heatersStatus[ heater ].calculatedTemperatureC = targetTemperature; heatersStatus[ heater ].targetFlowLPM = targetFlow; heatersStatus[ heater ].hasTargetTempChanged = FALSE; - setHeaterDutyCycle( heater, dutyCycle ); } @@ -850,7 +852,7 @@ { BOOL status = FALSE; F32 targetFlow = ( DG_PRIMARY_HEATER == heater ? getTargetROPumpFlowRateLPM() : getTargetDialysateFlowLPM() ); - BOOL hasFlowChanged = ( fabs( targetFlow - heatersStatus[ heater ].targetFlowLPM ) > NEARLY_ZERO ? TRUE : FALSE ); + BOOL hasFlowChanged = ( fabs( targetFlow - heatersStatus[ heater ].nomTargetFlowLPM ) > NEARLY_ZERO ? TRUE : FALSE ); // Check if the target flow has changed or the target temperature has changed. if ( TRUE == hasFlowChanged ) Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r0d1a270e86f26fc2ba145cb9aaa036bf09bcc6c1 -r3012a339084bbb5fa796d41680bc0c48bdc9f691 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 0d1a270e86f26fc2ba145cb9aaa036bf09bcc6c1) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 3012a339084bbb5fa796d41680bc0c48bdc9f691) @@ -909,26 +909,29 @@ processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp() ); #ifndef _RELEASE_ - if ( ( getHardwareConfigStatus() != HW_CONFIG_BETA ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) + if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) #endif { - errorCount = (U32)getFPGATHdErrorCount(); - readCount = (U32)getFPGATHdReadCount(); + if ( getCurrentOperationMode() != DG_MODE_INIT ) + { + errorCount = (U32)getFPGATHdErrorCount(); + readCount = (U32)getFPGATHdReadCount(); - checkFPGAPersistentAlarms( FPGA_PERS_ERROR_THD_ADC_TEMP_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_HEAT_DISINFECT, getFPGATHdTemp() ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THD_RTD, getFPGATHdInternalTemp() ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_THD_ADC_TEMP_SENSORS, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_HEAT_DISINFECT, getFPGATHdTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THD_RTD, getFPGATHdInternalTemp() ); - // Make sure the baro sensor coefficients are not corrupted - checkBaroSensorCRC(); + // Make sure the baro sensor coefficients are not corrupted + checkBaroSensorCRC(); - baroConvConsts.refTemperature = getFPGABaroReferenceTemperature(); - baroConvConsts.temperatureCoeff = getFPGABaroTempCoeffOfTemperature(); - errorCount = getFPGABaroErrorCount(); - readCount = getFPGABaroReadCount(); + baroConvConsts.refTemperature = getFPGABaroReferenceTemperature(); + baroConvConsts.temperatureCoeff = getFPGABaroTempCoeffOfTemperature(); + errorCount = getFPGABaroErrorCount(); + readCount = getFPGABaroReadCount(); - checkFPGAPersistentAlarms( FPGA_PERS_ERROR_BARO_SENSOR, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR, getFPGABaroTemperature() ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_BARO_SENSOR, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR, getFPGABaroTemperature() ); + } } errorCount = (U32)getFPGATRoErrorCount(); Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r32cd194d3751a7e7a4d0d0b43d76a4707fdd4e8c -r3012a339084bbb5fa796d41680bc0c48bdc9f691 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 32cd194d3751a7e7a4d0d0b43d76a4707fdd4e8c) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 3012a339084bbb5fa796d41680bc0c48bdc9f691) @@ -55,6 +55,8 @@ #define DATA_PUBLISH_COUNTER_START_COUNT 5 ///< Data publish counter start count. #define NUM_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK 1 ///< Number of acid and bicarb non-volatile data to check. +#define TARGET_TEMP_IN_FILLS_LESS_THAN_UF_VOL_C 45.0F ///< Target temperature in fill less than the ultrafilter's volume in C. + // ********** private data ********** /// Heaters temperature calculation data structure @@ -643,41 +645,54 @@ *************************************************************************/ F32 getPrimaryHeaterTargetTemperature( void ) { - // TODO once the equations are solidified, add the equations as comments to the lines - F32 tempTarget = 0.0; - F32 priTargetTemp = 0.0; + F32 tempTargetC = TARGET_TEMP_IN_FILLS_LESS_THAN_UF_VOL_C; + F32 priTargetTempC = 0.0F; F32 targetFillVolML = getTargetFillVolumeML(); - F32 UFTimeConstant = 0.0; + F32 UFTimeConstant = 0.0F; F32 tempLastFill = getLastFillTemperature(); F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); F32 RsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); F32 targetROFlowLPM = getTargetROPumpFlowRateLPM(); - F32 tgtAicdFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP1_ACID ) / ML_PER_LITER; + F32 tgtAcidFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP1_ACID ) / ML_PER_LITER; F32 tgtBicarbFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP2_BICARB ) / ML_PER_LITER; - F32 tgtTotalFlowLPM = targetROFlowLPM + tgtAicdFlowLPM + tgtBicarbFlowLPM; + F32 tgtTotalFlowLPM = targetROFlowLPM + tgtAcidFlowLPM + tgtBicarbFlowLPM; - if ( FALSE == isThisTheFirstFill() ) + if ( targetFillVolML > heatingConstsCalRecord.ultrafilterVolmL ) { - F32 tempTargetNumerator; - F32 targetTempDenominator; - F32 tempReservoirUse; + if ( FALSE == isThisTheFirstFill() ) + { + F32 tempTargetNumerator; + F32 tempTargetDenominator; + F32 tempReservoirUse; - tempReservoirUse = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; - heatersTempCalc.tempReservoirEndFill = tempReservoirUse - ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); - heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * RsrvrTauCPerMS ); + /* + * 1. T_rsrvr_use = T_target + * 2. T_rsrvr_end_fill = T_rsrvr_use - (t_rsrvr_fill_2_switch * Tau_rsrvr) + * 3. T_rsrvr_0 = T_rsrvr_end_fill - (t_rsrvr_fill/2 * Tau_rsrvr) + * 4. T_UF_fill = T_last_fill + [(t_rsrvr_cycle - t_rsrvr_fill) * Tau_UF] + * 5. T_numerator = T_rsrvr_0 - [(V_UF / V_fill) * T_UF_fill] + * 6. T_denominator = (V_fill - V_UF) / V_fill + * 7. T_mix_target = T_numerator / T_denominator + * 8. T_primary_target = T_mix_target * (Q_total / Q_RO) - (Q_acid / Q_RO) * T_acid - (Q_bicarb / Q_RO) * T_bicarb + */ - heatersTempCalc.timeUFDecayMS = (F32)heatersTempCalc.timeReservoirCycleMS - heatersTempCalc.timeReservoirFillMS; - UFTimeConstant = heatersTempCalc.timeUFDecayMS * UFTauCPerMS; - heatersTempCalc.tempUFFill = tempLastFill + UFTimeConstant; + tempReservoirUse = heatersTempCalc.tempTargetTrimmer; + heatersTempCalc.tempReservoirEndFill = tempReservoirUse - ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); + heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * RsrvrTauCPerMS ); - tempTargetNumerator = heatersTempCalc.tempReservoir0 - ( ( heatingConstsCalRecord.ultrafilterVolmL / targetFillVolML ) * heatersTempCalc.tempUFFill ); - targetTempDenominator = ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ); - tempTarget = tempTargetNumerator / targetTempDenominator; + heatersTempCalc.timeUFDecayMS = (F32)heatersTempCalc.timeReservoirCycleMS - heatersTempCalc.timeReservoirFillMS; + UFTimeConstant = heatersTempCalc.timeUFDecayMS * UFTauCPerMS; + heatersTempCalc.tempUFFill = tempLastFill + UFTimeConstant; + + tempTargetNumerator = heatersTempCalc.tempReservoir0 - ( ( heatingConstsCalRecord.ultrafilterVolmL / targetFillVolML ) * heatersTempCalc.tempUFFill ); + tempTargetDenominator = ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ); + tempTargetC = tempTargetNumerator / tempTargetDenominator; + } + else + { + tempTargetC = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; + } } - else - { - tempTarget = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; - } if ( targetROFlowLPM > 0 ) { @@ -689,17 +704,17 @@ // the target temperature is calculated by estimating the temperature of the dialysates and volume that is being mixed into the RO water F32 acidTemperature = acidConcentrateCalRecord.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidBottleTemperature; F32 bicarbTemperature = bicarbConcentrateCalRecord.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbBottleTemperature; - priTargetTemp = ( tempTarget * ( tgtTotalFlowLPM / targetROFlowLPM ) ) - ( acidTemperature * ( tgtAicdFlowLPM / targetROFlowLPM ) ) - + priTargetTempC = ( tempTargetC * ( tgtTotalFlowLPM / targetROFlowLPM ) ) - ( acidTemperature * ( tgtAcidFlowLPM / targetROFlowLPM ) ) - ( bicarbTemperature * ( tgtBicarbFlowLPM / targetROFlowLPM ) ); } else #endif { - priTargetTemp = tempTarget; + priTargetTempC = tempTargetC; } } - return priTargetTemp; + return priTargetTempC; } /*********************************************************************//** Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -r3012a339084bbb5fa796d41680bc0c48bdc9f691 --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 3012a339084bbb5fa796d41680bc0c48bdc9f691) @@ -34,7 +34,7 @@ // ********** public definitions ********** #define MAX_RESERVOIR_VOLUME_ML 2000 ///< Maximum reservoir volume in mL. -#define RESERVOIR_EXTRA_TEMPERATURE 0.0F ///< Reservoirs extra margin temperature. +#define RESERVOIR_EXTRA_TEMPERATURE 2.0F ///< Reservoirs extra margin temperature. /// Fill command data structure. typedef struct