Files
CHJ/user/Compute/Correct.c

284 lines
8.3 KiB
C
Raw Normal View History

2026-03-20 21:16:58 +08:00
#include "../main/SystemInclude.h"
//==============================================================================
u32 dcoefNode[DCOEF_MAX];
u16 dcoef, dcoefVal[DCOEF_MAX];
float GCFParaA, GCFParaB, GCFParaC;
2026-03-20 21:19:04 +08:00
u16 MeterFactor,GCFCoefB;
2026-03-20 21:16:58 +08:00
s32 GCFCoefA, GCFCoefC;
float GCFParaA, GCFParaB, GCFParaC;
//u16 dcoefNum;
//******************************************************************************
// Routines for device coefficients
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽ڵ<DFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
void StoreDevCoefNodeAndValue(unsigned char I)
{
tempL.DWord= dcoefNode[I];
tempDev.Word[2] = tempL.Word[1];
tempDev.Word[1] = tempL.Word[0];
tempDev.Word[0] = dcoefVal[I];
2026-03-20 21:19:04 +08:00
WriteParameterToEEPROM(DCOEF_BASE+I*DCOEF_WIDTH, DCOEF_WIDTH);
2026-03-20 21:16:58 +08:00
}
//******************************************************************************
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽ڵ<DFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
bool ReadDevCoefNodeAndValue(unsigned char I)
{
2026-03-20 21:19:04 +08:00
ReadMultiByteFromEEPROM(DCOEF_BASE + I * DCOEF_WIDTH, tempDev.Byte, DCOEF_WIDTH, PARA_EEPROM);
2026-03-20 21:16:58 +08:00
if(tempDev.Byte[DCOEF_CRC] == CRC8(tempDev.Byte, DCOEF_CRC))
{
tempDev.Byte[DCOEF_CRC] = 0;
dcoefVal[I] = tempDev.Word[0];
tempL.Word[0] = tempDev.Word[1];
tempL.Word[1] = tempDev.Word[2];
dcoefNode[I] = tempL.DWord;
return 0;
}
else
{
dcoefNode[I] = 0;
dcoefVal[I] = 0;
return 1;
}
}
//******************************************************************************
//Ĭ<>ϵĶ<CFB5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD>
void DefaultDevCoef(void)
{
unsigned char I;
//u32 flowRateMax;
dcoefNode[0] = (maxFlowRate * 1) / 100; // 1% 1028
dcoefNode[1] = 1000;
dcoefNode[2] = (maxFlowRate * 10) / 100; // 10%
//dcoefNode[3] = (maxFlowRate * 20) / 100;
//dcoefNode[4] = (maxFlowRate * 40) / 100;
dcoefNode[3] = maxFlowRate >> 1; // 50%
dcoefNode[4] = maxFlowRate; // 100%
if(dcoefNode[0] < 500) dcoefNode[0] = 500;
if(dcoefNode[1] <= dcoefNode[0]) dcoefNode[1] = (maxFlowRate * 5) / 100; //dcoefNode[1] = (dcoefNode[0] + dcoefNode[2])>>1;
if(dcoefNode[2] <= dcoefNode[1]) dcoefNode[2] = (dcoefNode[1] + dcoefNode[3]) >> 1;
if(dcoefNode[3] <= dcoefNode[2]) dcoefNode[3] = (dcoefNode[2] + dcoefNode[4]) >> 1;
dcoefNum = 5;
tempL.Byte[0] = dcoefNum;
2026-03-20 21:19:04 +08:00
WriteShortParameterToEEPROM(DCOEF_NUM, DCOEF_NUM_WIDTH);
2026-03-20 21:16:58 +08:00
for (I = 0; I < dcoefNum; I++)
{
dcoefVal[I] = METER_PARAMETER_DEFAULT;
//dcoefNode[I] = ConvertFlowrate(dcoefNode[I]);
StoreDevCoefNodeAndValue(I);
}
}
//******************************************************************************
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD>
void RetriveDevCoef(void)
{
2026-03-20 21:19:04 +08:00
unsigned char I;
2026-03-20 21:16:58 +08:00
// u32 flowRateMax;
2026-03-20 21:19:04 +08:00
ReadMultiByteFromEEPROM(DCOEF_NUM, tempL.Byte, DCOEF_NUM_WIDTH, PARA_EEPROM);
if(tempL.Byte[1] != CRC8(tempL.Byte, 1)) goto RetResetDevCoef;
2026-03-20 21:16:58 +08:00
dcoefNum = tempL.Byte[0];
if((dcoefNum > DCOEF_MAX)||(dcoefNum < 3)) goto RetResetDevCoef;
if(ReadDevCoefNodeAndValue(0)) goto RetResetDevCoef;
for (I = 1; I < dcoefNum; I++)
{
if(ReadDevCoefNodeAndValue(I)) goto RetResetDevCoef;
if(dcoefNode[I] <= dcoefNode[I-1]) goto RetResetDevCoef;
// if(dcoefNode[I] > flowRateMax) goto RetResetDevCoef;
}
return;
RetResetDevCoef:
DefaultDevCoef();
return;
}
//******************************************************************************
void JudgeDevCoef(void)
{
u16 I;
for (I = 1; I < dcoefNum; I++)
{
if(dcoefNode[I] <= dcoefNode[I-1]) { RetriveDevCoef(); return; }
}
}
//******************************************************************************
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
u16 GetDevCoefFactor(u32 dcoefFlowRate)
{
// u32 tmp;
u16 nodeVal = METER_PARAMETER_DEFAULT;
u32 nodeFR = 0;
unsigned char I;
for(I = 0; I < dcoefNum; I++)
{
if(dcoefNode[I] < dcoefFlowRate) continue;
if(I != 0)
{
nodeVal = dcoefVal[I-1];
nodeFR = dcoefNode[I-1];
}
tmpSLA = (u32)dcoefVal[I];
tmpSLA -= (u32)nodeVal;
tmpSLB = (u32)dcoefFlowRate;
tmpSLB -= (u32)nodeFR;
tmpSLA *= tmpSLB;
tmpSLB = (u32)dcoefNode[I];
tmpSLB -= (u32)nodeFR;
tmpSLA /= tmpSLB;
tmpSLA += (u32)nodeVal;
return (u16)tmpSLA;
}
return dcoefVal[dcoefNum-1];
}
//******************************************************************************
// Routines for calculating the following expression without overflow:
u32 CorrectionExpression(u32 target, u16 factor, u16 base)
{
float tempF;
tempF = (float)target;
#ifndef CORRECT_METHOD
#pragma message("[undefined] CORRECT_METHOD")
#elif(CORRECT_METHOD)
tempF *= (float)base;
tempF /= (float)factor;
#else
tempF /= (float)base;
tempF *= (float)factor;
#endif
return (u32)tempF;
}
//******************************************************************************
void GCFCorrection(void)
{
if(currentMode.Bit.CalibMode) return;
//----------------------------------------------------------------------------
#ifndef ENABLE_GAS_RECOGNITION
#pragma message("[undefined] ENABLE_GAS_RECOGNITION")
#elif(ENABLE_GAS_RECOGNITION)
//FY if(!isCurrentGas) return;
#endif
//----------------------------------------------------------------------------
float floatA, floatB;
//----------------------------------------------------------------------------
#ifndef ENABLE_A_TYPE_FLOWRATE
#pragma message("[undefined] ENABLE_A_TYPE_FLOWRATE")
#elif(ENABLE_A_TYPE_FLOWRATE)
if(FRType == ATYPE_FR)
{
floatA = (float)GDCFactorAType;
floatA *= (float)currentFlowRate;
floatA /= (float)GCF_PARAMETER_STD;
currentFlowRate = (u32)floatA;
return;
}
#endif
//----------------------------------------------------------------------------
#ifndef ENABLE_GCF_POWER_CORR
#pragma message("[undefined] ENABLE_GCF_POWER_CORR")
#elif(ENABLE_GCF_POWER_CORR)
// Power function correction
// GCF
if(GCFCoefC == 0)
{
floatB = (float)currentFlowRate;
floatB = (float)GCFParaB;
}
else
{
floatA = GCFParaC; // GCFParaC : area m2
floatB = (float)currentFlowRate;
if(FR_STD_UNIT == SL) floatA *= 60000000; // 0000SLPM - 0.000 m3/s (3bit): (FR/1000)
else floatA *= 3600000; // 0000m3/H - 0.000 m3/s (3bit): (FR/1000)
floatA = floatB/floatA; // 0.000 m/s
floatA = pow(floatA, GCFParaA); // compute GCF
floatA *= GCFParaB;
floatB *= floatA;
}
currentFlowRate = (u32)floatB;
#else
// Quadratic correction coefficient
// GCF
floatB = (float)currentFlowRate;
floatA = floatB * floatB;
floatA *= (float)GCFParaA;
floatB *= (float)GCFParaB;
floatA += floatB;
floatA += (float)GCFParaC;
currentFlowRate = (u32)floatA;
#endif
}
//******************************************************************************
void FlowRateSecondaryCorrection(void)
{
// retrieve the GDCF factor & device coefficients
// account in the GDCF factor & device coefficients
#ifndef ENABLE_DCOEF
#pragma message("[undefined] ENABLE_DCOEF")
#elif(ENABLE_DCOEF)
if(HWState.EnableCheckCorr) JudgeDevCoef();
//----------------------------------------------------------------------------
#ifndef ENABLE_FLOW_GAIN
#pragma message("[undefined] ENABLE_FLOW_GAIN")
#elif(ENABLE_FLOW_GAIN)
dcoef = GetDevCoefFactor(currentFlowRate/(u32)calibFlowGain);
#else
dcoef = GetDevCoefFactor(currentFlowRate);
#endif
//----------------------------------------------------------------------------
currentFlowRate = CorrectionExpression(currentFlowRate, dcoef, METER_PARAMETER_STD);
#endif
currentFlowRate = CorrectionExpression(currentFlowRate, MeterFactor, METER_PARAMETER_STD);
}
/******************************************************************************/
void ComputeGCFFactor(void)
{
// Quadratic correction coefficient
// GCF
GCFParaA = (float)GCFCoefA;
GCFParaA /= (float)GCF_A_DOT;
GCFCoefB = GDCFactor;
GCFParaB = (float)GCFCoefB;
GCFParaB /= (float)GCF_B_DOT;
GCFParaC = (float)GCFCoefC;
GCFParaC /= (float)GCF_C_DOT;
}