//-------------------------------------------------------// // 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; } } }