서보모터와 초음파 거리 센서 활용
지난 강좌에서 보여드렸던 강아지 모형은 사람이 50cm 이내로 가까이 오면 꼬리를 친다. 화려하게 LED가 반짝 거리는 부분은 차후에 배울 NeoPixel 강좌에서 마무리하도록 하고, 이번 시간에는 가까이 다가오는 물체를 감지하면 마치 스위치를 켠 것처럼 서보모터를 움직여 꼬리를 치고 LED 한 개가 반짝이게 하는 장난감을 만들 것이다.
앞 강좌의 동영상에서 보다 단순화된 앞모습과, 실제 부품들이 연결된 뒷면의 사진을 아래에 함께 보여드린다.
나는 인터넷에서 구한 강아지의 사진을 사용했지만, 본인 스스로 예쁜 강아지를 그려 보는 것도 의미 있을 것이다.
강아지의 크기는 A5 사이즈 정도로 그리고 받침 위에 아두이노와 관련 부품을 배치하였다.
원래는 아두이노 우노 보드를 가지고 제작하였지만, 위의 사진은 아두이노 나노로 회로를 꾸민 사진이다.
핀번호나 구성 모두 차이가 없다.
복잡해 보이지만 회로를 보면 서보모터, 초음파 거리센서, LED가 연결되어 있는 단순한 구조이다.
회로의 내용을 보면
서보모터는 4번 핀에 연결되어 있고,
초음파 센서는 설명이 좀 필요하지만 7번(TRIG 트리거)과 8번(ECHO 에코)에 연결되어 있고,
LED는 5번에 연결되어 있다.
서보모터와 센서 모두 VCC는 5V에 연결하고 GND는 GND에 연결한다.
이 회로가 앞서 설명한 회로들과 다른 것은 스위치를 눌러서 서보모터가 동작하던 부분의 스위치를 초음파 대신하고 있다는 것이다.
그래서 초음파 센서에 대한 공부가 필요하다.
초음파 센서는 센서의 앞에 놓인 물체까지의 거리가 얼마나 떨어져 있는가를 감지하는 센서이다.
두 개의 원통형 통의 한 곳에서 초음파를 발사(trigger 트리거)하고, 다른 원통에서 이 초음파가 반사(echo 에코)되어 돌아오는 음파를 감지한다.
그래서 두 개의 발사된 음파와 도착되는 음파의 시간차를 통해서 물체의 거리를 측정하게 된다.
중학교 과학 시간에서 배웠던 소리의 속도 즉 1초당 340m가 여기서 사용되는 것이다. 복잡한 계산을 간단히 풀어보면, 만일 음파가 1초 만에 돌아왔다면, 그 1초는 물체에 도착하는과 반사되어 돌아오는 시간이 모두 포함되어 있으므로 실제는 0.5초 거리에 있는 것이므로 170m 거리에 있는 것이다.
우리가 따지는 시간은 초보다 훨씬 짧은 시간인 백만분의 1초이므로 170미터의 1,000,000분의 1 그러니까 1ms당 0.017cm의 거리에 있다고 생각하면 된다.
온도에 따라 속도의 변화가 있다(속도= 331.5+0.6*온도)고는 하지만 우리가 그렇게 정밀한 거리 측정이 필요한 것은 아니므로 백만분의 1초당 0.017을 기본으로 하여 코드를 만들어 보면 아래와 같은 함수를 만들 수 있다.
이 함수는 트리거 핀에서 음파를 발사하고 10밀리 초 이후에 반사파를 받아서 두 작업의 차이 시간을 가지고 거리를 측정하는 함수이다.
int chk_Distance()
{
digitalWrite(tPin, LOW); //트리거 핀에서 아무런 음파를 발사하지 않는다.
delayMicroseconds(2); // 백만분의 2초만큼 기다린다
digitalWrite(tPin, HIGH); //트리거 핀에서 음파 발사
delayMicroseconds(10); // 백만분의 10초만큼 기다린다
digitalWrite(tPin, LOW); //트리거 핀에서 발사를 멈춘다
return pulseIn(ePin, HIGH)* 0.017; // 에코핀에 음파가 도달한 시간에 0.017을 곱하여
//거리를 측정하여 그 값을 전달한다.
}
전체 코드는 아래와 같다
chk_Distance() 함수는 앞에 설명했으므로 나머지 부분을 설명하자면...
연결 : 초음파 센서 - 트리거 핀 - 7, 에코핀 - 8
LED핀 - 5
서보모터 컨트롤 핀 - 4
setup 함수에서
LED 핀과 트리거 핀은 출력, 에코핀은 입력으로 지정
서보모터는 초기화 위치로
loop 함수에서
cm변수에 chk_Distance에서 측정한 거리를 넣고 이 값이 50보다 작으면
LED 연결핀은 HIGH로 하여 불을 켜고
서보모터는 각도 0에서 90도까지 움직이도록 한다.
거리가 계속 50보다 작으면 이 작업을 반복할 것이다.(loop함수 이므로)
만일,
거리가 50보다 크거나 같다면
모터는 초기 위치로 움직이고 LED는 끄게 된다.
Serial 관련 함수들은 실제 거리의 값을 보여주게 된다.
이를 tinkercad의 시뮬레이션으로 확인해 보자.
실제로 움직이는 꼬리 부분은 아래의 영상처럼 연결되어 있다.