본문 바로가기
Embedded SW/[Infineon] TC275 Lite Project

초음파 센서 원리, 자동차 장착 및 동작 확인 (인피니언 MCU)

by 방구석 임베디드 2021. 12. 24.
반응형

안녕하세요.

오늘은 초음파 센서를 

자동차에 장착하고 초음파센서를 통하여 거리정보를 받아서, 

자동차를 세워보는 동작을 수행해 보도록 하겠습니다.

 

참고로 이 글은 계속 연재하는 글이여서,

처음부터 보시려면 아래 링크를 참조해 주세요.

 

1) 임베디드 SW, MCU에 대한 정리 (feat. 임베디드 SW 비전)

https://embeddedchallenge.tistory.com/210

2) MCU 개발 장비 구매 방법 정리 (인피니언 MCU TC275 Lite)

https://embeddedchallenge.tistory.com/211

3) 임베디드 SW 개발 환경 세팅 방법 정리 (소스코드 편집기, 컴파일러, 디버거 환경 설정 방법)

https://embeddedchallenge.tistory.com/212

4) 인피니언 IDE Tool 사용방법 정리 (프로젝트 생성 및 다운로드 수행)

https://embeddedchallenge.tistory.com/219

5) 인피니언 MCU LED Blinking (TC275 GPIO 설정)

https://embeddedchallenge.tistory.com/225

6) 인피니언 MCU Clock, 오실레이터 에 대한 이해 (TC275 보드에서 확인)

https://embeddedchallenge.tistory.com/226

7) 인피니언 MCU PLL 설정 및 주변기기 Clock 설정 (TC275)

https://embeddedchallenge.tistory.com/227

8) 인피니언 MCU 인터럽트/Interrupt 설정 (TC275 동작 확인)

https://embeddedchallenge.tistory.com/228

9) 스케줄링(scheduling)에 대한 정리, 인피니언 MCU Scheduler 설계 정리

https://embeddedchallenge.tistory.com/229

10) PWM이란 무엇인가? 인피니언 MCU를 이용한 PWM 설계 수행

https://embeddedchallenge.tistory.com/232

11) Motor Driver L298N 사용법 정리 (인피니언 MCU 개발)

https://embeddedchallenge.tistory.com/235

12) DC모터 드라이버 설계, RC카 전진,후진,회전 설계 (인피니언 MCU PWM, GPIO 설정)

https://embeddedchallenge.tistory.com/236

13) UART 통신 정리, UART 통신 MCU 설계 (인피니언 MCU)

https://embeddedchallenge.tistory.com/237

14) Teraterm 시리얼 통신 터미널 프로그램 사용법, 다운로드 방법 (feat 허큘리스)

https://embeddedchallenge.tistory.com/238

15) Logic analyzer 사용법 (saleae 로직 분석기 사용법 정리)

https://embeddedchallenge.tistory.com/239

16) UART 통신 MCU Driver 초기화 설계 및 동작 확인 (Tx, Rx Interrupt)

https://embeddedchallenge.tistory.com/240

17) ADC 설명 정리 및 인피니언 MCU ADC 설계 요소 정리

https://embeddedchallenge.tistory.com/241

18) ADC를 이용하여 GP2Y0A21YK 적외선 센서 거리 측정 (TC275 MCU)

https://embeddedchallenge.tistory.com/264

19) 적외선 센서를 이용한 장애물 탐지 차량 주행 (TC275 MCU)

https://embeddedchallenge.tistory.com/265

 

1. 초음파 센서란 무엇인가?

먼저 우리는 초음파 센서사 무엇인지에 대해서 알아야 합니다.

우리는 사람이 말을 하면 알아들을 수 있습니다.

공기의 진동으로 우리는 정보를 전달하고 수신합니다.

그런데 그 진동이 더 고주파가 된다면 인간은 그 소리를 알아 들을수가 없습니다.

가청주파수는 20KHz로 사람은 보통 이 주파수보다 높아지면 알아 들을수가 없습니다.

초음파는 아래와 같이 가청주파수를 넘어서서

아래 노랑색 대역의 주파수를 가지는 음파입니다.

초음파센서란 20KHz가 넘는 음파를 발사하여

