Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r752defbb739ea0756a8bf060f00bc6b9429c2764 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 752defbb739ea0756a8bf060f00bc6b9429c2764) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -112,6 +112,7 @@ static U32 drainControlTimerCounter = 0; ///< Determines when to perform control on drain pump. static BOOL hasClosedLoopBeenRequested = FALSE; ///< Closed loop pump control flag. static U32 currentDrainPumpRPM = 0; ///< Current drain pump RPM from feedback. +static BOOL signalNewRPMRequest = FALSE; ///< Signal flag the indicates there is a new RPM request. static DRAIN_PUMP_STATE_T pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; ///< Delayed (pending) drain pump command. static F32 pendingDrainPumpCmdTarget = 0.0; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). @@ -134,15 +135,17 @@ * @brief * The initDrainPump function initializes the DrainPump module. * @details Inputs: none - * @details Outputs: hasClosedLoopBeenRequested + * @details Outputs: hasClosedLoopBeenRequested, targetFlushLineVolume_L, + * signalNewRPMRequest * @return none *************************************************************************/ void initDrainPump( void ) { stopDrainPump(); hasClosedLoopBeenRequested = FALSE; - targetFlushLineVolume_L = 0.0; + targetFlushLineVolume_L = 0.0; + signalNewRPMRequest = FALSE; // Initialize the drain pump PI controller initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, @@ -177,6 +180,7 @@ targetDrainPumpRPM = rpm; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; + signalNewRPMRequest = TRUE; result = TRUE; } else @@ -515,6 +519,8 @@ // Set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); + // Turn off the new RPM signal + signalNewRPMRequest = FALSE; // Set drain pump DAC drainPumpDACSet = drainPumpDAC; setFPGADrainPumpSpeed( drainPumpDACSet ); @@ -578,20 +584,28 @@ /*********************************************************************//** * @brief * The handleDrainPumpOpenLoopState function handles the open loop state. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: signalNewRPMRequest + * @details Outputs: signalNewRPMRequest, drainPumpDACSet * @return next state of the controller state machine *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ) { DRAIN_PUMP_STATE_T state = DRAIN_PUMP_OPEN_LOOP_STATE; - // Check if the RPM is 0, and if it is turn off the pump + // Check if the RPM is 0, then turn off the pump if ( 0 == getTargetDrainPumpRPM() ) { state = DRAIN_PUMP_OFF_STATE; signalDrainPumpHardStop(); } + // If there is a signal for a new RPM, change to the new RPM + else if ( TRUE == signalNewRPMRequest ) + { + // Set drain pump DAC + drainPumpDACSet = drainPumpDAC; + setFPGADrainPumpSpeed( drainPumpDACSet ); + signalNewRPMRequest = FALSE; + } return state; } Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -70,26 +70,29 @@ #define TEMPERATURES_MOVING_AVG_SIZE 3U ///< Heaters ramp state temperatures moving average size. #define DELTA_TEMPERATURE_TIME_COSNTANT_C 8.6 ///< Delta temperature calculated from time constant. +#define MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C 0.25 ///< Maximum allowed temperature deviation from target temperature in C. +#define PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C 0.03 ///< Primary heaters duty cycle per temperature in C. static const F32 WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES = 4184 / SEC_PER_MIN; ///< Water specific heat in J/KgC / 60. static const F32 PRIMARY_HEATERS_MAXIMUM_POWER_WATTS = 475 + 237.5; ///< Primary heaters maximum power (main primary = 475W and small primary = 237.5W). +/// Heaters exec states typedef enum Heaters_Exec_States { HEATER_EXEC_STATE_OFF = 0, ///< Heater exec state off. - HEATER_EXEC_STATE_RAMP_TO_TARGET, ///< Heater exec state ramp to target. - HEATER_EXEC_STATE_CONTROL_TO_TARGET, ///< Heater exec state control to target. + HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET, ///< Heater exec state ramp to target. + HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET, ///< Heater exec state control to target. HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET, ///< Heater exec state control to disinfect (heat or chemical) target. + HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET, + HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET, NUM_OF_HEATERS_STATE, ///< Number of heaters state. } HEATERS_STATE_T; /// Heaters data structure typedef struct { - F32 targetTemp; // TODO do we need this anymore? ///< Heater target temperature. - F32 originalTargetTemp; ///< Heater original target temperature set by user. + F32 targetTemp; ///< Heater target temperature. HEATERS_STATE_T state; ///< Heater state. - TEMPERATURE_SENSORS_T feedbackSensor; // TODO do we need this? ///< Heater feedback sensor for controlling. U32 controlTimerCounter; // TODO remove? Maybe use in heat disinfect ///< Heater control timer counter. BOOL startHeaterSignal; ///< Heater start indication flag. BOOL isHeaterOn; ///< Heater on/off status flag. @@ -101,7 +104,6 @@ F32 heaterEfficiency; ///< Heater efficiency during the run. BOOL hasTargetBeenReached; ///< Heater flag to indicate whether the target temperature has been reached. - PI_CONTROLLER_ID_T controllerID; ///< Heater PI controller ID TODO remove this? U32 tempOutOfRangeTimer; ///< Heater temperature out of range timer TODO remove once the mechanical thermal cutoff was implemented BOOL isHeaterTempOutOfRange; ///< Heater temperature out of range flag indicator TODO remove once the mechanical thermal cutoff was implemented } HEATER_STATUS_T; @@ -130,8 +132,6 @@ static void checkPrimaryHeaterTempSensors( void ); static void checkTrimmerHeaterTempSensors( void ); static void monitorHeatersVoltage( void ); -static void checkHeaterOnStatus( DG_HEATERS_T heater ); -static void getHeatersEfficiencyFromRTCRAM( void ); /*********************************************************************//** * @brief @@ -146,31 +146,22 @@ DG_HEATERS_T heater; voltageMonitorTimeCounter = 0; - operationMode = 0; + operationMode = 0; for ( heater = DG_PRIMARY_HEATER; heater < NUM_OF_DG_HEATERS; heater++ ) { heatersStatus[ heater ].controlTimerCounter = 0; - // The default feedback sensor of the primary heater is TPo but it changes to THd in heat disinfect - // The default feedback sensor of the trimmer heater is TDi all the time - heatersStatus[ heater ].feedbackSensor = ( DG_PRIMARY_HEATER == heater ? TEMPSENSORS_OUTLET_PRIMARY_HEATER : TEMPSENSORS_INLET_DIALYSATE ); heatersStatus[ heater ].startHeaterSignal = FALSE; heatersStatus[ heater ].tempOutOfRangeTimer = 0; heatersStatus[ heater ].isHeaterTempOutOfRange = FALSE; heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; heatersStatus[ heater ].targetTemp = 0.0; - heatersStatus[ heater ].originalTargetTemp = 0.0; heatersStatus[ heater ].dutycycle = 0.0; heatersStatus[ heater ].targetROFlow = 0.0; - heatersStatus[ heater ].controllerID = ( DG_PRIMARY_HEATER == heater ? 4 : PI_CONTROLLER_ID_TRIMMER_HEATER ); // TODO remove or refactor? heatersStatus[ heater ].hasTargetTempChanged = FALSE; heatersStatus[ heater ].heaterEfficiency = 1.0; // Assuming 100% efficiency during initialization until it is updated heatersStatus[ heater ].hasTargetBeenReached = FALSE; } - - // Initialize the PI controller for the trimmer heater - initializePIController( PI_CONTROLLER_ID_TRIMMER_HEATER, HEATERS_MIN_DUTY_CYCLE, TRIMMER_HEATER_P_COEFFICIENT, TRIMMER_HEATER_I_COEFFICIENT, - HEATERS_MIN_DUTY_CYCLE, HEATERS_MAX_DUTY_CYCLE ); // TODO remove? } /*********************************************************************//** @@ -193,7 +184,7 @@ // Check if the requested temperature is within the allowed range if ( ( targetTemperature >= MINIMUM_TARGET_TEMPERATURE ) && ( targetTemperature <= MAXIMUM_TARGET_TEMPERATURE ) ) { - heatersStatus[ heater ].originalTargetTemp = targetTemperature; + heatersStatus[ heater ].targetTemp = targetTemperature; heatersStatus[ heater ].hasTargetTempChanged = TRUE; // TODO alarm if temperature if out of range or just reject? } @@ -279,11 +270,11 @@ heatersStatus[ heater ].state = handleHeaterStateOff( heater ); break; - case HEATER_EXEC_STATE_RAMP_TO_TARGET: + case HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET: heatersStatus[ heater ].state = handleHeaterStateRampToTarget( heater ); break; - case HEATER_EXEC_STATE_CONTROL_TO_TARGET: + case HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET: heatersStatus[ heater ].state = handleHeaterStateControlToTarget( heater ); break; @@ -431,7 +422,7 @@ heatersStatus[ heater ].startHeaterSignal = FALSE; // Turn on the heater - state = HEATER_EXEC_STATE_RAMP_TO_TARGET; + state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; } return state; @@ -448,29 +439,26 @@ *************************************************************************/ static HEATERS_STATE_T handleHeaterStateRampToTarget( DG_HEATERS_T heater ) { - HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; + HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); F32 targetFlow = 0.0; F32 dutyCycle = 0.0; - F32 targetTemperature = heatersStatus[ heater ].originalTargetTemp; - F32 heaterEfficiency = heatersStatus[ heater ].heaterEfficiency; + F32 targetTemperature = heatersStatus[ heater ].targetTemp; if ( DG_MODE_FILL == getCurrentOperationMode() ) { // Get the previous fill's average flow rate targetFlow = getAvgFillFlowRate(); dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); - // Multiply the duty cycle to the heater efficiency - dutyCycle *= heaterEfficiency; - state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) || ( DG_MODE_DRAI == getCurrentOperationMode() ) ) { targetTemperature += DELTA_TEMPERATURE_TIME_COSNTANT_C; // Use target flow rate during Idle and drain targetFlow = getTargetROPumpFlowRate(); dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); - state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_HEAT == getCurrentOperationMode() ) || ( DG_MODE_CHEM == getCurrentOperationMode() ) ) { @@ -497,13 +485,13 @@ *************************************************************************/ static HEATERS_STATE_T handleHeaterStateControlToTarget( DG_HEATERS_T heater ) { - HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; // TODO do we need any control to maintain the temperature? if ( TRUE == haveHeaterControlConditionsChanged( heater ) ) { - state = HEATER_EXEC_STATE_RAMP_TO_TARGET; + state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; } return state; @@ -528,19 +516,19 @@ // Check if the heaters control conditions have changed, if yes, switch back to ramp to target if ( TRUE == haveHeaterControlConditionsChanged( heater ) ) { - state = HEATER_EXEC_STATE_RAMP_TO_TARGET; + state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; } // If the heat disifect sensor indicates that the temperature is below target temperature but the target temperature had been reached // before turn on the heaters with 100% power - if ( ( heatDisinfectSensorTemp <= heatersStatus[ heater ].originalTargetTemp ) && ( TRUE == heatersStatus[ heater ].hasTargetBeenReached ) ) + if ( ( heatDisinfectSensorTemp <= heatersStatus[ heater ].targetTemp ) && ( TRUE == heatersStatus[ heater ].hasTargetBeenReached ) ) { heatersStatus[ heater ].hasTargetBeenReached = FALSE; setHeaterDutyCycle( heater, HEATERS_MAX_DUTY_CYCLE ); } // If we have reached to target temperature, turn off the heaters - if ( heatDisinfectSensorTemp > heatersStatus[ heater ].originalTargetTemp ) + if ( heatDisinfectSensorTemp > heatersStatus[ heater ].targetTemp ) { // Set the flag to true for the next run heatersStatus[ heater ].hasTargetBeenReached = TRUE; @@ -587,9 +575,29 @@ *************************************************************************/ static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow ) { + // Get the primary heater's efficiency and the last fill temperature from the ModeFill + F32 heaterEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency; + F32 lastFillTemperature = getLastFillTemperature(); + + // If the last fill temperature > target temperature, it means the primary heater overshot the duty cycle + // so with its efficiency is toned down for the next fill cycle + // If the heater undershot the duty cycle, the efficiency increases the duty cycle for the next fill cycle + if ( lastFillTemperature - targetTemperature > MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) + { + heaterEfficiency -= ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } + else if ( lastFillTemperature - targetTemperature <= MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) + { + heaterEfficiency += ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } + + // Update the heaters efficiency + heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = heaterEfficiency; + // Duty cycle = ( 69.73 * flow rate * deltaT / primary heater maximum power ) ^ 1/2 + // Multiply the duty cycle to the heater efficiency F32 dutyCycle = sqrt( ( WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * - fabs( targetTemperature - currentTemperature ) * flow ) / PRIMARY_HEATERS_MAXIMUM_POWER_WATTS ); + fabs( targetTemperature - currentTemperature ) * flow ) / PRIMARY_HEATERS_MAXIMUM_POWER_WATTS ) * heaterEfficiency; // Check the boundaries of the calculated duty cycle dutyCycle = ( dutyCycle > HEATERS_MAX_DUTY_CYCLE ? HEATERS_MAX_DUTY_CYCLE : dutyCycle ); @@ -824,16 +832,7 @@ } } -static void checkHeaterOnStatus( DG_HEATERS_T heater ) -{ - if ( FALSE == heatersStatus[ heater ].isHeaterOn ) - { - setHeaterDutyCycle( heater, HEATERS_MIN_DUTY_CYCLE ); - //state = HEATER_EXEC_STATE_NOT_RUNNING; - } -} - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r752defbb739ea0756a8bf060f00bc6b9429c2764 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 752defbb739ea0756a8bf060f00bc6b9429c2764) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -644,7 +644,6 @@ // Get the pressure to use it for setting the control F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - if ( actualPressure >= targetROPumpMaxPressure ) { resetPIController( PI_CONTROLLER_ID_RO_PUMP_MAX_PRES, roPumpDutyCyclePctSet ); Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -40,39 +40,41 @@ // ********** private definitions ********** -#define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. -#define TARGET_RO_FLOW_RATE_L 0.8 ///< Target flow rate for RO pump. +#define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. +#define TARGET_RO_FLOW_RATE_L 0.8 ///< Target flow rate for RO pump. -#define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. -#define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. -///< Persistent time interval for concentrate pumps prime. -#define CONCENTRATE_PUMP_PRIME_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. +#define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. -#define ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER 1.06 ///< Acid and bicarbonate concentrates make up around 6% to total volume. -#define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1 ///< Flow integrated volume has 10% tolerance compare to load cell reading. +#define CONCENTRATE_PUMP_PRIME_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Persistent time interval for concentrate pumps prime. -#define CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN 5.0 ///< Concentrate pump additional speed during priming in mL/min. -#define CONCENTRATE_TEST_TIME_OUT_MS ( 45 * MS_PER_SECOND ) ///< Concentrate test time out period in ms. -#define WATER_QUALITY_CHECK_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Inlet water quality check time out period in ms. +#define ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER 1.06 ///< Acid and bicarbonate concentrates make up around 6% to total volume. +#define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1 ///< Flow integrated volume has 10% tolerance compare to load cell reading. -#define DIALYSATE_TEMPERATURE_TOLERANCE_C 2.0 ///< Dialysate temperature tolerance in degree C. +#define CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN 5.0 ///< Concentrate pump additional speed during priming in mL/min. +#define CONCENTRATE_TEST_TIME_OUT_MS ( 45 * MS_PER_SECOND ) ///< Concentrate test time out period in ms. +#define WATER_QUALITY_CHECK_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Inlet water quality check time out period in ms. -#define ACID_CONCENTRATION_BOTTLE_VOLUME_ML 3000.0 ///< Volume of acid concentration in ml. -#define BICARB_CONCENTRATION_BOTTLE_VOLUME_ML 3000.0 ///< Volume of bicarb concentration in ml. -#define CONCENTRATION_BOTTLE_LOW_VOLUME_ML 100.0 ///< Concentration bottle low volume in ml. +#define DIALYSATE_TEMPERATURE_TOLERANCE_C 2.0 ///< Dialysate temperature tolerance in degree C. +#define ACID_CONCENTRATION_BOTTLE_VOLUME_ML 3000.0 ///< Volume of acid concentration in ml. +#define BICARB_CONCENTRATION_BOTTLE_VOLUME_ML 3000.0 ///< Volume of bicarb concentration in ml. +#define CONCENTRATION_BOTTLE_LOW_VOLUME_ML 100.0 ///< Concentration bottle low volume in ml. + /// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. static const F32 FLOW_INTEGRATOR = ( (F32)TASK_GENERAL_INTERVAL / (F32)( SEC_PER_MIN * MS_PER_SECOND ) ); // ********** private data ********** +/// Fill conditions status typedef struct { F32 fillFlowRateRunningSum; ///< Fill flow running sum. U32 fillSampleCounter; ///< Fill flow sample counter. F32 fillTemperatureRunningSum; ///< Fill temperature running sum. F32 fillTemperatureAverage; ///< Fill temperature average value. F32 fillFlowRateAverage; ///< Fill flow average value. + F32 fillLastTemperature; ///< Fill last temperature value. } FILL_CONDITION_STATUS_T; static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. @@ -266,13 +268,26 @@ * @details Outputs: fillTemperatureAverage * @return average fill temperature *************************************************************************/ -F32 getAverageFillTemperature( void ) +F32 getAvgFillTemperature( void ) { return fillStatus.fillTemperatureAverage; } /*********************************************************************//** * @brief + * The getLastFillTemperature function returns the last fill temperature + * in each fill. + * @details Inputs: none + * @details Outputs: fillLastTemperature + * @return last fill temperature + *************************************************************************/ +F32 getLastFillTemperature( void ) +{ + return fillStatus.fillLastTemperature; +} + +/*********************************************************************//** + * @brief * The handleCheckInletWaterState function checks for inlet water quality * before jumping to dialysate production state. * @details Inputs: Temperature and conductivity alarms @@ -473,12 +488,12 @@ // Set concentrate pumps speed based off RO pump flow rate handleDialysateMixing( measuredROFlowRate_mL_min ); - totalROFlowRate_mL_min += measuredROFlowRate_mL_min; - integratedVolume_mL = totalROFlowRate_mL_min * FLOW_INTEGRATOR * ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER; - usedAcidVolume_mL.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; + totalROFlowRate_mL_min += measuredROFlowRate_mL_min; + integratedVolume_mL = totalROFlowRate_mL_min * FLOW_INTEGRATOR * ACID_BICARB_CONCENTRATE_ADDITION_MULTIPLER; + usedAcidVolume_mL.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; usedBicarbVolume_mL.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB ) * FLOW_INTEGRATOR; - acidConductivityTotal += acidConductivity; + acidConductivityTotal += acidConductivity; dialysateConductivityTotal += dialysateConductivity; conductivitySampleCount++; @@ -554,6 +569,8 @@ fillStatus.fillFlowRateRunningSum = 0.0; fillStatus.fillTemperatureRunningSum = 0.0; fillStatus.fillSampleCounter = 1; + // Get the last fill temperature before leaving to Generation Idle + fillStatus.fillLastTemperature = getTemperatureValue( (U32)TEMPSENSORS_OUTLET_PRIMARY_HEATER ); requestNewOperationMode( DG_MODE_GENE ); } @@ -599,7 +616,6 @@ return ( ( isInletPressureGood && isWaterTemperatureGood && isWaterConductivityGood ) ? TRUE : FALSE ); } - /*********************************************************************//** * @brief * The checkDialysateTemperature function checks dialysate temperature after @@ -610,13 +626,12 @@ *************************************************************************/ static BOOL checkDialysateTemperature( void ) { - F32 const dialysateTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 const targetTemp = getHeaterTargetTemperature( DG_PRIMARY_HEATER ); + F32 dialysateTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + F32 targetTemp = getHeaterTargetTemperature( DG_PRIMARY_HEATER ); return ( ( fabs( dialysateTemp - targetTemp ) <= DIALYSATE_TEMPERATURE_TOLERANCE_C ) ? TRUE : FALSE ); } - /*********************************************************************//** * @brief * The handleDialysateMixing function handles the dialysate mixing by setting Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -38,10 +38,12 @@ U32 execFillMode( void ); // execute the fill mode state machine (call from OperationModes) F32 getAvgFillFlowRate( void ); -void setAvgFillFlowRateToRTCRAM( void ); +void setAvgFillFlowRateToRTCRAM( void ); // TODO do we need this? -F32 getAvgFillTemperature( void ); +F32 getAvgFillTemperature( void ); // TODO do we need this? +F32 getLastFillTemperature( void ); + /**@}*/ #endif Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -16,8 +16,6 @@ * ***************************************************************************/ -#include "etpwm.h" - #include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "DrainPump.h" Index: firmware/App/Services/PIControllers.c =================================================================== diff -u -r033c0a8a34377fdc9a4d681877f7be1e103857f0 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 033c0a8a34377fdc9a4d681877f7be1e103857f0) +++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -63,7 +63,6 @@ { // Kp Ki uMax uMin ref meas err esw esum ctrl Ilimit controller type { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_RO_PUMP { 0.0, 0.0, 3000, 300, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, CONTROLLER_BIDIRECTIONAL }, // PI_CONTROLLER_ID_DRAIN_PUMP - { 0.0, 0.0, 0.50, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_TRIMMER_HEATER { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_RO_PUMP_MAX_PRES }; Index: firmware/App/Services/PIControllers.h =================================================================== diff -u -r033c0a8a34377fdc9a4d681877f7be1e103857f0 -r03e051ef654a1bff100da02483645c4e9d0b7a30 --- firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision 033c0a8a34377fdc9a4d681877f7be1e103857f0) +++ firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) @@ -35,7 +35,6 @@ { PI_CONTROLLER_ID_RO_PUMP_FLOW = 0, ///< RO Pump controller to flow PI_CONTROLLER_ID_DRAIN_PUMP, ///< Drain Pump controller - PI_CONTROLLER_ID_TRIMMER_HEATER, ///< Trimmer Heater controller PI_CONTROLLER_ID_RO_PUMP_MAX_PRES, ///< RO pump controller to maximum pressure NUM_OF_PI_CONTROLLERS_IDS ///< Number of PI controllers } PI_CONTROLLER_ID_T;