삽질 기반의 공학/ELECTRONIC

005. 음파를 이용한 거리 측정, 원리부터 파악하는 초음파 거리 센서

서론

오늘은 초음파를 이용한 거리 측정 센서에 대해서 살펴보겠습니다.

 


초음파?

 

많은 Maker 분들이 애용하시는 초음파 거리 센서

보통 아두이노를 많이 접하셨다면 초음파는 거리 센서로 익숙하실 겁니다.

적외선을 이용한 방식의 거리 센서도 있지만 초음파 거리 센서는 가격도 저렴하고 사용 방법이 어렵지도 않기 때문에 다양한 강의나 키트로 만날 수 있죠.

 

초음파(超音波, Ultrasonic)는 단어에서도 알 수 있듯이 '음파'입니다만, 들을 수 없는 음파에 속합니다. 보통의 음파는 우리의 귀로 청취가 가능하지만 이 음파는 우리가 들을 수 있는 한계의 주파수를 초월한 음파를 가지고 있기 때문에 '초음파'로 불리고 우리가 들을 수 없는 음파인 것입니다.

 

수치로 풀어서 설명하자면 우리는 20Hz ~ 20kHz (Hz : 헤르츠, 진동 수의 단위) 대역의 주파수를 들을 수 있습니다. 그보다 더 높은 20kHz 그 이상의 주파수를 초음파라고 말하는 것입니다.

 

초음파의 다양한 특성 덕분에 많은 산업 분야에서 초음파를 이용하고 있습니다.

우리가 익히 알고 있는 초음파 거리 센서가 초음파의 반향파 특성을 이용하여 거리를 측정하고 있는 것입니다.

 


초음파 센서의 구조부터..

초음파 센서의 구성은 외부로 보기엔 크게 2가지로 나눌 수 있습니다.

(세부적으로 칩까지 들어가기엔 내용이 너무 많아지고 어려워지기에..)

차근차근히 1개씩 살펴보겠습니다.

 


X-TAL (크리스탈 오실레이터)

16Mhz의 X-TAL

초음파 기술에서 빠질 수 없는 소자입니다.

크리스탈 또는 X-TAL, 정확하게는 크리스탈 오실레이터(결정 진동자)라고 부르는 이것은 수동 발진(진동) 소자입니다.

 

발진(oscillation)직류에너지를 전기 진동 에너지로 변환하는 것을 말합니다.

전기 진동 에너지는 진동파를 만들어내는 것이기 때문에, 결과적으로 직류 에너지를 이용해 펄스 또는 사인파 형식의 교류 에너지로 변환하는 것입니다.

 

발진 소자가 어떻게 전기 에너지를 기계적 에너지로 바꾸냐구요?

비밀은 바로 내부의 특수한 결정체인 압전의 효과 중 하나인 역압전 효과에 있습니다.

이 중, 역압전 효과에 따르면 이 압전에 전기 에너지를 가하면 기계적 에너지로 바꾸어 줍니다.

바로 여기서 이 기계적 에너지가 바로 진동 에너지가 되는 것입니다. 그리고 이 진동 에너지를 이용하여 교류 에너지(펄스 파)를 생성하는 것이죠.

(자세한 내용은 추후 다른 게시글에서 다루겠습니다.)

 


초음파 발신 · 수신기과 제어 핀

초음파 센서의 핵이자 근본입니다.

 

초음파 발신기(송신기)는 스피커에 비유할 수 있습니다.

초음파를 내보내는 역할이죠.

 

위에서 설명한 X-TAL이 초음파 발신기와 크게 연관이 있습니다.

X-TAL이 생성해준 펄스 파를 이 발신기를 통해 내보내는 것입니다.

X-TAL이 휴대폰, 발신기가 스피커가 되어서 X-TAL에서 보내주는 진동을 발신기가 멀리 보내주는 것입니다.

초음파를 발신하거나 중지를 시키려면 TRIG 핀에 신호를 보내주면 됩니다.

 

 

초음파 수신기는 마이크에 비유하겠습니다.

초음파를 받아들이는 역할을 수행합니다.

수신기는 평소에 대기 상태를 유지하고 있다가 초음파가 입력되는 순간 특정 전기 신호를 보내주게 되는 것입니다.

이 전기 신호는 ECHO 핀을 통해 받을 수 있습니다.

 

이제 어떻게 초음파의 발신, 수신을 이용해 거리를 측정하는 지 알아봅시다.

 

 


반향파를 이용한다?

 

반향파란 발신된 초음파가 전파되던 중, 매질에 부딪히면 그 초음파가 반사되어 돌아오는데 그 때의 음파를 반향파라고 부르는 것입니다.

그런데, 왜 이 반향파 특성 덕분에 초음파로 거리를 측정할 수 있다는 것일까요?

 

