
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
//-------------------------------------------------------//
// Project Code : V2H6K01-23-ENEMAN
// File Name : RoutineTsamp.cpp
// Created on : 2023. 8. 8.
// Description :
// Author : KimJeongWoo
// Last modified Date :
//-------------------------------------------------------//
#include "Cpu1DeviceDefine.h"
int Testpcs4 = 0;
int Adc_BUTTON = 0;
int Chk_Botton = 0;
int Chk_Botton_pre = 0;
//순환 버퍼
#define BUFFER_SIZE 5 //10 이상 커지면 순간적인 변화를 계산하지 못함?
int currentIndex = 0;
int UV_buffer[BUFFER_SIZE];
int VIS_buffer[BUFFER_SIZE];
int IR_buffer[BUFFER_SIZE];
// 이전 센서 값 저장을 위한 변수 초기화
int CH4_UV_prev = 0, CH4_VIS_prev = 0, CH4_IR_prev = 0;
// 변화량을 저장할 배열
int UV_change[BUFFER_SIZE], VIS_change[BUFFER_SIZE], IR_change[BUFFER_SIZE];
int prev_avg =0;
// 상관 계수를 계산하는 함수
double calculate_correlation(const int *x, const int *y, int n) {
long long sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0;
for (int i = 0; i < n; ++i) {
sum_x += x[i];
sum_y += y[i];
sum_x2 += (long long)x[i] * x[i];
sum_y2 += (long long)y[i] * y[i];
sum_xy += (long long)x[i] * y[i];
}
double numerator = (double)n * sum_xy - sum_x * sum_y;
double denominator = sqrt(((double)n * sum_x2 - sum_x * sum_x) * ((double)n * sum_y2 - sum_y * sum_y));
if (denominator == 0) return 0; // 분모가 0이면, 상관관계를 계산할 수 없음
return numerator / denominator;
}
void RoutineTsamp()
{
// PllRun();
Lpf1stRun();
FaultChecker();
if(Testpcs4 == 1)
{
EepromWriteAdcScale();
Testpcs4 = 0;
}
if(Testpcs4 == 2)
{
EepromReadAdcScale();
Testpcs4 = 0;
}
// receivedChar = SCI_readCharBlockingFIFO(SCIC_BASE);
// SCI_writeCharBlockingFIFO(SCIC_BASE, receivedChar);
ModbusACheckBuffer();
Chk_Botton = Din.Data.bit.Button;
if((Chk_Botton_pre == 0)&& (Chk_Botton == 1))
{
FaultReset = 1;
}
else
{
FaultReset = 0;
}
Chk_Botton_pre = Chk_Botton;
/////////////////////////////////////////////
UV_buffer[currentIndex] = CH4_UV_Flt; // 배열에 센싱값 저장
VIS_buffer[currentIndex] = CH4_VIS_Flt; // 배열에 센싱값 저장
IR_buffer[currentIndex] = CH4_IR_Flt; // 배열에 센싱값 저장
// 센서 값 갱신 및 변화량 계산
UV_change[currentIndex] = CH4_UV_Flt - CH4_UV_prev; // UV 변화량 계산
VIS_change[currentIndex] = CH4_VIS_Flt - CH4_VIS_prev; // VIS 변화량 계산
IR_change[currentIndex] = CH4_IR_Flt - CH4_IR_prev; // IR 변화량 계산
// 현재 값을 '이전 값'으로 저장
CH4_UV_prev = CH4_UV_Flt;
CH4_VIS_prev = CH4_VIS_Flt;
CH4_IR_prev = CH4_IR_Flt;
currentIndex = (currentIndex + 1) % BUFFER_SIZE; // 인덱스 갱신
if(CH4_UV_Flt > CH4_UV_max) CH4_UV_max = CH4_UV_Flt; // 새로운 최대값 발견 시 갱신
if(CH4_VIS_Flt > CH4_VIS_max) CH4_VIS_max = CH4_VIS_Flt; // 새로운 최대값 발견 시 갱신
if(CH4_IR_Flt > CH4_IR_max) CH4_IR_max = CH4_IR_Flt; // 새로운 최대값 발견 시 갱신
// 버퍼가 한 바퀴 돌았을 때 상관 계수 계산
if (currentIndex == 0)
{
uv_vis_correlation = calculate_correlation(UV_buffer, VIS_buffer, BUFFER_SIZE);
uv_ir_correlation = calculate_correlation(UV_buffer, IR_buffer, BUFFER_SIZE);
vis_ir_correlation = calculate_correlation(VIS_buffer, IR_buffer, BUFFER_SIZE);
// 변화량의 상관관계 계산
uv_vis_change_correlation = calculate_correlation(UV_change, VIS_change, BUFFER_SIZE);
uv_ir_change_correlation = calculate_correlation(UV_change, IR_change, BUFFER_SIZE);
vis_ir_change_correlation = calculate_correlation(VIS_change, IR_change, BUFFER_SIZE);
// 평균과 표준 편차 계산
double sum = 0, sum_sq_diff = 0;
for (int i = 0; i < BUFFER_SIZE; ++i) {
sum += UV_buffer[i];
sum_sq_diff += (UV_buffer[i] - (sum / BUFFER_SIZE)) * (UV_buffer[i] - (sum / BUFFER_SIZE));
}
double avg = sum / BUFFER_SIZE;
stddev = sqrt(sum_sq_diff / BUFFER_SIZE);
adaptive_threshold = avg + 2 * stddev;
// 최신 값과 바로 이전 값 사이의 변화율 계산을 위한 인덱스 계산
int latest_index = (currentIndex - 1 + BUFFER_SIZE) % BUFFER_SIZE;
int prev_index = (latest_index - 1 + BUFFER_SIZE) % BUFFER_SIZE;
// latest_change = UV_buffer[latest_index] - UV_buffer[prev_index];
latest_change = avg - prev_avg;
prev_avg = avg;
if (abs(latest_change) > adaptive_threshold) {
// 변화율이 적응형 임계값을 초과하는 경우 처리
// 예: 알림 발송, 로깅, 경고 등
SET_FT_UV_Level = adaptive_threshold;
}
}
}