NULL
This commit is contained in:
363
user/Compute/FlowRateCompute.c
Executable file
363
user/Compute/FlowRateCompute.c
Executable file
@@ -0,0 +1,363 @@
|
||||
#include "../main/SystemInclude.h"
|
||||
//==============================================================================
|
||||
#define FR_FILTER_MAX 8
|
||||
#define FR_FILTER_SHIFT 3
|
||||
#define FR_FILTER_MASK (FR_FILTER_MAX-1)
|
||||
|
||||
u32 flowSample[8], DisSample[8];
|
||||
u16 FIndexSample[8];
|
||||
u16 DisIndex, FRIndex, FIndex, filterShift, dataMask, filterDepth;
|
||||
u32 maxAlarmFlowRate;
|
||||
|
||||
#ifndef ENABLE_LEAK_DETECT
|
||||
#pragma message("[undefined] ENABLE_LEAK_DETECT")
|
||||
#elif(ENABLE_LEAK_DETECT)
|
||||
u16 leakDetectLowCounter, leakDetectHighCounter, leakDetectCounter;
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
u32 GetFlowRate(u16 flowIndex, u16 curveType)
|
||||
{
|
||||
u16 indexL, dataCompFac;
|
||||
u8 temp[12];
|
||||
switch(curveType)
|
||||
{
|
||||
case CURVE_1ST:
|
||||
if(flowIndex > 32767) return 0;
|
||||
else if(flowIndex < zeroSuppression) return 0;
|
||||
else if(flowIndex >= CALIB_MAX_INDEX) flowIndex = CALIB_MAX_INDEX;
|
||||
dataCompFac = CALIB_COMP_FAC;
|
||||
indexL = CALI_DATA_ADDR;
|
||||
break;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef ENABLE_2ND_CURVE
|
||||
#pragma message("[undefined] ENABLE_2ND_CURVE")
|
||||
#elif(ENABLE_2ND_CURVE)
|
||||
case CURVE_2ND:
|
||||
dataCompFac = CALIB_COMP_FAC2;
|
||||
indexL = CALI_DATA2_ADDR;
|
||||
break;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef ENABLE_3RD_CURVE
|
||||
#pragma message("[undefined] ENABLE_3RD_CURVE")
|
||||
#elif(ENABLE_3RD_CURVE)
|
||||
case CURVE_3RD:
|
||||
if(flowIndex > 32767) return 0;
|
||||
else if(flowIndex < zeroSuppression) return 0;
|
||||
else if(flowIndex >= CALIB_MAX_INDEX3) flowIndex = CALIB_MAX_INDEX;
|
||||
dataCompFac = CALIB_COMP_FAC3;
|
||||
indexL = CALI_DATA3_ADDR;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
//240000-3*4 2*4096*6=48828-6*4
|
||||
if(flowIndex > (CALIB_MAX_INDEX - dataCompFac*4)) {
|
||||
indexL += (CALIB_MAX_INDEX / dataCompFac - 1)*3;
|
||||
ReadCalbrationDataFromMemory(indexL, &tempDev.Byte[0], 3);
|
||||
|
||||
tempDev.Byte[3] = 0;
|
||||
return tempDev.DWord[0];
|
||||
}
|
||||
|
||||
u16 index0, indexD, IndexA, IndexB, J=0, K;
|
||||
u32 tempFR[4];
|
||||
//u32
|
||||
|
||||
index0 = flowIndex / dataCompFac;
|
||||
indexL += index0*3;
|
||||
|
||||
ReadCalbrationDataFromMemory(indexL-3, temp, 12);
|
||||
|
||||
tmpLA = 0;
|
||||
tmpLB = 0xffffffff;
|
||||
for(K=0, J=0; K<4; K++) {
|
||||
tempL.Byte[0] = temp[J++];
|
||||
tempL.Byte[1] = temp[J++];
|
||||
tempL.Byte[2] = temp[J++];
|
||||
tempL.Byte[3] = 0;
|
||||
tempFR[K] = tempL.DWord;
|
||||
|
||||
if(tempL.DWord > tmpLA) {
|
||||
tmpLA = tempL.DWord;
|
||||
IndexA = K;
|
||||
}
|
||||
|
||||
if(tempL.DWord < tmpLB) {
|
||||
tmpLB = tempL.DWord;
|
||||
IndexB = K;
|
||||
}
|
||||
}
|
||||
|
||||
for(K=0, J=0; K<4; K++) {
|
||||
if(K == IndexA) continue;
|
||||
if(K == IndexB) continue;
|
||||
temp[J] = K;
|
||||
J++;
|
||||
}
|
||||
|
||||
IndexA = temp[0];
|
||||
IndexB = temp[1];
|
||||
|
||||
tmpSLA = (u32)tempFR[IndexA];
|
||||
tmpSLB = (u32)tempFR[IndexB];
|
||||
IndexB = (IndexB - IndexA)*dataCompFac;
|
||||
IndexA *= dataCompFac;
|
||||
|
||||
// (tmpLB-tmpLA)*indexD/dataCompFac + tmpLA
|
||||
indexD = flowIndex - index0 * dataCompFac;
|
||||
indexD += dataCompFac;
|
||||
|
||||
tmpSLB -= tmpSLA;
|
||||
if(indexD > IndexA) {
|
||||
tmpSLB *= (u32)(indexD-IndexA);
|
||||
tmpSLB /= (u32)IndexB;
|
||||
tmpSLA += tmpSLB;
|
||||
}
|
||||
else {
|
||||
tmpSLB *= (u32)(IndexA-indexD);
|
||||
tmpSLB /= (u32)IndexB;
|
||||
tmpSLA -= tmpSLB;
|
||||
}
|
||||
|
||||
if(tmpSLA < 0) return 0;
|
||||
else return (u32)tmpSLA;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
u16 HalfWordMovingAverage(u16 *TPFilter, u16 shiftCompare, u16 updateScale)
|
||||
{
|
||||
u16 I, tempDelta;
|
||||
|
||||
//for(I=0; I<sumLen; I++) tempSum += (u32)*TPFilter++;
|
||||
//return tempSum >> shiftBit;
|
||||
|
||||
tmpLA = 0;
|
||||
for(I=0; I<filterDepth; I++) tmpLA += (u32)*(TPFilter+I);
|
||||
tmpIA = (u16)(tmpLA >> filterShift);
|
||||
|
||||
if(shiftCompare > tmpIA) tempDelta = shiftCompare - tmpIA;
|
||||
else tempDelta = tmpIA - shiftCompare;
|
||||
|
||||
tmpLA = (u32)tmpIA;
|
||||
tmpLA *= (u32)updateScale;
|
||||
tmpLA >>= 10;
|
||||
|
||||
if(tempDelta < (u16)tmpLA) return tmpIA;
|
||||
for(I=0; I<filterDepth; I++) *TPFilter++ = shiftCompare;
|
||||
|
||||
return shiftCompare;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
u32 WordMovingAverage(u32 *TPFilter, u32 shiftCompare, u16 updateScale)
|
||||
{
|
||||
u16 I;
|
||||
u32 tempDelta;
|
||||
|
||||
tmpLA = 0;
|
||||
for(I=0; I<filterDepth; I++) tmpLA += (u32)*(TPFilter+I);
|
||||
tmpLA >>= filterShift;
|
||||
|
||||
if(shiftCompare > tmpLA) tempDelta = shiftCompare - tmpLA;
|
||||
else tempDelta = tmpLA - shiftCompare;
|
||||
|
||||
tmpLB = (u32)tmpLA;
|
||||
tmpLB *= (u32)updateScale;
|
||||
tmpLB >>= 10;
|
||||
|
||||
if(tempDelta < (u16)tmpLB) return tmpLA;
|
||||
for(I=0; I<filterDepth; I++) *TPFilter++ = shiftCompare;
|
||||
|
||||
return shiftCompare;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void GetFilterDepth(u16 timeIndex)
|
||||
{
|
||||
filterDepth = FilterMax[timeIndex] / FilterMax[samplingInterval];
|
||||
switch(filterDepth)
|
||||
{
|
||||
case 1: filterShift = 0; break;
|
||||
case 2: filterShift = 1; break;
|
||||
case 4: filterShift = 2; break;
|
||||
case 8: filterShift = 3; break;
|
||||
case 16: filterShift = 4; break;
|
||||
case 32: filterShift = 5; break;
|
||||
default:
|
||||
filterDepth = 1;
|
||||
filterShift = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
dataMask = filterDepth-1;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
u16 FlowRateIndexFilter(u16 filterANX, u16 updateScale)
|
||||
{
|
||||
FIndex++;
|
||||
FIndex &= dataMask;
|
||||
FIndexSample[FIndex] = voltageDetected[filterANX];
|
||||
|
||||
return HalfWordMovingAverage(&FIndexSample[0], voltageDetected[filterANX], updateScale);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void FlowRateMoving(void)
|
||||
{
|
||||
FRIndex++;
|
||||
FRIndex &= dataMask;
|
||||
flowSample[FRIndex] = flowRate;
|
||||
flowRate = WordMovingAverage(&flowSample[0], flowRate, FLOWRATE_UPDATE_SCALE); // 1.5%
|
||||
|
||||
#ifndef ENABLE_LCD_DISPLAY
|
||||
#pragma message("[undefined] ENABLE_LCD_DISPLAY")
|
||||
#elif(ENABLE_LCD_DISPLAY)
|
||||
GetFilterDepth(DISPLAY_FILTER_DEFAULT);
|
||||
DisIndex++;
|
||||
DisIndex &= dataMask;
|
||||
DisSample[DisIndex] = displayUpdate;
|
||||
displayUpdate = WordMovingAverage(&DisSample[0], displayUpdate, FLOWRATE_UPDATE_SCALE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void CurrentFlowRateMoving(void)
|
||||
{
|
||||
FRIndex++;
|
||||
FRIndex &= dataMask;
|
||||
flowSample[FRIndex] = currentFlowRate;
|
||||
currentFlowRate = WordMovingAverage(&flowSample[0], currentFlowRate, FLOWRATE_UPDATE_SCALE); // 1.5%
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void DisplayFlowRateMoving(void)
|
||||
{
|
||||
GetFilterDepth(DISPLAY_FILTER_DEFAULT);
|
||||
DisIndex++;
|
||||
DisIndex &= dataMask;
|
||||
DisSample[DisIndex] = displayUpdate;
|
||||
displayUpdate = WordMovingAverage(&DisSample[0], displayUpdate, FLOWRATE_UPDATE_SCALE);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void FlowRateAlarmJudgment(void)
|
||||
{
|
||||
u32 minAlarmFlowRate;
|
||||
unsigned long long int alarmFlowRate;
|
||||
|
||||
// float tempFlow;
|
||||
//maxFlowRate = 3500000;
|
||||
// tempFlow = (float)maxFlowRate;
|
||||
// tempFlow *= (float)MAX_ALRAM_FR_DEFAULT;
|
||||
// maxAlarmFlowRate = (u32)tempFlow;
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Уʱ<D7BC><CAB1><EFBFBD><EFBFBD><EFBFBD>ķŴ<C4B7><C5B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
//maxAlarmFlowRate = maxFlowRate;
|
||||
//maxAlarmFlowRate *= (u32)MAX_ALRAM_FR_DEFAULT; // 1.25*128 = 160;
|
||||
//maxAlarmFlowRate >>= 7;
|
||||
|
||||
alarmFlowRate = (unsigned long long int)maxFlowRate;
|
||||
alarmFlowRate *= (unsigned long long int)MAX_ALRAM_FR_DEFAULT;
|
||||
alarmFlowRate >>= 7;
|
||||
maxAlarmFlowRate = (u32)alarmFlowRate;
|
||||
minAlarmFlowRate = minFlowRate;
|
||||
|
||||
//===========================================================================
|
||||
#ifndef ENABLE_FLOW_GAIN
|
||||
#pragma message("[undefined] ENABLE_FLOW_GAIN")
|
||||
#elif(ENABLE_FLOW_GAIN)
|
||||
maxAlarmFlowRate *= calibFlowGain;
|
||||
minAlarmFlowRate *= calibFlowGain;
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
systemAlarm.Bit.FRAlarm = 0;
|
||||
if(currentFlowRate > maxAlarmFlowRate) //1.25Qmax
|
||||
{
|
||||
systemAlarm.Bit.FRAlarm = 1;
|
||||
currentFlowRate = maxAlarmFlowRate;
|
||||
}
|
||||
else if(currentFlowRate < minAlarmFlowRate) currentFlowRate = 0; // V2004
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
#ifndef ENABLE_LEAK_DETECT
|
||||
#pragma message("[undefined] ENABLE_LEAK_DETECT")
|
||||
#elif(ENABLE_LEAK_DETECT)
|
||||
void FlowRateLeakDetect(void)
|
||||
{
|
||||
if((alarmState1 & LEAK_ALARM)== LEAK_ALARM)
|
||||
{
|
||||
leakDetectCounter = 0;
|
||||
leakDetectHighCounter = 0;
|
||||
leakDetectLowCounter = 0;
|
||||
#ifndef ENABLE_ERROR_PIN_FOR_VALVE_CONTROL
|
||||
#pragma message("[undefined] ENABLE_ERROR_PIN_FOR_VALVE_CONTROL")
|
||||
#elif(ENABLE_ERROR_PIN_FOR_VALVE_CONTROL)
|
||||
ERROR_PIN_OUTPUT();
|
||||
TURN_OFF_VALVE();
|
||||
alarmState1 |= VALVE_OFF_ALARM;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// if((leakDetectTime == 0) || (sampleState.EnableRoughTest))
|
||||
// {
|
||||
// leakDetectCounter = 0;
|
||||
// leakDetectHighCounter = 0;
|
||||
// leakDetectLowCounter = 0;
|
||||
// return;
|
||||
// }
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
if(flowRate < minLeakFlowRate)
|
||||
{
|
||||
leakDetectLowCounter++;
|
||||
leakDetectHighCounter = 0;
|
||||
if(leakDetectLowCounter > 4)
|
||||
{
|
||||
leakDetectLowCounter = 0;
|
||||
leakDetectCounter = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(flowRate > maxLeakFlowRate)
|
||||
{
|
||||
leakDetectHighCounter++;
|
||||
leakDetectLowCounter = 0;
|
||||
if(leakDetectHighCounter > 4)
|
||||
{
|
||||
leakDetectHighCounter = 0;
|
||||
leakDetectCounter = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
leakDetectHighCounter = 0;
|
||||
leakDetectLowCounter = 0;
|
||||
if(leakDetectCounter > leakDetectTime)
|
||||
{
|
||||
leakDetectCounter = leakDetectTime;
|
||||
alarmState1 |= LEAK_ALARM;
|
||||
|
||||
#ifndef ENABLE_ERROR_PIN_FOR_VALVE_CONTROL
|
||||
#pragma message("[undefined] ENABLE_ERROR_PIN_FOR_VALVE_CONTROL")
|
||||
#elif(ENABLE_ERROR_PIN_FOR_VALVE_CONTROL)
|
||||
ERROR_PIN_OUTPUT();
|
||||
TURN_OFF_VALVE();
|
||||
alarmState1 |= VALVE_OFF_ALARM;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user