물체의 거리를 측정하는 센서를 의미합니다.

우리가 사용할 초음파센서는 HC-SR04로서 아래와 같이 생겼습니다.

이 초음파 센서는 40KHz의 음파가 발사합니다.

그래서 아래와 같이 물체에 반사하여 다시 음파가 들어가게 됩니다.

아래 Datasheet를 살펴 보도록 하겠습니다.

아래와 같이 초음파를 발사시키면,

센서Output에서는 아래와 같은 사각파를 내보내줍니다.

이 사각파는 초음파가 발사되고 반사되어 돌아온 시간을 의미합니다.

음파의 속도는 340m/s 입니다.

1초에 340m 이동합니다.

따라서 1cm 이동하는데 29us가 걸립니다. (1/34000 = 29us)

그렇다면

1 : 29 = x : time

x = time/29 가 됩니다.

그런데 x는 발사하고 반사되어 돌아온 거리이기 때문에

실제거리는 x = 2d 입니다.

d는 distance를 의미합니다.

 

따라서 

d = time/29/2로 계산이 되어야 합니다.

 

 그러면 초음파 발사는 어떻게 시켜야 하는 것일까요.

아래와 같이 Trigger Input 핀을 High로 10us이상 유지시켜주면 초음파가 발사됩니다.

그리고 적당한 시간에 Low를 내려주고

다시 High로 올려서 발사를 시켜주면 됩니다.

 

하지만 발사를 시킬때 다음번 High를 올리기 까지 60ms이 넘는 시간 뒤에 High를 올리도록 

Datasheet는 아래와 같이 언급하고 있습니다.

 

이제 설계를 해보도록 하겠습니다.

 

2. 초음파센서를 통해 거리를 측정해 보자

2가지 주변기기를 사용하여 설계를 수행해야 할 것입니다.

 

MCU와의 연결은 아래와 같이 수행합니다.

P33.10 : Echo -> GTM 에 연결

P33.7 : Trig -> GPO에 연결

전압 5V와 GND에 나머지 Pin 연결

Trigger 핀은 GPO를 이용하여 Digital Output을 이용하여 줄 것입니다.

그리고 거리를 사각파형태의 시간을 통하여 생성되는 Echo는 GTM(General Timer Module) 모듈로 받아서

사각파의 Rising, Falling Edge에 Interrupt를 발생시켜서

그 사이의 시간을 측정할 것입니다.

 

이 시간을 이용하여 거리 환산을 해보도록 하겠습니다.

 

코드는 아래와 같습니다.

 

1) 아래와 같이 p33.7 포트를 Digital Ouput으로 초기화 합니다.

    /*P33_7    Digital Output*/
    IfxPort_setPinModeOutput(IfxPort_P33_7.port, IfxPort_P33_7.pinIndex, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
    IfxPort_setPinLow(IfxPort_P33_7.port, IfxPort_P33_7.pinIndex);

 

 

2) 이 핀을 High로 올리고 1ms뒤에 Low로 내려서 Tirgger 신호를 센서로 보내주도록 설계합니다.

이렇게 되면 초음파 센서는 음파를 발사할 것입니다.

그리고 다음번 음파는 100ms 뒤에 보내도록 설계합니다.

아래와 같이 1ms에 할당하는 함수를 만들었습니다.

이 함수는 위와 같이 동작을 합니다.

void Unit_UltraSenseTrig(void)
{
    static uint32_t ulUltraSenseCnt = 0u;

    if(ulUltraSenseCnt == 0u)
    {
        gulUltraStartFlag = 1u;
        MidDio_SetUltraTrig(1u);
    }
    else if(ulUltraSenseCnt == 1u)
    {
        MidDio_SetUltraTrig(0u);
    }
    else
    {
        /*No Code*/
    }

    ulUltraSenseCnt++;
   
    if(ulUltraSenseCnt >= 100u)
    {
        ulUltraSenseCnt = 0u;
        gulUltraStartFlag = 0u;
    }
}

이제 Trigger는 만들었으니

 

Echo 부분을 어떻게 설계하였는지 알아 보도록 하겠습니다.

위와 같이 Rising, Falling때 인터럽트가 발생하도록 설계할 것입니다.

물론 GTM TIM 모듈을 이용해서요.

