Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -ra3960210792d0811093a6913e505d43eda1918ea -r8a553b10a224c745cb4bd6d963c867391905ba8c --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision a3960210792d0811093a6913e505d43eda1918ea) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 8a553b10a224c745cb4bd6d963c867391905ba8c) @@ -87,20 +87,21 @@ /// Heaters data structure typedef struct { - F32 targetTemp; ///< Heater target temperature. + F32 targetTemp; ///< Heater target temperature. HEATERS_STATE_T state; ///< Heater state. BOOL startHeaterSignal; ///< Heater start indication flag. BOOL isHeaterOn; ///< Heater on/off status flag. - F32 dutycycle; ///< Heater duty cycle. - F32 targetROFlow; ///< Heater target flow. - U32 heaterOnWithNoFlowTimer; // TODO remove ///< Heater on with no flow timer. + F32 dutycycle; ///< Heater duty cycle. + F32 targetROFlow; ///< Heater target flow. + U32 heaterOnWithNoFlowTimer; // TODO remove ///< Heater on with no flow timer. BOOL isFlowBelowMin; ///< Heater flow below minimum flag indicator. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. - F32 heaterEfficiency; ///< Heater efficiency during the run. + F32 heaterEfficiency; ///< Heater efficiency during the run. BOOL hasTargetBeenReached; ///< Heater flag to indicate whether the target temperature has been reached. 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 + F32 temporaryInterimTemperature; ///< TODO remove } HEATER_STATUS_T; static HEATER_STATUS_T heatersStatus[ NUM_OF_DG_HEATERS ]; ///< Heaters status. @@ -327,8 +328,8 @@ { cmdResponse.rejected = FALSE; #ifndef DISABLE_HEATERS_AND_TEMPS - heatersStatus[ DG_TRIMMER_HEATER ].targetTemp = heaterCmdPtr->targetTemp; - heatersStatus[ DG_TRIMMER_HEATER ].startHeaterSignal = TRUE; + //heatersStatus[ DG_TRIMMER_HEATER ].targetTemp = heaterCmdPtr->targetTemp; DEBUG_DENALI + //heatersStatus[ DG_TRIMMER_HEATER ].startHeaterSignal = TRUE; #endif } else @@ -464,23 +465,24 @@ F32 targetFlow = 0.0; F32 dutyCycle = 0.0; F32 targetTemperature = heatersStatus[ heater ].targetTemp; + DG_OP_MODE_T opMode = getCurrentOperationMode(); - if ( DG_MODE_FILL == 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 = ( getAvgFillFlowRate() - 0.0 > NEARLY_ZERO ? getAvgFillFlowRate() : getTargetROPumpFlowRate() ); dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, TRUE ); state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } - else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) || ( DG_MODE_DRAI == getCurrentOperationMode() ) ) + else if ( ( DG_MODE_GENE == opMode ) || ( DG_MODE_DRAI == opMode ) ) { targetTemperature += DELTA_TEMPERATURE_TIME_COSNTANT_C; // Use target flow rate during Idle and drain targetFlow = getTargetROPumpFlowRate(); dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } - else if ( ( DG_MODE_HEAT == getCurrentOperationMode() ) || ( DG_MODE_CHEM == getCurrentOperationMode() ) ) + else if ( ( DG_MODE_HEAT == opMode ) || ( DG_MODE_CHEM == opMode ) ) { // If the mode is any of the disinfects, especially 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 81 C @@ -489,6 +491,10 @@ state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; } + // TODO remove + heatersStatus[ DG_PRIMARY_HEATER ].temporaryInterimTemperature = targetTemperature; + // TODO remove + setHeaterDutyCycle( heater, dutyCycle ); return state; @@ -571,32 +577,25 @@ HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET; DG_HEATERS_T heater = DG_TRIMMER_HEATER; F32 currentTemperature = 0.0; - F32 targetFlow = 0.35; // TODO get target dialysate flow from HD + F32 targetFlow = getTargetDialysateFlowLPM(); F32 dutyCycle = 0.0; F32 targetTemperature = heatersStatus[ heater ].targetTemp; + DG_OP_MODE_T opMode = getCurrentOperationMode(); - if ( DG_MODE_FILL == getCurrentOperationMode() ) + if ( ( DG_MODE_FILL == opMode ) || ( DG_MODE_GENE == opMode ) || ( DG_MODE_DRAI == opMode ) ) { currentTemperature = getReservoirActualTemperature(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, currentTemperature, targetFlow, TRUE ); + dutyCycle = calculateTrimmerHeaterDutyCycle( targetTemperature, currentTemperature, targetFlow, TRUE ); state = HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET; } - /*else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) || ( DG_MODE_DRAI == getCurrentOperationMode() ) ) + else if ( DG_MODE_HEAT == opMode ) { - targetTemperature += DELTA_TEMPERATURE_TIME_COSNTANT_C; - // Use target flow rate during Idle and drain - targetFlow = getTargetROPumpFlowRate(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); - state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; - }*/ // TODO do we need this else if for the trimmer heater - else if ( DG_MODE_HEAT == getCurrentOperationMode() ) - { // If the mode is heat disinfect, 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 81 C and // it is far from the inlet temperature. currentTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); targetFlow = getTargetROPumpFlowRate(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, currentTemperature, targetFlow, FALSE ); + dutyCycle = calculateTrimmerHeaterDutyCycle( targetTemperature, currentTemperature, targetFlow, FALSE ); state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; } @@ -667,7 +666,7 @@ // Get the primary heater's efficiency and the last fill temperature from the ModeFill F32 heaterEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency; - if ( TRUE == checkEfficiency ) + /*if ( TRUE == checkEfficiency ) { F32 lastFillTemperature = getLastFillTemperature(); @@ -685,7 +684,7 @@ // Update the heaters efficiency heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = heaterEfficiency; - } + }*/ // TODO bring this part back // Duty cycle = ( 69.73 * flow rate * deltaT / primary heater maximum power ) ^ 1/2 // Multiply the duty cycle to the heater efficiency @@ -699,18 +698,32 @@ return dutyCycle; } +/*********************************************************************//** + * @brief + * The calculateTrimmerHeaterDutyCycle function calculates the trimmer + * heater's duty cycle. + * @details Inputs: none + * @details Outputs: none + * @param targetTemperature target temperature of the heater + * @oaram currentTemperature current inlet temperature of the heater + * @param flow current flow + * @param check efficiency flag to indicate whether to consider heater's + * efficiency + * @return calculated duty cycle + *************************************************************************/ static F32 calculateTrimmerHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow, BOOL checkEfficiency ) { // Get the primary heater's efficiency and the last fill temperature from the ModeFill F32 heaterEfficiency = heatersStatus[ DG_TRIMMER_HEATER ].heaterEfficiency; + F32 dutyCycle = 0.0; if ( TRUE == checkEfficiency ) { // TODO add the trimmer efficiency } - F32 dutyCycle = flow * WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * ( targetTemperature - currentTemperature ) * heaterEfficiency; + dutyCycle = flow * WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * ( targetTemperature - currentTemperature ) * heaterEfficiency; // Check the boundaries of the calculated duty cycle dutyCycle = ( dutyCycle > HEATERS_MAX_DUTY_CYCLE ? HEATERS_MAX_DUTY_CYCLE : dutyCycle ); @@ -732,7 +745,7 @@ static BOOL haveHeaterControlConditionsChanged( DG_HEATERS_T heater ) { BOOL status = FALSE; - F32 targetFlow = getTargetROPumpFlowRate(); + F32 targetFlow = getTargetROPumpFlowRate(); BOOL hasFlowChanged = ( fabs( targetFlow - heatersStatus[ heater ].targetROFlow ) > NEARLY_ZERO ? TRUE : FALSE ); // Check if the target flow has changed or the target temperature has changed. @@ -812,6 +825,11 @@ data.trimmerHeaterState = heatersStatus[ DG_TRIMMER_HEATER ].state; data.primaryEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency * 100; + data.dialysateTargetLPM = getTargetDialysateFlowLPM(); + data.interimTargetTemp = heatersStatus[ DG_PRIMARY_HEATER ].temporaryInterimTemperature; + data.targetHeaterFlowLPM = heatersStatus[ DG_PRIMARY_HEATER ].targetROFlow; + + broadcastData( MSG_ID_DG_HEATERS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( HEATERS_DATA_T ) ); dataPublicationTimerCounter = 0;