HC-SR04 초음파 거리센서 실습 파이선 코드
초음파 센서는 40KHz의 펄스 신호를 출력하여 반사되어 돌아오는 펄스의 시간을 측정하여 거리를 계산한다. 여기서는 HC-SR04 초음파 센서를 사용한다. 초음파 센서의 자세한 스펙은 데이터 쉬트를 참고한다.
초음파 센서 데이터북 http://www.micropik.com/PDF/HCSR04.pdf
보통 초음파센서에는 4개의 신호선이 존재하는데 각 각 VCC, Triger, Echo, GND 신호가 된다. VCC 와 GND 는 5v 라인에 연결하고, Triger 핀과 Echo 핀은 라즈베리파이의 GPIO 핀에 연결해준다.아래는 센서의 외관과 핀 맵을 보여준다.
HC-SR04의 전기적 특성을 나타냈는데, 초음파 센서의 입력 전원으로 +5V를 공급하는것에 주의한다. 출력은 펄스를 받아 계산하므로 센서의 Trigger 신호는 GPIO 핀으로 받게 된다.
위 그림은 센서의 작동원리를 설명해주는 그림이다. 우선 triger 핀에 10us 정도의 High 신호를 주면 초음파센서는 40khz 펄스를 자동적으로 8번을 발생시키고 펄스를 발생시킨 직후에 echo 핀은 high 되고 반사된 초음파가 감지 되었을때 echo 핀이 low 가 된다. 이 Echo 핀이 high 였다가 low 가 되는데 걸리는 시간을 측정하여서 그 시간을 초음파의 속도/2(즉 58)로 나누면 거리가 나온다.
라즈베리파이와 연결도를 아래에 올린다. 주의할 점은 반드시 소스 코드에서 라즈베리파이에 할당한 핀 번호와 초음파 센서에 연결한 핀 번호는 반드시 일치해야 원하는 결과를 얻을 수 있다. 이런 사실은 GPIO 사용할 경우 필수적으로 확인해야 한다.
아래 파이선 코드를 참고한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #!/usr/bin/env python #-*- coding: utf-8 -*- import time import RPi.GPIO as GPIO #핀 넘버링을 BCM 방식을 사용한다. GPIO.setmode(GPIO.BCM) # HC-SR04의 트리거 핀을 GPIO 17번, 에코핀을 GPIO 27번에 연결한다. GPIO_TRIGGER = 21 //17 GPIO_ECHO = 16 //27 print "Ultrasonic Distance Measurement" # 초음파를 내보낼 트리거 핀은 출력 모드로, 반사파를 수신할 에코 피은 입력 모드로 설정한다. GPIO.setup(GPIO_TRIGGER,GPIO.OUT) GPIO.setup(GPIO_ECHO,GPIO.IN) try: while True: stop = 0 start = 0 # 먼저 트리거 핀을 OFF 상태로 유지한다 GPIO.output(GPIO_TRIGGER, False) time.sleep(2) # 10us 펄스를 내보낸다. # 파이썬에서 이 펄스는 실제 100us 근처가 될 것이다. # 하지만 HC-SR04 센서는 이 오차를 받아준다. GPIO.output(GPIO_TRIGGER, True) time.sleep(0.00001) GPIO.output(GPIO_TRIGGER, False) # 에코 핀이 ON되는 시점을 시작 시간으로 잡는다. while GPIO.input(GPIO_ECHO)==0: start = time.time() # 에코 핀이 다시 OFF되는 시점을 반사파 수신 시간으로 잡는다. while GPIO.input(GPIO_ECHO)==1: stop = time.time() # Calculate pulse length elapsed = stop-start # 초음파는 반사파이기 때문에 실제 이동 거리는 2배이다. 따라서 2로 나눈다. # 음속은 편의상 340m/s로 계산한다. 현재 온도를 반영해서 보정할 수 있다. if (stop and start): distance = (elapsed * 34000.0) / 2 print "Distance : %.1f cm" % distance except KeyboardInterrupt: print "Ultrasonic Distance Measurement End" GPIO.cleanup() # Reset GPIO settings GPIO.cleanup() |
C 언어로 구현한 코드를 참고한다. 여기서 main( ) 함수에서 시간을 구현하는 함수, 즉 펄스를 방출하고 기다리는 시간을 다르게 구현한 코드를 올려둔다. 같은 원리인데 시간을 측정하는 방법이 다름을 보여준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | /* * hc_sr04.c: * Simple test program to test the wiringPi functions * hc_sr04 test */ #include <unistd.h> #include <time.h> #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <sys/resource.h> #include <wiringPi.h> #define GPIO_TRIGGER 13 #define GPIO_ECHO 22 unsigned long get_usec_tick() { struct timespec ts; unsigned theTick = 0U; clock_gettime( CLOCK_REALTIME, &ts ); theTick = ts.tv_nsec / 1000; theTick += ts.tv_sec * 1000000; return theTick; } int wait_state(int state) { while ( digitalRead( GPIO_ECHO ) == state ); return 0; } int main( void ) { long start, stop; int loop = 0, count; float f; float distance; printf( "Raspberry Pi wiringPi HC-SR04 Ultrasonic sensor test program\n" ); if ( wiringPiSetupGpio() == -1 ) exit( 1 ); pinMode( GPIO_TRIGGER, OUTPUT ); pinMode( GPIO_ECHO, INPUT ); // Set trigger to False (Low) digitalWrite( GPIO_TRIGGER, LOW ); delay( 500 ); while ( 1 ) { // Send 10us pulse to trigger digitalWrite( GPIO_TRIGGER, HIGH); delayMicroseconds( 10 ); digitalWrite( GPIO_TRIGGER, LOW); wait_state(LOW); start = micros(); wait_state(HIGH); stop = micros(); distance = (float)(stop - start) / 58.8235; printf( "Distance : %9.1f cm\n", distance ); delay(1000); if(loop++ == 100)break; } return(0); } |
시간 측정을 다르게 구현한 C 코드 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include<stdio.h> #include<wiringPi.h> #define trigPin 1 //gpio 21 #define echoPin 29 //gpio 18 //old #define trigPin 21 //gpio 5 //old #define echoPin 4 //gpio J16-pin3 GPIO 23 int main(void) { int distance=0; int pulse = 0; long startTime; long travelTime; if(wiringPiSetup () == -1) { printf("Unable GPIO Setup"); return 1; } pinMode (trigPin, OUTPUT); pinMode (echoPin, INPUT); for(;;) { digitalWrite (trigPin, LOW); usleep(2); digitalWrite (trigPin, HIGH); usleep(20); digitalWrite (trigPin, LOW); while(digitalRead(echoPin) == LOW); startTime = micros(); while(digitalRead(echoPin) == HIGH); travelTime = micros() - startTime; int distance = travelTime / 58; printf( "Distance: %dcm\n", distance); delay(200); } } |
'라즈베리파이' 카테고리의 다른 글
HC-SR501 적외선 모션감지센서 Python, C 소스코드 (1) | 2019.04.02 |
---|---|
HC-SR04 초음파 거리센서 인터럽트 처리로 구현한 C 코드 (0) | 2019.04.02 |
온습도 센서 DHT11 실습 python 코드 (0) | 2019.04.02 |
온습도 센서 DHT11 - 비동기 방식으로 값을 얻는 C코드 (0) | 2019.04.01 |
라즈베리파이 카메라 사용법 상세한 자료 파이선 코드 [링크] (0) | 2019.04.01 |