2013-04-22 2 views
0

0에서 10V 사이의 전압으로 읽힌 온도 이동 창이있는 간단한 이동 평균을 작성했습니다.단순 이동 평균 합계/오프셋 문제

알고리즘이 제대로 작동하는 것처럼 보일지라도, 어떤 온도가 창을 먼저 채웠는지에 따라 이동 평균은이 값에 근접하지 않는 모든 값에 대해 오프셋을 갖습니다. 예를 들어,이 프로그램을 임시로 실행하십시오. 센서가 실내 온도에 연결되면 4.4V 또는 21.3C가됩니다. 단, 온도를 뽑으면. 센서에서 전압은 1.4V로 떨어지나 이동 평균은 1.6V로 유지된다. 이 오프셋은 창 크기를 늘리면 작아집니다. 작은 윈도우 크기에서도이 오프셋을 제거하는 방법. 20?

REM SMA Num Must be greater than 1 
#DEFINE SMANUM 20 
PROGRAM 
'Program 3 - Simple Moving Average Test 
CLEAR 
DIM SA(1) 
DIM SA0(SMANUM) : REM Moving Average Window as Array 
DIM LV1 
DIM SV2 
LV0 = 0 : REM Counter 
SV0 = 0 : REM Average 
SV1 = 0 : REM Sum 
WHILE(1) 
    SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window 
    SV1 = SV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum 
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values 
     SV1 = SV1 - SA0((LV0+1) MOD SMANUM) : REM remove oldest value from sum 
     SV0 = SV1/SMANUM : REM calc moving average 
     PRINT "Avg: " ; SV0 , " Converted: " ; SV0 * 21.875 - 75 
    ENDIF 
    LV0 = LV0 + 1 : REM increment counter 
WEND 
ENDP 

출력 (이 후드로 ACR9000위한 ACROBASIC 작성된 주) - 프로그램

Raw: 1.40625 Avg: 1.55712  Converted: -40.938 
Raw: 1.40381 Avg: 1.55700  Converted: -40.940625 
Raw: 1.40625 Avg: 1.55699  Converted: -40.94084375 
Raw: 1.40625 Avg: 1.55699  Converted: -40.94084375 
Raw: 1.40381 Avg: 1.55686  Converted: -40.9436875 
Raw: 1.40381 Avg: 1.55674  Converted: -40.9463125 
Raw: 1.40625 Avg: 1.55661  Converted: -40.94915625 
을 실행하는 동안 온도 센서를 제거 ... 온도 센서
Raw: 4.43115 Avg: 4.41926  Converted: 21.6713125 
Raw: 4.43115 Avg: 4.41938  Converted: 21.6739375 
Raw: 4.43359 Avg: 4.41963  Converted: 21.67940625 
Raw: 4.43359 Avg: 4.41987  Converted: 21.68465625 
Raw: 4.43359 Avg: 4.42012  Converted: 21.690125 
Raw: 4.43359 Avg: 4.42036  Converted: 21.695375 
Raw: 4.43359 Avg: 4.42061  Converted: 21.70084375 

붙어

센서를 제거한 후 원시 및 이동 평균간에 눈에 띄는 오프셋이 나타납니다.

은 또한 반대의 순서로 발생하는 오프셋 :

출력 - 프로그램

Raw: 4.43848 Avg: 4.28554  Converted: 18.7461875 
Raw: 4.43848 Avg: 4.28554  Converted: 18.7461875 
Raw: 4.43848 Avg: 4.28554  Converted: 18.7461875 
Raw: 4.43848 Avg: 4.28554  Converted: 18.7461875 
Raw: 4.43848 Avg: 4.28554  Converted: 18.7461875 
Raw: 4.43359 Avg: 4.28530  Converted: 18.7409375 

을 실행하면서 프로그램을 승 시작/온도 센서는 온도 센서를 부착 ...

Raw: 1.40381 Avg: 1.40550  Converted: -44.2546875 
Raw: 1.40625 Avg: 1.40550  Converted: -44.2546875 
Raw: 1.40625 Avg: 1.40549  Converted: -44.25490625 
Raw: 1.40625 Avg: 1.40549  Converted: -44.25490625 
Raw: 1.40625 Avg: 1.40548  Converted: -44.255125 
Raw: 1.40625 Avg: 1.40548  Converted: -44.255125 

제거 다시 센서를 부착 한 후 원시 평균과 이동 평균간에 눈에 띄는 오프셋이 나타납니다.

+0

VBA와 관련이 있습니까? –

+0

Mistagged. 고마워. 나는 그것을 업데이트했다. –

답변

1

합계에서 뺀 값이 실제로 배열에서 가장 오래된 값이 아닌 것 같습니다. 사실 가장 오래된 값은 WHILE의 첫 번째 줄에 새 값으로 덮어 씁니다. 고리. 합계에서 두 번째로 오래된 값이었습니다.

OP의 조언에 따라 시간 경과에 따른 정밀도 손실을 해결하기 위해 Changed Average 및 Sum 변수를 64 비트 부동 소수점으로 편집하십시오.

PROGRAM 
'Program 3 - Simple Moving Average Test 
CLEAR 
DIM SA(1) 
DIM SA0(SMANUM) : REM Moving Average Window as Array 
DIM LV1 
DIM DV2 
LV0 = 0 : REM Counter 
DV0 = 0 : REM Average 
DV1 = 0 : REM Sum 
WHILE(1) 
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values 
     DV1 = DV1 - SA0(LV0 MOD SMANUM) : REM remove oldest value from sum 
    ENDIF 
    SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window 
    DV1 = DV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum 
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values 
     DV0 = DV1/SMANUM : REM calc moving average 
     PRINT "Avg: " ; DV0 , " Converted: " ; DV0 * 21.875 - 75 
    ENDIF 
    LV0 = LV0 + 1 : REM increment counter 
WEND 

내가 실행중인 기본 환경이 없어하지만 난 파이썬이 테스트와 같은을 가지고 : (배열이 가득 차면) 가장 오래된 값을 먼저 차감되는 것을 보장

이 예상되는 답을 제공합니다 버전에 상응하는 코드에 대한 잘못된 출력과 위에서 삽입 한 버전에 해당하는 코드의 예상 출력.

+0

고마워요, 이것이 해결책입니다. 당신이 맞습니다, 나는 새로운 온도를 얻을 때 가장 오래된 값을 덮어 썼습니다. 나는 잠시 머리를 숙이고 있었고, 다시 한번 감사드립니다. –

+0

내가 총을 뛰어 넘은 것처럼 보입니다. 나는 아직도 원시 평균과 이동 평균 사이의 작은 오프셋을 눈치 채고있다. 예 :'Raw : 4.55322 Avg : 4.42033'은 약 2.9C입니다. 나는 내일 더 조사를 할 것이고, 나의 발견과 함께 여기에서 논평 할 것이다. –

+0

배열의 전압 순서 (예 :'V')와'V (LV0)'의 각 전압을 읽음으로써 코드를 테스트해볼 수 있습니다. 그런 식으로, 나는'V'의 첫 번째 절반의 값을'1'과 같게 만들고'V'의 두 번째 절반의 값을'5'와 같게 만들고 이동 평균을 관찰 할 수 있습니다. 출력은 입력 값의 일관된 계단식 시퀀스를 기반으로합니다. 또 다른 방법은 매번 'SA0'배열의 값의 합을 계산하여 'SV1'과 비교하는 것입니다. 프로덕션 용도로는 빠르지 만 남아있는 버그를 발견하는 데 도움이 될 수 있습니다. – Simon