이렇게 TIM 모듈을 이용하여 인터럽트를 생성하게 되면

아래와 같이 인터럽트 함수가 수행되어서, rising과 falling일때 시간을 획득하도록 설계합니다.

STM0_TIM0라고 적힌 부분은 System Timer Module의 Clock Counter입니다.

시간점과 끝지점의 시간정보를 가지고 와서,

그 차이를 us 단위로 계산합니다.

그 값이 fReultTemp에 저장이 됩니다.

그리고 이 값을 앞서 이야기한

거리 환산 수식에 집어넣어서

최종적인 거리값을 획득합니다.

이제 fUltraDistance라는 거리값을 이용하여 자동차에 적용해 보도록 하겠습니다.

 

3. 자동차에 초음파센서를 이용하여 장애물 탐지후 멈추어 보도록 설계

void Unit_UltraTest(void)
{
    uint8_t u8nuWirelessCmd = 0u;
    float32_t fDuty =0.5f;
    
    if(fUltraDistance > 50.0f)
    {
        fDuty = 0.5f;
    }
    else if(fUltraDistance > 30.0f)
    {
    fDuty = 0.2f;

    }
    else if(fUltraDistance > 10.0f)
    {
    fDuty = 0.1f;

    }
    else if(fUltraDistance > 5.0f)
    {
    fDuty = 0.1f;

    }
    else
    {
        fDuty = 0.0f;
        gu32nuAscRxData = 's';
    }

    DrvGtmPwmTest(fDuty,fDuty,fDuty,fDuty);

    u8nuWirelessCmd = (uint8_t)gu32nuAscRxData;
    
    if(u8nuWirelessCmd == 'w')    /*Forward*/
    {
        Unit_MotorFrontDirectionCtl(MOTOR_FWD);
        Unit_MotorRearDirectionCtl(MOTOR_FWD);
    }
    else if(u8nuWirelessCmd == 'd') /*TurnRight*/
    {
        Unit_MotorFrontDirectionCtl(MOTOR_TURN_RIGHT);    
        Unit_MotorRearDirectionCtl(MOTOR_TURN_RIGHT);
    }
    else if(u8nuWirelessCmd == 'a') /*TurnLeft*/
    {
        Unit_MotorFrontDirectionCtl(MOTOR_TURN_LEFT);    
        Unit_MotorRearDirectionCtl(MOTOR_TURN_LEFT);
    }
    else if(u8nuWirelessCmd == 'x') /*Reverse*/
    {
        Unit_MotorFrontDirectionCtl(MOTOR_REVERSE);    
        Unit_MotorRearDirectionCtl(MOTOR_REVERSE);
    }    
    else if(u8nuWirelessCmd == 's') /*Stop*/
    {
        Unit_MotorFrontDirectionCtl(MOTOR_STOP);    
        Unit_MotorRearDirectionCtl(MOTOR_STOP);
    }
    else
    {
        /*No Code*/
    }  

}

아주 간단한 함수를 하나 만들었습니다.

거리가 가까워지면,

모터를 구동하는 PWM Duty를 낮추어서

자동차를 멈추는 코드입니다.

 

그렇다면 지금부터 동작을 살펴 보도록 하겠습니다.

 

장애물앞에서 속도를 줄였지만 박았네요. ㅎㅎ

Duty 값을 조금더 변경해 보도록 하겠습니다.

 

 

훨씬 좋네요 ㅎㅎ

 

사실 초음파센서를 이용하는 가장큰 설계방법의 핵심은

GTM TIM을 이용하여 Edge를 Detection하여 어떻게 ISR(Interrupt Sevice Routine)을 띄울것인가?

가 핵심입니다 ㅎㅎ

 

이 부분은 추후, GTM TIM에서 조금더 자세히 다루어 보도록 하겠습니다.

 

추가적인 질문은 아래 홈페이지에서 문의사항을 남겨주세요.

https://cafe.naver.com/binaryembedded

 

임베디드 유니버스 : 네이버 카페

임베디드 유니버스 : 임베디드의 세계로 초대합니다.

cafe.naver.com

오늘은 이것으로 포스팅을 마치도록 하겠습니다.

감사합니다.

반응형

댓글