이번에도 어김없이 자세히 하나하나씩 살펴보겠습니다.

 

"거리 값"을 구하기 위한 공식?

 

여기 아주 유명한 공식인 "거속시" 공식이 있습니다.

이 공식 중에는 거리를 구할 수 있는 "거리 = 속력 X 시간" 공식이 있죠.

 

아주 간단하게 생각해보면 "거리"를 구하기 위해선 "속력"과 "시간"이 필요합니다.

어느 정도의 "속도"로 얼마 만큼의 "시간"동안 나아갔나를 알면 "거리"를 구할 수 있습니다.

(60km/h의 속도로 1시간 동안 나아가면 60 X 1 = 60.. 즉, 60km만큼 갔다는 것을 알 수 있는 것 처럼요.)

 


얼마나 빠르니?

 

이 센서는 "초음파"를 사용하고 있습니다. 사실 초음파가 일반적인 소리(음파)보다 고주파의 음파인 것은 맞으나 음파의 속도, 음속과는 상관이 없는 이야기입니다. (초음속과 초음파는 다릅니다!)

 

파동은 매질에 따라 그 속도가 달라집니다. 그런데 사실 일반적인 상황에서는 음파의 매질은 변하지 않습니다.

매질은 바로 우리가 지금도 마시고 있는 "공기"입니다.

그럼 일단 매질은 공기라고 가정하겠습니다. 그러면 음속을 바로 구할 수 있을까요?

 

아닙니다. 음속은 온도와 습도에도 영향을 받습니다. 

온도와 습도의 변화는 공기 분자에 영향을 끼치기 때문에 음속에도 영향을 주죠.

  • 온도가 높으면 공기 분자가 활발하게 움직이고 있다는 것이기 때문에 음속도 같이 높아집니다.
  • 습도가 높다면 공기 중의 수분이 차지하는 양이 높아졌다는 것이고, 이는 공기 분자를 대체하는 수증기가 더 많아졌다는 것이기 떄문에 공기 분자가 줄어듦을 의미합니다. 그래서 음속은 낮아집니다.

빠르게 정리하자면 온도와 음속은 비례하며, 습도와 음속은 반비례합니다.

위의 내용은 알아 두시면 좋습니다. 추후에 보다 정밀하게 거리를 측정해야 할때 위의 내용을 생각해보세요.

 

일단 지금은 간단하게 원리를 파악하는 것이 목적이므로 일상생활에서 음속이 얼마나 나오는지만 알면 됩니다.

일상생활에서 음속을 측정하면 음속은 331~4m/s 정도가 나온다고들 많이 가정합니다.

(온도는 영상 15 ℃ 기압은 1000 hPa.라고 가정을 했을 때의 측정치입니다.)

(더 정확히 측정하려면 v=331+0.6t이라는 공식을 사용합니다. t는 섭씨 온도를 의미합니다.)

 

일단 음파의 속력, 음속은 구했습니다.(초음파는 1초에 331m 가량을 이동할 수 있다고 생각해두겠습니다.)

 


시간이 금이다

 

이제 시간을 구할 차례입니다.

사실 시간은 매질과의 거리에 따라 매번 달라지는 것이므로 음속처럼 상수로 두기에는 무리가 있습니다.

그러면 매질과의 거리에 따른 시간을 측정할 방법을 구해야 합니다.

 

이때 바로 반향파 특성을 제대로 사용합니다.

초음파를 발사시키고 수신기에서 초음파가 감지될 때 까지의 시간을 잰다면?

초음파가 매질에 부딪혀 반사되어 돌아오는, 즉 초음파와 장애물간의 왕복 시간을 잴 수 있습니다.

 

하지만 왕복 시간을 구하려고 하는게 아니죠. 장애물과의 거리를 알려는 것이므로 측정된 시간을 2로 나누겠습니다.

왕복 시간을 2로 나누면 편도 시간을 낼 수 있겠죠.

(아니면 구해진 거리를 2로 나누어도 됩니다!)

 


총망라하면..

거리를 구하려면 "거리 = 속력 X 시간" 공식을 사용해야 합니다.

(모두가 알고 유명한 거속시 공식 중 간판 공식이죠)

 

앞서 이야기 했던 2가지, 음속(속력)과 시간에 대해 다시 생각해보겠습니다.

  • 초음파의 속력은 매질이 공기이며, 일반적인 상황에서 331m/s 정도를 가진다.
  • 초음파를 송신하고 장애물에 부딪혀 반향파가 수신될때 까지의 시간을 측정해 2로 나누면 구할 수 있다.

 

최종적으로 초음파 센서를 이용해 거리를 구하는 공식은 위와 같이 나오는 것을 알 수 있습니다.

 


실험! 실험을 하자!

실험을 통해 간단히 위의 이론이 맞는지 확인할 필요가 있습니다.

 


실험 준비

 


