Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -rbe4507c7fef6c9d987eba9e34369402e989e962e -r44222e803e04d057ab793ce6b72902b8bfe9b7d0 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision be4507c7fef6c9d987eba9e34369402e989e962e) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 44222e803e04d057ab793ce6b72902b8bfe9b7d0) @@ -52,10 +52,6 @@ #define MAX_REDUNDANT_LOAD_CELL_DIFF 50.0 ///< Maximum difference in redundant load cells when determining if fill completed. -#define RESERVOIR_TEMPERATURE_TAU_C_PER_MIN -0.512 ///< Reservoir temperature time constant C/min. -#define ULTRAFILTER_TEMPERATURE_TAU_C_PER_MIN -4.565 ///< Ultrafilter temperature time constant C/min. -#define ULTRAFILTER_VOLUME_ML 700 ///< Ultrafilter volume in milliliters. - // ********** private data ********** /// Heaters temperature calculation data structure @@ -77,7 +73,7 @@ static U32 reservoirDataPublicationTimerCounter = 0; ///< used to schedule reservoir data publication to CAN bus. static OVERRIDE_U32_T activeReservoir = { 0, 0, 0, 0 }; ///< The active reservoir that the DG is filling/draining/etc. -static OVERRIDE_U32_T fillVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir fill volume (in mL). +static OVERRIDE_U32_T fillVolumeTargetMl = { 0, 0, 0, 0 }; // TODO is this needed with NV Data? ///< The target reservoir fill volume (in mL). static OVERRIDE_U32_T drainVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir drain volume (in mL). @@ -91,15 +87,10 @@ static U32 reservoirWeightUnchangeStartTime[ NUM_OF_DG_RESERVOIRS ] = { 0, 0 }; ///< The reservoirs' weight start time when weight stop decreasing. static BOOL tareLoadCellRequest; ///< Flag indicates if load cell tare has been requested by HD. static DG_RESERVOIR_VOLUME_RECORD_T reservoirsCalRecord; ///< DG reservoirs non-volatile record. +static DG_HEATING_CAL_RECORD_T heatingConstsCalRecord; ///< DG heating calibration record. static F32 targetFillFlowRateLPM; ///< Target fill flow rate in L/min. static BOOL isThisTheFirstCycle = TRUE; ///< Boolean flag to indicate whether this is the first cycle. -/// Conversion of ultrafilter tau in C/min to C/ms. -static const F32 ULTRAFILTER_TAU_C_PER_MS = ULTRAFILTER_TEMPERATURE_TAU_C_PER_MIN / ( SEC_PER_MIN * MS_PER_SECOND ); - -/// Conversion of reservoir tau in C/min to C/ms. -static const F32 RESERVOIR_TAU_C_PER_MS = RESERVOIR_TEMPERATURE_TAU_C_PER_MIN / ( SEC_PER_MIN * MS_PER_SECOND ); - /*********************************************************************//** * @brief * The initReservoirs function initializes the Reservoirs module. @@ -121,7 +112,8 @@ * @brief * The execReservoirs function manages periodic tasks for the Reservoirs module. * @details Inputs: reservoirDataPublicationTimerCounter - * @details Outputs: reservoirDataPublicationTimerCounter + * @details Outputs: reservoirDataPublicationTimerCounter, heatingCalRecord, + * reservoirsCalRecord * @return none *************************************************************************/ void execReservoirs( void ) @@ -132,6 +124,9 @@ // Get the new calibration data and check its validity getNVRecord2Driver( GET_CAL_RSRVRS_VOL_RECORD, (U08*)&reservoirsCalRecord, sizeof( reservoirsCalRecord ), NUM_OF_CAL_DATA_RSRVRS, ALARM_ID_DG_RESERVOIRS_INVALID_CAL_RECORD ); + + getNVRecord2Driver( GET_CAL_HEATING_RECORD, (U08*)&heatingConstsCalRecord, sizeof( heatingConstsCalRecord ), + NUM_OF_CAL_DATA_RSRVRS, ALARM_ID_DG_HEATING_INVALID_CAL_RECORD ); } // publish active reservoir, fill/drain volume targets at 1 Hz. @@ -167,10 +162,14 @@ SELF_TEST_STATUS_T execReservoirsSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + BOOL calStatus = FALSE; - BOOL calStatus = getNVRecord2Driver( GET_CAL_RSRVRS_VOL_RECORD, (U08*)&reservoirsCalRecord, sizeof( reservoirsCalRecord ), - NUM_OF_CAL_DATA_RSRVRS, ALARM_ID_DG_RESERVOIRS_INVALID_CAL_RECORD ); + calStatus |= getNVRecord2Driver( GET_CAL_RSRVRS_VOL_RECORD, (U08*)&reservoirsCalRecord, sizeof( reservoirsCalRecord ), + NUM_OF_CAL_DATA_RSRVRS, ALARM_ID_DG_RESERVOIRS_INVALID_CAL_RECORD ); + calStatus |= getNVRecord2Driver( GET_CAL_HEATING_RECORD, (U08*)&heatingConstsCalRecord, sizeof( heatingConstsCalRecord ), + NUM_OF_CAL_DATA_RSRVRS, ALARM_ID_DG_HEATING_INVALID_CAL_RECORD ); + if ( TRUE == calStatus ) { result = SELF_TEST_STATUS_PASSED; @@ -572,20 +571,22 @@ F32 targetFillVolML = getTargetFillVolumeML(); F32 tempLastFill = getLastFillTemperature(); F32 tempAvgFill = getAvgFillTemperature(); + F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 RsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); // Only do the calculations if the fill volume is not 0.0 so the final value will not be a nan. if ( targetFillVolML > NEARLY_ZERO ) { heatersTempCalc.timeUFDecayMS = (F32)heatersTempCalc.timeReservoirCycleMS - heatersTempCalc.timeReservoirFillMS; - UFTimeConstant = heatersTempCalc.timeUFDecayMS * ULTRAFILTER_TAU_C_PER_MS; + UFTimeConstant = heatersTempCalc.timeUFDecayMS * UFTauCPerMS; heatersTempCalc.tempUFFill = tempLastFill + UFTimeConstant; - F32 ultrafilterPart = ( ULTRAFILTER_VOLUME_ML / targetFillVolML ) * heatersTempCalc.tempUFFill; - F32 fillPart = ( ( targetFillVolML - ULTRAFILTER_VOLUME_ML ) / targetFillVolML ) * tempAvgFill; + F32 ultrafilterPart = ( heatingConstsCalRecord.ultrafilterVolmL / targetFillVolML ) * heatersTempCalc.tempUFFill; + F32 fillPart = ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ) * tempAvgFill; F32 tempReservoir0Actual = ultrafilterPart + fillPart; - F32 tempReservoirEndfillActual = tempReservoir0Actual + ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RESERVOIR_TAU_C_PER_MS ); - heatersTempCalc.tempReservoirUseActual = tempReservoirEndfillActual + ( heatersTempCalc.timeReservoirFill2SwitchMS * RESERVOIR_TAU_C_PER_MS ); + F32 tempReservoirEndfillActual = tempReservoir0Actual + ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RsrvrTauCPerMS ); + heatersTempCalc.tempReservoirUseActual = tempReservoirEndfillActual + ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); } else { @@ -610,6 +611,8 @@ F32 targetFillVolML = getTargetFillVolumeML(); F32 UFTimeConstant = 0.0; F32 tempLastFill = getLastFillTemperature(); + F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 RsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); if ( FALSE == isThisTheFirstFill() ) { @@ -618,15 +621,15 @@ F32 tempReservoirUse; tempReservoirUse = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; - heatersTempCalc.tempReservoirEndFill = tempReservoirUse - ( heatersTempCalc.timeReservoirFill2SwitchMS * RESERVOIR_TAU_C_PER_MS ); - heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RESERVOIR_TAU_C_PER_MS ); + heatersTempCalc.tempReservoirEndFill = tempReservoirUse - ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); + heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RsrvrTauCPerMS ); heatersTempCalc.timeUFDecayMS = (F32)heatersTempCalc.timeReservoirCycleMS - heatersTempCalc.timeReservoirFillMS; - UFTimeConstant = heatersTempCalc.timeUFDecayMS * ULTRAFILTER_TAU_C_PER_MS; + UFTimeConstant = heatersTempCalc.timeUFDecayMS * UFTauCPerMS; heatersTempCalc.tempUFFill = tempLastFill + UFTimeConstant; - tempTargetNumerator = heatersTempCalc.tempReservoir0 - ( ( ULTRAFILTER_VOLUME_ML / targetFillVolML ) * heatersTempCalc.tempUFFill ); - targetTempDenominator = ( ( targetFillVolML - ULTRAFILTER_VOLUME_ML ) / targetFillVolML ); + tempTargetNumerator = heatersTempCalc.tempReservoir0 - ( ( heatingConstsCalRecord.ultrafilterVolmL / targetFillVolML ) * heatersTempCalc.tempUFFill ); + targetTempDenominator = ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ); tempTarget = tempTargetNumerator / targetTempDenominator; } else