Embedded Lecture/Arduino2017. 4. 16. 21:57


시중에서 쉽게 구할 수 있는 저가형 초음파 센서 모듈(HC-SR04)는 그림과 같이 4핀 인터페이스를 갖습는다. VCC/GND는 5V 전원핀이고 Trig는 초음파를 발생시키는 펄스 신호를 내보내는 핀이며, Echo 핀은 반사파가 감지되었음을 알려주는 신호선으로 측정된 거리에 해당하는 High level 펄스를 출력합니다. 그러므로 이 모듈을 사용하기 위해서는 Arduino Uno의 2개의 디지털 핀이 필요하게 됩니다.



HC-SR04, 초음파 센서는 정밀도가 3mm정도로 2~400cm 까지의 거리를 초음파를 이용하여 측정할 수 있으며, 이 모듈에는 초음파 송수신, 제어회로가 모두 내장되어 있어서 마이크로컨트롤러를 이용하면 비교적 손쉽게 응용이 가능하다는 것입니다. 기본원리는 다음과 같습니다. 우선 Uno 보드로 모듈의 Trig 핀으로 약 10us 정도의 High level 펄스를 보냅니다.



그러면 모듈의 내부에서는 40KHz의 초음파를 정면으로 발사하고 나서 장애물에 반사되어 오는 초음파를 감지합니다.



신호가 반사되어 되돌아오면 모듈에서 Echo 핀을 통해 마이크로컨트롤러의 IO로 측정거리만큼의 High level 펄스 신호를 보내줍니다.



마이크로컨트롤러에서는 모듈에서 받은 High 펄스의 시간(High 펄스 폭)을 계산해서 다음 식에 의해 거리로 환산합니다. 여기서 초음파는 장애물은 만나기 전과 만난 후 반사되어 되돌아가기 때문에 왕복으로 2로 나누어야 합니다. 이와 같은 일련의 과정을 계속 반복하여 거리 측정값을 업데이트 할 수 있습니다.


측정거리 = (High level 펄스 시간 x 음속(340m/s)) / 2


위 초음파 센서 모듈을 이용하기 위해서는 쉬운 방법으로 아두이노의 NewPing 라이브러리가 필요한데, 압축된 zip 파일을 다운로드 받은 후에 다음과 같이 Arduino IDE에서 등록할 수 있습니다.


스케치 > Include Library > Add .ZIP Library


설치하였다면 다음과 같이 메뉴에 항목이 새로 만들어진다. 이것을 선택하면 스케치 파일에 #include “NewPing.h” 행이 추가되어 라이브러리 함수를 사용할 수 있게 됩니다.



다음은 NewPing 라이브러리를 이용한 거리 측정 예제입니다. 여기 Trig는 2번 핀에 Echo는 3번 핀에 연결되었다고 가정합니다.


#include <NewPing.h>

#define TRIGGER_PIN 2

#define ECHO_PIN 3

NewPing sonar(TRIGGER_PIN, ECHO_PIN);

void setup() {

  Serial.begin(9600);

}


void loop() {

  float fDist = (float)sonar.ping()/US_ROUNDTRIP_CM;  // 반사파가 감지될 때 까지의 시간을 us 단위의 정수로 반환

                                                               // US_ROUNDTRIP_CM는 us를 cm단위로 바꾸어주는 상수

  Serial.print("Ping: ");

  Serial.print(fDist);

  Serial.println(" cm");

  Serial.println();

  delay(300);

}


NewPing sonar(trigger_pin, echo_pin [, max_cm_distance])는 해당되는 핀 번호 두 개와 최대 측정 거리(디폴트값 500 cm)를 주게 되어 있으며 최대 측정 거리는 생략할 수도 있습니다. 이 라이브러리는 다양한 함수를 제공하고 있으며 여기서 사용할 함수는 sonar.ping()으로, 이 함수는 초음파가 발사되고 그 반사파가 감지될 때까지 걸린 시간을 microsecond 단위의 정수로 반환합니다. 따라서 이 값을 라이브러리에 이미 정의된 상수 US_ROUNDTRIP_CM으로 나누면 장애물까지의 거리를 cm단위로 얻을 수 있습니다. 만일 감지 가능 거리 내에 장애물 없다면 0을 반환합니다.


위에서 fDist 변수값을 구하는데 sonar.ping() 함수의 반환값을 정확한 값을 계산하기 위해서 float로 변환(forcing)하였습니다. 결국 NewPing sonar() 함수는 지정된 Trig 핀에 초음파 센서를 구동하기 위한 10us 펄스를 내보내고, 지정된 Echo 핀에서는 측정 거리에 비례하는 HIGH 펄스 신호의 폭을 계산하는 루틴이 포함되어 있습니다.


다음은 NewPing 라이브러리를 사용하지 않고 거리를 측정하는 예제입니다.


#define TRIGGER_PIN 2

#define ECHO_PIN 3


void setup() {

  Serial.begin(9600);

  pinMode(TRIGGER_PIN, OUPUT); // 핀 모드를 출력으로 설정합니다.

  pinMode(ECHO_PIN, INPUT); // 핀 모드를 입력으로 설정합니다.

}


void loop() {

  float fDist;

  digitalWrite(TRIGGER_PIN,HIGH); 

  delayMicroseconds(10); // 10us 지연

  digitalWrite(TRIGGER_PIN, LOW); // 10us의 트리거 신호를 만들어 보냅니다.

  fDist = (float)pulseIn(ECHO_PIN, HIGH)/US_ROUNDTRIP_CM;

  Serial.print("Ping: ");

  Serial.print(fDist);

  Serial.print(" cm");

  Serial.println();

  delay(300); // 0.3s 대기 후 다시 측정합니다.

}

위 예제에서 사용된 pulseIn(pin, value, timeout)는 지정된 핀에 value는 'LOW' 혹은 'HIGH' 값으로, 'LOW'이면 low 펄스 구간의 폭을 'HIGH' 이면 high 펄스 구간의 폭을 측정하여 microsecond 단위로 반환합니다. 이 반화값의 자료형은 unsigned long 형으로 계산의 정확도를 위해서 float 형으로 변환(forcing)하였습니다. 세 번째 인수 timeout은 시간 제한으로 생략할 수 있으며 이 함수는 10us에서 3분까지 측정할 수 있습니다. 이러한 거리 측정은 0.3초 간격으로 반복됩니다.



Posted by Nature & Life