아두이노 코딩-105: 아두이노 코딩에 의한 RC 저주파 필터 회로 성능실험

codingart(66)
Published in
#kr
Words
435
Reading
2 min
Listen
Play
8y

noname01.png

100Ω저항과 220μF 극성콘덴서로 구성된 저주파 필터를 제작하여 아두이노 우노 보드의 디지털 핀과 배선하였다. 저주파 필터 회로 실험을 위한 아두이노 디지털 핀의 선정은 pinout 다이아그램에서 물결 표시가 있는 즉 PWM(pulse width modulation) 이 가능한 핀 3, 5 ,6, 9, 10, 11번 핀 중에 하나를 선택해 사용해야 한다.

noname02.png

아두이노 코딩에 의해서 2개의 주파수로 구성된 신호를 생성한다. 2개의 주파수 중 하나는 1HZ 로 아주 낮은 저주파 freqLow를 선정하고 다른 하나는 freqHigh[] 어레이로 20Hz, 40Hz, 50Hz, 70Hz를 대상으로 필터링 성능 실험을 해 보기로 한다. setup() 의 통신 속도는 9600 으로 설정한다.

저주파 필터 실험에서 굳이 loop()를 코딩할 필요는 없으며 setup()에서 1회성으로 사례별로 계산 후 시리얼 플로터를 통해서 가시적인 주파수 파형을 살펴 보기로 하자.

noname03.png

for loop 변수 k는 freqHigh[] 어레이를 불러 올 수 있도록 0,1,2,3 의 범위를 가진다. sin 함수 괄호안의 계산 값은 한 주기에 해당하는 0∼2π 구간을 가지게 된다. 2개의 주파수를 8:2로 혼합하여 계산된 0∼2.0 사이의 sensorV의 값을 analogWrite() 명령을 적용할 수 있도록 0∼255 사이의 값으로 변환하여 지정된 PWM 디지털 핀에 출력하자.

배선도에 의하면 이 PWM 디지털 핀 출력이 저주파 필터 RC 회로의 입력 신호전압이 된다. 자주파 필터링의 성능 실험을 위해서는 배선도에서 보듯이 저장과 콘덴서의 연결점에서 필터링 되었을 출력 전압을 뽑아서 아날로그 핀에서 읽는다. 아날로그 핀에서는 0∼5.0V 사이의 전압 값을 읽어 10비트 해상도에 해당하는 0∼1023 사이의 정수값을 출력해 준다. 따라서 1023으로 나누고 2.0을 곱해주면 다시
0∼2.0 사이의 값으로 환산이 된다.

중요한 점은 입력 신호전압과 출력신호전압 사이에 필터링에 의한 즉 저주파를 통과 시키고 고주파를 배제하는 주파수 거르기가 일어났는지 알아볼 필요가 있다. 이과정에서 복잡한 주파수 스펙트럼 분석을 할 것이 아니라 직접 시리얼 플로터 비쥴얼라이제이션을 통해 높은 주파수 성분의 잔존 여부를 확인하도록 하자.

noname04.png

1Hz+20Hz 파형은 둘 다 저주파이므로 필터링 할 부분이 거의 없다. 1Hz+40Hz 파형에서는 고주파에 해당하는 40Hz 성분이 깔금히 걸러졌다. 1Hz+50Hz 파형은 생성 자체에 어던 문제가 있는듯하여 아래 그림과 같이 50Hz주변의 파형을 조사해본 결과 사실 45Hz부터 파형 패턴이 좀 일그러지기 시작했는데 아두이노의 실수 계산 정밀도 문제가 아닌가 한다.

noname05.png

45Hz를 지나 50Hz를 넘어서 부터는 저주파 필터링 성능이 다시 점차 떨어지기 시작했다.

한편 코딩이 가능한 디지털 저주파 필터링 기법을 사용하게 되면 이러한 현상이 나타나지 않는다. 아두이노 드론 으용의 경우에 I2C 인터페이스되는 MPU6050 자이로 센서가 많이 사용되는데 실제로 드론을 시험 비행을 시켜보면 예를 들어 Yaw의 경우 서서히 회전시키기 때문에 그 주파수로 규정한다면 1Hz(60 rpm) 도 채 안되는 저주파이므로 만약에 I@C 인터페이스를 통해 아두이노에 건내는 데이터의 경우 이 정도 수준의 필터면 충분해 보인다.

한편 I2C 인터페이스 방식으로 전달되는 입력 신호 파형은 그 자체가 숫자이기매문에 디지털 저주파 필터 코딩 기법 적용이 더 적합해 보인다.

동영상에서 입력 신호파형과 필터된 출력 신호 파형을 체크해 보자.

간단한 회로를 꾸민 후 사이트에 첨부된 코드를 실행해 보자.
//Lowpass_filter_circuit_serialplot_01
float pi =3.1415629543;
float freqLow = 1.0;//Hz
float freqHigh[] = {20, 40, 50, 70};//Hz

void setup() {
Serial.begin(9600);
for ( int k=0; k<4; k) {
for ( int i=1; i<201; i
) {
float sensorV = 1.0+0.8sin(2.0pifreqLowi/100.0)+0.2sin(2.0pifreqHigh[k]i/100.0);
Serial.print(sensorV);
Serial.print(",");
int volt = 255sensorV/2.0;
analogWrite(3, volt);
float X = 2.0
analogRead(A0)/1023 - 2;
Serial.println(X);
}
}
}

void loop() {
}//끝