[아두이노] 초음파 거리 센서 : HC-SR04 (with 3m 연장선)

    이전에 적외선 거리 센서를 다뤘습니다.

    https://conceptbug.tistory.com/entry/아두이노-적외선-거리-센서-GP2Y0A21-IR-C29-with-3m-연장선

     

    [아두이노] 적외선 거리 센서 : GP2Y0A21 IR - C29 (with 3m 연장선)

    거리를 측정해야 할 일이 있는데 아두이노와 쉽게 호환되는 센서 종류로는 대~충 3가지가 있는 것 같습니다. 적외선 센서 초음파 센서 LIDAR 센서 해당 제품은 적외선을 통해 거리를 측정하는 센

    conceptbug.tistory.com

    사실 사용할 환경이 워낙 특이 케이스라서 LIDAR는 너무 비싸고.. 적당한 적외선과 초음파 센서를 둘 다 사서 써보자 하는 마음으로 구매했습니다.

    동작 원리는 적외선 센서와 크게 다를것이 없습니다.

    사용자가 초음파를 발생시키면 발신부에서 발사된 초음파는 물체에 맞고 반사되어 다시 수신부로 들어옵니다.

    이 때 발생된 시간과 소리의 속도를 이용하여 거리를 계산합니다.

    측정 매개체가 '빛'이 아닌 '소리'이기 때문에 비교적 야외 환경에 대한 저항력을 기대할 수 있을거라 생각했고, 가격도 저렴할 뿐더러 측정 가능한 범위까지 더 깁니다.


    Environment

    적외선 센서와 동일한 환경입니다.

    대한민국의 4계절을 모두 야외에서 있을 녀석으로 극한의 환경에 노출되어 있을 것입니다.

    적외선과 초음파를 둘 다 테스트 해봐야 하기 때문에 동일 위치에 두 종류의 센서를 모두 부착하여 어느것의 신뢰도가 더 높은지 테스트 할 것입니다.

    이 센서도 3m의 연장선을 사용했습니다.


    Specification

    제품명 : HC-SR04

    가격 : 3,200원 (VAT 별도)

    거리 측정 범위 : 2cm ~ 400cm

    동작 전압 : 5V

    실효각 : 15°

    해상도 : 3mm

    케이블/포트

    • Vcc
    • Trig (디지털 출력핀)
    • Echo (디지털 입력핀)
    • GND

    Test Code

    아래는 테스트용 코드 원문입니다.

    #define trigPin 22 // digital output
    #define echoPin 23 // digital input
    
    float distance = 0;
    float duration = 0;
    
    void setup()
    {
        Serial.begin(115200);
        Serial.println("Setup in progress...");
        pinMode(trigPin, OUTPUT);
        pinMode(echoPin, INPUT);
    }
    
    void loop()
    {
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        duration = pulseIn(echoPin, HIGH);
        distance = duration * 0.017;
    
        if ((distance > 2.0) && (distance < 400)) {
            Serial.print("Distance : ");
            Serial.print(distance);
            Serial.println("cm");
        }
        else {
            Serial.println("Measurement out of range!");
        }
    }

    trig 핀은 22번 디지털 출력 핀으로, echo 핀은 23번 디지털 입력 핀으로 설정합니다.

    음파가 발신부를 떠나 수신부로 도달한 시간과 계산한 거리값을 저장할 변수를 선언하고 초기화 합니다.

    loop()문의 처음 5줄이 거리를 구하는 부분이라고 생각하시면 됩니다.

    위 그림은 거리를 측정하는 일련의 과정에서 생성하고 읽어야 하는 신호들을 그림으로 표현한 것입니다.

    먼저 trig 핀을 통해 펄스 신호를 만들어줘야 합니다.

    정리를 하면 이런 과정이죠.

    이후 pusleIn() 함수를 이용해 echo 핀에서 수신된 펄스 신호의 주기를 duration에 저장합니다.

    이제 일종의 수학 계산이 필요한데, 초음파의 속력은 340m/sec 입니다.

    현재 프로그램에서 다루는 시간의 단위는 𝜇(micro) 초에 해당되고, 제가 나타내고 싶은 단위는 cm이기 때문에 단위 환산을 해야 합니다.

    그리고 이 시간은 음파가 물체까지 도달한 왕복 거리이므로 마지막에 2를 나눠줘야 하죠.

    이 계산을 모두 끝내면 duration에 저장된 값에 0.017만 곱해주면 됩니다.

    마지막으로 센서의 유효 측정 범위를 고려해 if()문으로 거리값을 출력합니다.


    Code with Smoothing

    이번에도 노이즈를 줄이기 위해 평균 필터를 적용해 봤습니다.

    #define trigPin 22 // digital output
    #define echoPin 23 // digital input
    
    float distance = 0;
    
    float getDistance(int count) {
        float sum = 0;
    
        digitalWrite(trigPin, LOW);
        for (int i = 0; i < count; i++) {
            digitalWrite(trigPin, HIGH);
            delayMicroseconds(10);
            digitalWrite(trigPin, LOW);
            float duration = pulseIn(echoPin, HIGH);
            float range = duration * 0.017; // ((340 * duration) / 10000) / 2
            sum += range;
        }
    
        return (sum / count);
    }
    
    void setup()
    {
        Serial.begin(115200);
        Serial.println("Setup in progress...");
        pinMode(trigPin, OUTPUT);
        pinMode(echoPin, INPUT);
    }
    
    void loop()
    {
        distance = getDistance(10);
        if ((distance > 2.0) && (distance < 400)) {
            Serial.print("Distance : ");
            Serial.print(distance);
            Serial.println("cm");
        }
        else {
            Serial.println("Measurement out of range!");
        }
    }

    제가 수동으로 테스트했을 때, 확실히 값이 덜 튀는 것 같습니다.


    마무리

    저의 뇌피셜로는 일단 구동 환경 때문에 적외선 보다는 초음파 센서가 외란의 영향이 덜 할 것으로 생각됩니다.

    하지만 테스트할 때 한계점을 발견할 수 있었습니다.

    앞서 제품의 스펙에 대해 다룰때 실효각이라는 항목이 있었는데 위의 그림이 그 실효각을 나타내주는 제품의 성능 그래프입니다.

    방위각 좌표로 그려졌으며 0°를 기준으로 거리가 멀어질수록 좌우 15° 내외로 정확한 값이 나오는 것을 볼 수 있습니다.

    따라서 제가 테스트했을 때는 일정 거리를 넘어서면, 이 15°라는 실효각 때문에 내가 측정하고자 하는 물체 주위에 다른 물체가 있을 때 원하는 거리값을 얻기 힘들 수 있다는 얘기죠.

    위 그림을 예시로 들어보겠습니다.

    주황색 실린더가 제가 거리를 측정하고자 하는 타겟이고, 다른 물체들이 실효각 안에서 더 가까이 존재합니다.

    이런 경우 음파는 녹색 실린더에 먼저 맞고 반사되어 실제로 측정하고자 하는 1m와는 다른 값이 측정될 것입니다.

     

    다행히도 제가 측정하고자 하는 수준이 이렇게 정밀할 필요는 없습니다.

    다만, 정확한 지점의 거리를 알고자 하는 사용자는 음파가 아닌 빛을 이용한 적외선 센서나 LIDAR를 사용하는 것이 옳은 선택일 것 같습니다.

    댓글

    Designed by JB FACTORY