안녕하세요.
오늘은 파이썬으로 신호처리의 기본인 신호의 시간영역과 주파수 영역에 대해 알아보겠습니다.
우선 제가 진행하고 있는 프로젝트의 신호를 사용하겠습니다.
우선, 저 위 데이터를 설명하겠습니다.
AVR의 adc(analog to digital converter)를 거친 데이터로 0에서 1023의 사이의 출력값을 가집니다.
https://coding-yoon.tistory.com/13?category=823570
위 데이터를 설명하려고 하니, 옛날에 적어놓은 글이 있었습니다. 위 글을 참고하시면 좋을 것 같습니다.
( 위 링크의 글에 이상한 점이 있는데 혹시 찾으셨나요?? 제가 다시 한 번 읽어보니 샘플링(양자화)하여 부호화!! 이렇게 적혀 있습니다. 정확히 말하자면 샘플링(sampling)은 시간으로 쪼갠 것이며, 진폭으로 쪼갠 것이 양자화 입니다.
그러니 0 ~ 5v를 0 ~ 1023(10bits)로 양자화했다는 것이 정확한 표현입니다.)
위 데이터는 시간에 따른 소리 데이터입니다. 아무 전처리를 거치지 않는 시간 & 진폭 디지털 데이터입니다.
다시 의미가 있는 아날로그화시켜주도록 합시다. 다만, 제가 sampling rate를 몇으로 설정했는지 지금은 기억이 나지 않아 시간은 그대로 두고, 진폭을 아날로그화시켜주도록 하겠습니다.
analog_data = digital_data / 1024 * 5.0(v)
디지털 데이터에 양자화시켜준 bit로 나눠주고, 인가한 전압을 곱해주면 됩니다.
대부분 사람들은 시간 영역으로 보는 데이터를 보고 분석합니다. ex) 시간에 따른 전압, 주식 등등
하지만, 공학을 배우는 사람들은 시간 영역뿐만 아니라 주파수 영역을 알아야 합니다.
주파수 영역은 언제 사용될까요?
가장 대표적인 예시 중 하나가 필터일 것입니다.
만약, 제가 위 데이터를 Low Pass Filter를 사용해서 100Hz미만의 데이터만 추출하였고(sample rate를 알고 있다는 가정하에), 그것을 확인하고 싶다면 어떻게 해야할까요? 어느정도 눈으로 고주파가 잘렸구나는 시간영역에서 대략적으로 알 수 는 있지만 정확히 알 수 없습니다. 그 때 사용되는 영역이 주파수 영역입니다.
시간 신호를 주파수 영역으로 변환하고 싶다면, 푸리에 급수, 푸리에 변환을 알아야 하지만, 그건 파이썬에게 맡겨 둡시다.
파이썬을 numpy를 사용해서 바로 변환해보도록 하겠습니다. 한 줄이면 가능합니다.
import numpy as np
fft = np.fft.fft(data) / len(data)
fft_abs = abs(fft)
np.fft.fft에 나온 값을 왜 abs(절댓값)을 씌운 이유는 복소수가 들어있기 때문입니다. 바로 plot시켜 보겠습니다.
import matplotlib.pyplot as plt
plt.title("raw data - frequency domain")
plt.stem(fft_abs)
plt.show()
그림이 무언가 잘못된 것 같습니다.
0Hz에서 2.5가 우뚝 서있고, 나머지 주파수는 보이지 않습니다. 어떻게 해야할까요?
직류 성분을 제거하면 됩니다. 지금 현재 데이터는 2.5V를 기준으로 값이 흐르고 있습니다.
그 말은 즉슨 2.5V의 직류 성분을 제거하면 교류 성분만 남게 된다는 것입니다. 바로 2.5V를 빼숩니다.
analog_data = digital_data / 1024 * 5.0(v) - 2.5(v)
그리고 다시 그려줍시다.
위처럼 주파수 영역으로 변경하면, 어떤 대역의 주파수가 많고 적은지는 정확히 알 수 있게 됩니다.