회로

회로는 위의 사진과 같습니다.

간단하게 초음파 센서와 아두이노를 연결했습니다.

Vcc Trig Echo GND
5V D3 D4 GND

 


소스 코드

int trig = 3;
int echo = 4;
float velocity = 331.0; //음속은 331m/s로 가정합니다.

void setup() {
  Serial.begin(9600); //시리얼 플로터로 값 보기
  pinMode(trig, OUTPUT); //송신기는 출력
  pinMode(echo, INPUT); //수신기는 입력
  
  digitalWrite(trig, LOW);
  digitalWrite(echo, LOW); //모두 0으로해서 꺼둡니다.
}

void loop() {
  digitalWrite(trig, HIGH); //송신기를 켜서 초음파를 송신합니다.
  delayMicroseconds(10); 
  digitalWrite(trig, LOW); //10ms동안 송신하고 끕니다.
  
  //pulseIn 함수를 사용합니다. 함수가 호출되고 echo핀이 High가 될 때(반향파가 돌아올 때) 까지의 시간을 측정합니다.
  unsigned long measure_time = pulseIn(echo, HIGH); //ms단위로 들어오는 값을 초로 바꾸기 위해 1000을 나눕니다.

  //거리 = 속도 * (왕복 시간 / 2)
  float distance = ((velocity * measure_time) / 1000) / 2;
  
  //Serial.print(distance); //밀리미터 단위
  Serial.print(distance / 10); //센티미터 단위
  delay(100);
}

전체적인 코드는 위와 같습니다.

중요한 부분을 뜯어서 살펴보겠습니다. 

 


digitalWrite(trig, HIGH); //송신기를 켜서 초음파를 송신합니다.
delayMicroseconds(10); 
digitalWrite(trig, LOW); //10ms동안 송신하고 끕니다.

초음파를 송신하는 부분입니다.

 

초음파 송신기를 작동시켜(HIGH) 초음파를 송신시키는 상태로 바꿉니다.

10ms동안 그 상태를 유지시킨 뒤 송신기를 끕니다.(LOW)

 


//pulseIn 함수를 사용합니다. 함수가 호출되고 echo핀이 High가 될 때(반향파가 돌아올 때) 까지의 시간을 측정합니다.
unsigned long measure_time = pulseIn(echo, HIGH);

시간을 측정하는 부분입니다. pulseIn 함수가 핵심입니다.

 

pulseIn(핀, 상태) 함수는 타이머와 비슷한 역할입니다. 함수가 호출(사용)될 때 부터 측정이 시작되고, 기입된 핀 번호에서 들어오는 값을 계속 측정합니다. 그리고 핀 번호에서 읽은 값이 상태와 같아질 때 측정이 종료됩니다.

 

측정이 종료되면 측정된 시간을 반환합니다. 

 


//거리 = (속도 * 왕복 시간) / 2 //측정 시간이 ms단위로 들어오기 때문에 초로 바꾸기 위해 1000으로 나눕니다.
  float distance = ((velocity * measure_time) / 1000) / 2;

너무 많이 설명드려서 이젠 다 아시지 않을까 싶습니다.

거리를 구하는 공식을 그대로 코드로 옮긴 부분입니다.

반환되는 시간이 ms(밀리세컨드) 단위인데 공식에서 사용할 시간은 s(초) 단위여야 하기에 추후에 값을 사용할 때는 1000으로 나누는 부분 정도가 추가되었습니다. (1000ms = 1s)


//Serial.print(distance); //밀리미터 단위
Serial.print(distance / 10); //센티미터 단위

일반적으로 측정 값은 밀리미터 단위로 들어오게 됩니다.

센티미터 단위로 값을 받아주려면 10으로 나눈 값을 사용하면 됩니다.

 

나머지 부분은 기본적인 설정과 시리얼 출력 부분이니 실험으로 넘어가겠습니다.


실험 영상

작동 테스트

시리얼 플로터를 이용해서 제대로 동작하는지 확인하는 실험을 먼저 했습니다.

 

정확도 테스트

이번엔 자를 이용해 얼마나 정확한지 테스트 해보았습니다.

10cm 이내로 접어들면 정확도가 떨어지지만, 그 이상의 거리는 제법 높은 정확도를 보여줍니다.

 

끝!


초음파 거리 센서를 단순히 사용하기까지 밖에 못했지만 이렇게 원리와 세세한 부분까지 알아보니 피곤하기도 하지만 정말 공부한 것 같네요.

 

오늘 게시글은 여기서 마무리하겠습니다. 처음으로 직접 그린 일러스트를 게시글에 넣어보는 시도를 해보았는데 효과적인지는 아직 모르겠지만 차차 더 나은 일러스트를 그려보도록 노력하겠습니다!

긴 삽질 게시글을 읽어주셔서 감사합니다!