거리 측정을 위한 초음파 센서 SR-04는 아두이노 센서 중에서 가장 중요한 센서 중의 하나이다. 초음파 센서의 구조는 크리스탈 발진회로에 의해서 40kHz 주파수를 만들어 Triggering 하여 쏜 다음 벽면으로부터의 반사파 즉 echo를 수신하는데 그 사이 경과 시간을 정밀하게 측정하여 공기 중의 초음파 속도와 곱하여 거리를 환산한다.
공기 중의 초음파 전달 속도는 340m/sec
초음파 센서는 주둥이형 센서의 높이가 1cm 정도이므로 50cm 거리 측정 실험에서 이 정도의 오차 범위 내에 있어야 한다.
물론 제품에 따라서 최대 ∼500cm 까지의 거리 측정이 가능하기도 하다.
최대 측정 거리는 수직으로 마주한 벽면을 대상으로 500 cm 이며 그 이상의 거리에서는 0 cm 라는 결과를 보여 준다. 한편 반사파가 돌아오지 못할 정도로 벽면에 기울여 초음파를 발사하는 경우에도 0 cm 라는 결과를 줄 수밖에 없다. 주변 환경 에서 보면 울퉁불퉁 튀어 나온 부분이 많기 때문에 갑자기 이상한 숫자를 보여 줄 수도 있음에 유의하자.
초음파 센서의 배선은 Vcc 는 반드시 5V 에 배선한다. 3.3V에서도 동작할 수 있다고는 하나 측정 거리가 짧아질 수 도 있음에 유의하자. Trig 와 Echo는 아래 그림에서 2번과 3번에 배선되어 있지만 RC카에서는 모터쉴드가 3번 핀에서 부터 12번 핀까지 모조리 사용하기 때문에 유일하게 남은 핀은 2번과 13번 핀이다. ECHO는 2번 핀 TRIG는 13핀에 배선하자.
초음파 센서를 사용하기 위한 특별한 라이브러리 지원은 별도로 없다.
마이크로 세컨드 단위로 경과 시간 정수형 변수 us를 설정한다.
cm 단위로 하는 대상물과의 거리를 정수형 변수 cm 으로 설정한다.
setup()에서 통신 속도와 ECHO 및 TRIG 핀의 모드를 설정한다. TRIG는 초음파를 발사하라는 듀티 신호를 SR-04 보드에 보내야 하므로 출력 즉 OUTPUT 이다. 반면에 ECHO 핀은 SR-04 보드로부터 듀티 신호를 받는 핀이므로 INPUT 으로 설정해야 한다.
TRIG 듀티의 시간 폭은 10 마이크로 세컨드로서 delayMicroseconds()를 사용한다. 경과 시간은 pulseln(ECHO,HIGH) 명령에서 ECHO 핀이 LOW에서 HIGH로 변화 시작하는 시점을 체크하여 지속된 시간이 끝나고 LOW로 바뀌는 시점까지 경과 시간을 측정한다.
이 초음파 거리 측정 코드를 그대로 블루투스 RC카 코드에 옮기자.
경기 꿈의 대학 여섯 번째 주의 HC-06 블루투스 조종 RC카 코드는 그대로 살아 있으며 스마트폰 앱도 그대로 사용이 가능하다. 단지 loop() 시작 부분에 초음파에 의한 장애물과의 거리를 측정하는 루틴이 부가되었을 따름이다. 이 코드를 업로딩하여 실행 시켰을 때에 RC 카가 30cm 전방의 장애물 발견 시 멈추게 된다. 이 범위 안에서도 주행이 가능하지만 loop() 문 실행 속도가 제법 빠르므로 찔끔 찔끔씩은 움직임이 가능하다. 따라서 후진하여 30cm를 벗어나면 자유롭게 주행이 가능하다.
#RCCAR_BT_ULTRASONIC_01
#define ECHO 2
#define TRIG 13
#include <AFMotor.h>
AF_DCMotor motor1(3);
AF_DCMotor motor2(4);
int mspd = 180;
char command;
void setup() {
Serial.begin(9600);
pinMode(TRIG,OUTPUT);
pinMode(ECHO,INPUT);
Stop();
delay(11000);
}
void loop() {
digitalWrite(TRIG,HIGH); //send Pulse
delayMicroseconds(10);
digitalWrite(TRIG,LOW);
int us = pulseIn(ECHO,HIGH); //get return time
int cm = us/58;
Serial.print("cm : ");
Serial.println(cm);
if( cm < 30 ) {
Stop();
delay(50);
}
if(Serial.available() > 0){
command = Serial.read();
// if( command == 'F') {
if( command == 'G' || command == 'g' || command == 'F') {
forward();
delay(50);
}
// if( command == 'B') {
if( command == 'B' || command == 'b' || command == 'BK') {
back();
delay(50);
}
// if( command == 'L') {
if( command == 'L' || command == 'l' || command == 'LA') {
left();
delay(50);
}
// if( command == 'R') {
if( command == 'R' || command == 'r' || command == 'h') {
right();
delay(50);
}
// if( command == 'S') {
if( command == 'S' || command == 's' || command == 'st') {
Stop();
delay(50);
}
}
}
void forward() {
motor1.setSpeed(mspd); //Define maximum velocity
motor1.run(FORWARD); //rotate the motor clockwise
motor2.setSpeed(mspd); //Define maximum velocity
motor2.run(FORWARD); //rotate the motor clockwise
}
void back() {
motor1.setSpeed(mspd);
motor1.run(BACKWARD); //rotate the motor counterclockwise
motor2.setSpeed(mspd);
motor2.run(BACKWARD); //rotate the motor counterclockwise
}
void left() {
motor1.setSpeed(mspd); //Define maximum velocity
motor1.run(FORWARD); //rotate the motor clockwise
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}
void right() {
motor1.setSpeed(0);
motor1.run(RELEASE); //turn motor1 off
motor2.setSpeed(mspd); //Define maximum velocity
motor2.run(FORWARD); //rotate the motor clockwise
}
void Stop() {
motor1.setSpeed(0);
motor1.run(RELEASE); //turn motor1 off
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}
//끝
생각보다 정밀도가 후덜덜입니다. ㅋㅋㅋㅋ
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
고교생도 한번 설명해 주면 주당 2시간 7주면 쉽게 만들 수 있습니다.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
ㅎㅎㅎ 코딩아트님이 설명해주셔서 그렇져. 멋지십니다, ㅎㅎ
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit