[아두이노] [강좌] 9. digitalWrite()/digitalRead() 실습 – 초음파 센서

디지털 함수에 대해 알아봤으니두 함수를 이용한 센서를 실습해보자이번 실습에 사용될 센서는 거리를 측정하는 초음파 센서사실, pinMode() 함수 설명할 때 약속했었기 때문에 예정에 없던 실습을… ㅋㅋ

brown_and_cony-54


초음파 센서는 아래 사진처럼 생겼다. (아래 부분의 빨간 색 판은 무시해도 된다.) 초음파 센서의 이름은 “NT-TS601”.

75a268fb2d3a256a1c7c01573701f1b2.jpg


 

초음파 센서에는 연결 핀이 3개인 종류와 4개인 종류가 있는데여기서 실습할 초음파 센서는 핀이 3개인 초음파 센서이다. 

 

하나의 핀으로 데이터를 출력하고 입력도 받는 방식을 사용하기 때문에 실습용으로 골랐음핀이 4개인 초음파 센서도 동작 방식은 대부분 비슷하다.

 

초음파 센서의 연결 핀 3개는 각각 VCC, GND, SIG 핀으로 이루어진다. VCC 5V에 연결하면 되고, GND GND에 연결, SIG 핀은 아두이노 핀 중 아무 핀에나 꽂아도 된다디지털 입출력으로 쓸꺼니까 아무 핀에나.

 

첨부 파일에 디바이스마트(devicemart.co.kr)에서 제공받은 사용자 매뉴얼 파일을 첨부해뒀으니 센서에 대한 자세한 내용은 파일을 참고하도록 하고여기서는 동작에 필요한 내용들만 살펴보도록 하자.

 

 

다음은 매뉴얼 중 동작 방법에 대한 부분만 캡쳐한 것이다.


62123c7b7bf51e56031e2856be3a5503.png


정리하면 동작 순서는 다음과 같다.

 

1.     SIG 핀의 기본 출력은 ‘LOW’. (아두이노  초음파 센서)

2.     센서를 동작하기 위한 시작 신호로 SIG 핀에 최소 5마이크로초 동안 HIGH 신호를 출력한 후 다시 LOW 출력. (아두이노  초음파 센서)

3.     그러면 초음파 센서에서는 송신부를 통해 초음파 발사 (초음파 센서)

4.     SIG 핀으로 HIGH 출력 (초음파 센서 → 아두이노)

5.     발사한 초음파가 물체에 부딪혀 수신부로 입력 (초음파 센서계속 HIGH 출력 유지)

6.     SIG 핀으로 LOW 출력 (초음파 센서 → 아두이노)

7.     SIG 핀이 HIGH를 유지했던 시간을 측정하여 거리 값 계산 (아두이노)

8.     다시 초음파 센서를 측정하기 위해서 최소 200마이크로초 간격 필요

 

 

쉬운가?

 

유의해야 할 점은 SIG 핀이 출력으로 사용되기도 하고 입력으로 사용되기도 한다는 점.

 

1, 2번 단계에서는 SIG 핀이 아두이노에서 초음파 센서로 신호를 출력하는 출력’ 모드로 사용된다그리고 4~6번 단계에서는 초음파 센서에서 아두이노로 신호를 보내는 것이므로 아두이노 입장에서는 입력’ 모드로 사용되어야 한다핀의 모드가 바뀌는 것.

 

 

혹시 핀이 4개인 초음파 센서를 가지고 있다면 1, 2번 단계에서 사용하는 핀과 4~6번 단계에서 사용하는 핀이 따로 있다고 생각하면 된다이 경우에는 입력 모드로 사용하는 핀과 출력 모드로 사용하는 핀이 다르기 때문에 핀의 모드를 바꿀 필요는 없다.

 

 

그럼 실습을 시작해볼까?

 

우선 초음파 센서와 아두이노 보드를 연결해보자다음 연결 그림 참고.

 

b53bbac5ba73b12a4226f9a45361fb7e.png


VCC 핀에 5V 전원을 연결하고 GND끼리 연결해준다그리고 SIG 핀에 아두이노 보드의 11번 핀을 연결해주었다. (이제 나름 익숙할 테니 보드 연결 사진은 따로 찍지 않았다.) 

  

이제 소스를 짜볼까스케치에서 제공하는 예제 소스가 아니라 직접 작성하는 첫 예제 소스이니 하나씩 차근차근 설명하겠다.

 

 우선 setup() 소스에는 시리얼 모니터에 값을 출력 하기 위한 초기화 구문이 들어가야겠지측정된 거리를 확인해야 하니까원래는 핀의 모드를 설정하는 pinMode() 함수도 setup() 함수에 들어가야겠지만, SIG 핀은 모드가 계속 바뀔 예정이므로 setup() 함수에 넣지 않았다.



 void setup() {

   Serial.begin(9600);

 }



그리고 1번 단계를 진행하기 위한 소스를 loop() 함수에 넣어보자. 1번 단계는 SIG 핀의 기본 출력이 ‘LOW’라는 것이고이를 위해서는 핀의 모드가 출력이어야하므로,



   pinMode(11, OUTPUT);

 digitalWrite(11, LOW);

    delay(1);



이라고 하면 되겠다. 8번 단계에서 이전 동작과 다음 동작 사이에 최소 200마이크로초만큼의 시간 간격이 있어야 된다고 했으므로넉넉히1밀리초만큼 딜레이를 준다.

 

그 다음 2번 단계시작 신호로 5마이크로초 동안 HIGH 신호를 출력한 후 다시 LOW를 출력해야하니까,



   digitalWrite(11, HIGH)

   delayMicroseconds(10);

   digitalWrite(11, LOW);



delayMicroseconds() 함수는 마이크로초 단위로 딜레이를 줄 수 있는 함수이다. delay() 함수는 밀리초 단위로 딜레이.

 

매뉴얼에 최소 5마이크로초만큼 유지해야 한다고 되어 있으니넉넉히 10마이크로초를 주자핀에 HIGH 신호를 주고 10마이크로초만큼 딜레이 10마이크로초만큼 HIGH 신호를 유지하고다시 LOW 신호를 출력했다.

 

 

다음 3단계는 초음파 센서가 하는 일이니 넘어가고, 4단계부터는 초음파 센서가 아두이노 보드로 신호를 보내는 것이므로 그 전에 SIG 핀의 모드를 입력으로 바꿔야겠지.



   pinMode(11, INPUT);

 


 

여기서부터 조금 헷갈린다. 4~6단계를 보자.

 

초음파 센서가 HIGH를 출력하고 초음파가 물체에 부딪혀 되돌아올 때까지 HIGH 신호를 유지하다가 신호가 되돌아오면 LOW 신호를 출력한다우리는 HIGH 신호가 유지되는 시간을 알아내야 한다.

 


어떻게??

 

두 가지 방법이 있다.

 

첫 번째 방법은 micros() 함수를 이용하는 방법. micros() 함수는 전원이 인가된 이 후로 얼마의 시간이 지났는지 마이크로초 단위로 반환하는 함수이다그래서 HIGH 신호가 들어오기 시작할 때의 시간을 저장하고다시 LOW 신호가 들어올 때(HIGH 신호가 끝날 때)의 시간을 비교해서 HIGH 신호가 유지된 시간을 계산하는 방법이다.

 

두 번째 방법은 pulseIn() 함수를 이용하는 방법. pulseIn() 함수의 기능은 지정한 핀으로 들어오는 신호가 HIGH 또는 LOW로 유지되는 시간을 계산해서 반환하는 것첫 번째에서 말한 방법이랑 같은데?

 

같다첫 번째에서 설명한 기능을 아두이노에서는 pulseIn()이라는 함수로 제공하고 있다. pulseIn() 함수의 구조는 다음과 같다.

 


 

unsigned long pulseIn(pin, value)

unsigned long pulseIn(pin, value, timeout)



  

 매개 변수

 

 pin : 신호를 읽어서 시간을 계산할 핀 번호

 

 value : 시간을 체크할 신호. HIGH/LOW 중에 선택.

 

 timeout : 타임아웃지정한 시간만큼 기다려도 신호의 변화가 없을 경우 기다림을 끝내고 ‘0’을 반환한다마이크로초 단위로 시간을 지정할 수 있으며지정하지 않을 수도 있다지정하지 않을 경우에는 1(=1,000,000마이크로초)로 자동 설정된다.

 


  

 반환 값

 

 time : value 값으로 지정한 신호가 유지된 시간을 마이크로초 단위로 반환한다신호가 시작되지 않았거나타임아웃 시간이 지날 경우 0을 반환한다






그럼 pulseIn() 함수를 이용해서 초음파 센서에서 출력하는 신호의 시간을 알아오자우리가 알아야 할 건 HIGH가 유지되는 시간이므로,



  unsigned long duration = pulseIn(11, HIGH);


 

‘duration’이 unsigned long 타입의 변수라는 건이제 설명 안 해도 알겠지타임아웃 시간은 주지 않았다.

 

시간을 알아왔으니 이제 거리 값으로 변환하는 일만 남았다.

 



brown_and_cony-79

어떻게?? ㅋㅋㅋㅋㅋㅋㅋ

 



초음파 센서의 사용자 매뉴얼에 다음과 같은 내용이 있다사용자 매뉴얼은 참 중요한 것.

 

253f408fbba26248f6c18fd6f906aa24.png


음속! 

 

친절하게 음속을 구하는 공식까지 제공하고 있으므로우리는 계산식을 그냥 쓰면 됨위 식에서 ‘T’는 현재 온도 값으로실온 25로 가정하고 거리를 구해보자.



  double dist = (331.5 + (0.60714 * 25.0)) * (((double)duration/1000000) / 2);



duration 값은 마이크로초 단위이므로 1,000,000을 나눠 초 단위로 바꿔줬다. duration 변수 앞에 “(double)”을 붙여 정수 타입이었던 값을 실수 타입으로 바꿔준 것에 유의그래야 1000000으로 나눴을 때 제대로 값이 나오기 때문에.

 

이렇게해서 나온 dist 값의 단위는 m(미터)이므로 cm(센티미터) mm(밀리미터)로 바꿔주려면 dist 값에 100이나 1000을 곱해주면 된다.

 

그리고는 시리얼 모니터에 출력.



  Serial.print(“Distance : “);

  Serial.print(dist*100);

  Serial.println(“cm");



Serial.print() 함수와 Serial.println() 함수의 차이는 매개 변수로 받은 문자열 또는 값을 출력한 후 줄바꿈을 하느냐하지 않느냐의 차이.



끝. 이게 다다. 어렵지 않았기를 바란다.




이제 소스 코드를 한꺼번에 모아볼까?



 UltraSonicTest.ino

  

int ultra = 11;

 

void setup() {

  Serial.begin(9600);

}

 

void loop() {

  pinMode(ultra, OUTPUT);

  digitalWrite(ultra, LOW);

  delay(1);

 

  digitalWrite(ultra, HIGH);

  delayMicroseconds(10);

  digitalWrite(ultra, LOW);

 

  pinMode(ultra, INPUT);

 

  unsigned long duration = pulseIn(ultra, HIGH);

  double dist = (331.5 + (0.60714*25.0))*(((double)duration/1000000)/2);

 

  Serial.print("Distance : ");

  Serial.print(dist*100);

  Serial.println("cm");

 

  delay(100);

}




핀 번호는 ‘ultra’라는 변수를 만들어 저장해줬다만약 핀 번호를 바꿀 일이 생겼을 때 ‘11’이라는 값을 일일이 찾아 바꿀 필요 없이 변수 값만 바꾸면 된다는 좋은 점.

 

마지막의 “delay(100);” 구문은 시리얼 모니터에 출력되는 값을 보기 쉽게 하기 위하여 추가했다사실 DigitalReadSerial 예제에서도 그렇고나는 loop() 함수 마지막에 딜레이를 좀 넉넉하게 주는 편인데, 이유는 왠지 아두이노 보드가 힘들어 보여서랄까… 좀 쉬엄쉬엄 일하라는 의미

 moon_and_james-12

 



업로드 한 후 시리얼 모니터를 열어보자오른쪽 하단의 보레이트 설정 주의. 9600 보레이트(또는 baud)로 설정되어야 한다.

 

c6483d77406733aa857aae45efb09701.png


위 화면처럼 나오는가초음파 센서 앞 쪽으로 손을 갖다 대보면서 거리 값이 맞게 변하는지 확인하자.

 

 

초음파 센서 실습 끝짝짝짝~

brown_and_cony-70

 

초음파 센서를 응용해서 만들 수 있는 작품은 무궁무진하다제일 대표적인 것이 자율주행로봇초음파 센서로 장애물을 감지하여 멈추거나 방향을 바꿔 주행할 수 있다또는 앞에 있는 물체의 거리를 읽어 음계가 다른 소리를 내는 거리 감지 피아노라던지또는 초음파 센서로 장애물을 감지해 경고음을 내는 시각 장애인용 지팡이라던지.


센서를 다루는 법에 대해 하나하나 익혀가면서이 센서들을 이용해 내가 무엇을 만들어볼까에 대한 고민을 하는 것도 아주 즐거운 일이다.

 

 

그럼즐거운 고민을 하며 이번 강좌는 여기서 끝안녕~

0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

임베디드 보드

번호 제목 글쓴이 날짜 조회수
18 아두이노 [강좌] 10. 아날로그 기능 - analogRead() 함수 icon 양재동메이커 03-14 11,384
17 아두이노 [강좌] 9. digitalWrite()/digitalRead() 실습 – 초음파 센서 icon 양재동메이커 03-14 8,766
16 아두이노 [강좌] 8. digitalRead() 함수(2) – 풀업 저항과 INPUT_PULLUP 모드 icon 양재동메이커 03-14 10,682
15 아두이노 [강좌] 7. digitalRead() 함수(1) - 스위치를 이용한 DigitalReadSerial 예제 icon 양재동메이커 03-14 9,486
14 아두이노 [강좌] 6. digitalWrite() 함수 실습 - LED 깜빡이기 icon 양재동메이커 03-14 8,480
13 아두이노 [강좌] 5. Blink 예제 해부하기(4) - digitalWrite()와 delay() icon 양재동메이커 03-14 7,359
12 아두이노 [강좌] 4. Blink 예제 해부하기(3) - pinMode() icon 양재동메이커 03-14 8,274
11 아두이노 [강좌] 3. Blink 예제 해부하기(2) - 함수 icon 양재동메이커 03-14 7,349
10 아두이노 [강좌] 2. Blink 예제 해부하기(1) icon 양재동메이커 03-14 7,923
9 아두이노 [강좌] 1. 아두이노 보드와 스케치 툴 icon 양재동메이커 03-13 7,998
8 아두이노 [강좌] 0. 아두이노, 시작. icon 양재동메이커 03-11 8,117
7 STM32 / MBED 19년 Mbed OS 동영상 강좌 List icon HelloMaker 03-11 7,857
6 STM32 / MBED MBED 수학 icon HelloMaker 03-11 7,651
5 STM32 / MBED MBED RTOS icon HelloMaker 03-11 7,316
4 STM32 / MBED MBED 파일 시스템 icon HelloMaker 03-11 7,352
3 STM32 / MBED MBED 통신 icon HelloMaker 03-10 7,848
2 STM32 / MBED MBED Timer icon HelloMaker 03-10 9,223
1 STM32 / MBED MBED 기본 구조 icon HelloMaker 03-10 6,670