상세 컨텐츠

본문 제목

[MATLAB] 전압 한주기를 찾아내는 코드개발

프로그래밍/MATLAB

by 척척석사 민준 2020. 8. 25. 17:15

본문

728x90

포스팅하다 보니 아이디어가 떠올랐다. 그것은 바로 전압한주기를 컴퓨터가 알아서 찾아서 슬라이싱 해주는 코드다. 

코드 블록의 흐름은 다음과 같다. 

소스코드의 흐름도

 

주기의 정의에서 출발하자 : What is period?

물리학도이기 때문에 정의에서 출발하는 걸 좋아한다. 주기는 일정하게 반복되는 상황에서 반복이 일어날 때 걸리는 시간 간격을 주기라고 한다 (출처 : 네이버 물리학백과) 여기서 코드를 짜는데 중요한 아이디어가 숨어있다. 바로 시간 간격이다. 반복되는 데이터에서 간격에 대한 정보를 추출하면 그게 주기 정보가 되는 것이다. 

내가 측정하는 데이터는 대부분 플라즈마로 인해 발생하는 전류 정보와 전압 정보이기 때문에 전류 정보는 분석하기가 까다롭다. 그래서 주로 안정적인 전압 데이터를 이용한다. 전압한주기를 지정할 때 두 가지 방법이 있는데 하나는 전압의 피크값에서 피크값(Vpeak - Vpeak)으로 정의하는 것과 전압이 0인점에서 0인점으로 정의하는 방법(V0 - V0) 이 있는데 전압강하 등의 문제로 피크값을 정하는데 오류가 생기므로 두 번째 방법을 택하기로 한다. 

find 함수를 이용해서 V = 0 인 점의 '위치'를 찾자

처음에 find 함수를 사용하는데 많이 어려웠다. 그 이유는 값과 인덱스에 대한 개념이 없었기 때문이다. 파이썬에서 리스트의 개념과 비슷한데, 매트랩에서 값을 저장하면 저장되는 순서대로 순서가 부여되는데 이를 인덱스라고 한다. 이 인덱스는 실제 그 값이 어디에 저장되어있는지에 대한 주소를 의미한다. find 함수는 조건에 맞는 값들이 있는 위치를 반환한다. find 함수의 정의는 0이 아닌 요소의 값이나 인덱스 찾기(출처 : https://kr.mathworks.com/help/matlab/ref/find.html?s_tid=srchtitle) 라고 되어있다. 그래서 0인 요소를 찾기 위해선 논리 기호 ~(not)을 쓰면 요소에서 0이 있는 위치를 반환한다. 

zero_idx = find(~V) % 전압데이터를 저장한 리스트 V에서 0인 점들의 위치(인덱스)를 zero_idx에 저장

diff 함수를 이용해서 인덱스 위치사이의 '간격'을 찾자

diff 함수는 다음값과의 차이를 반환하는 함수이다. 어렵게 말하면 미분이고 쉽게 말하면 값과 값 사이 간격을 얻는 함수이다. A = [0, 1, 2, 3, 4, 5, 100] 일 때, diff(A) = [1, 1, 1, 1, 1, 95]가 된다. 인덱스 사이 간격이 1이나 3이 되는 값은 0인 점들이 연속되어 있는 것이다. 데이터를 어느 간격으로 얻는지에 따라 다르겠지만 한 주기의 전압 데이터가 1000개는 넘을 것이므로, 인덱스 간격이 100 이상인 경우는 연속되지 않고 반주기 간격으로 떨어져 있는 경우일 것이다. 

출처 : https://www.mathsisfun.com/algebra/trig-sin-cos-tan-graphs.html

위의 Sine 그래프를 봐도, V = 0 인점들 사이의 간격은 주기의 반이다. (주기가 2π 일때 V = 0 인 점은 -2π, π,  0, π, 2π이다)

zero_idx = find(~V); %전압데이터에서 V = 0 인 점의 인덱스를 찾음
diff_zero_idx = diff(zero_idx); %0인점이 여러개이므로 diff를 써서 값이 크게 변하는 점을 찾음
zero_point_idx = find(diff_zero_idx > 100); %인덱스 간격이 100이 넘는 구간은 최소 반주기임

이제 한 주기를 찾아보자

zero_point_idx 에 저장된 정보는 간격이 100이 넘는 인덱스 값들이다. zero_point_idx(1)는 이 배열의 첫 번째 값으로 그 의미는 첫 번째로 0이 나오는 점이다. zero_point_idx(2)는 반주기째에 나오는0점이다. zero_point_idx(3)은 한 주기의 끝에 나오는 0점이다.

그럼 이 인덱스 정보를 t1과 t2에 저장하면, 전류 전압 데이터에서 이 인덱스를 이용해 한 주기를 슬라이싱 할 수 있다. 

zero_idx = find(~V); %전압데이터에서 V = 0 인 점의 인덱스를 찾음
diff_zero_idx = diff(zero_idx); %0인점이 여러개이므로 diff를 써서 값이 크게 변하는 점을 찾음
zero_point_idx = find(diff_zero_idx > 100); %인덱스 간격이 100이 넘는 구간은 최소 반주기임
t1 = zero_idx(zero_point_idx(1)); %첫번째 점이 주기 시작점임
t2 = zero_idx(zero_point_idx(3)); %세번째 점이 주기 끝임 두번째 점은 반주기

% 한주기의 전류 전압 데이터를 따로 저장해준다
V_1cyc = V(t1:t2);
I_1cyc = I(t1:t2);
T_1cyc = T(t1:t2);
Period = length(T_1cyc)*dt;
Freq = 1/Period ; 

잘라낸 한 주기를 plot 한 데이터

 

728x90

관련글 더보기