[아두이노] 장애물 감지 자율주행 자동차
블루투스로 컨트롤 하는 자동차도 만든김에 초음파 센서를 이용해 장애물을 감지해서 혼자서 움직이는 자율주행 자동차를 만들어보기로 했습니다. 이름이 거창하지만 움직이는 패턴은 그냥 전진하다가 앞에 장애물이 있으면 감지해서 후진 후 좌회전 또는 우회전 후 (좌, 우 회전은 랜덤하게...) 전진하는 자동차 입니다. 초음파 센서를 더 많이 붙인다면 더 정교한 움직임이 가능하겠는데 초음파 센서가 하나 밖에 없네요. ^^ 그래도 원하는 대로 잘 움직입니다. 어쨋든 센서가 많아지더라도 원리는 같습니다. 초음파 센서나 모터 드라이버에 대해서는 기존에 썼던 아래의 글들을 참고 하시면 도움이 될 것입니다.
■ 참고 글
▶ [아두이노] 초음파센서(HC-SR04)를 이용한 거리측정
▶ [아두이노] DC 모터의 제어(모터드라이버 L298N) 1편
기존 블루투스로 컨트롤 하는 자동차에서 달라진 부분은 블루투스 모듈이 사라지고 초음파 센서를 추가하였으며 9V 건전지를 아두이노 전원으로 추가해서 전원부를 보강했습니다. 이게 6V만 연결하면 처음에는 잘 되는데 조금 작동시키면 전압이 낮아져서 오류가 발생하더군요. 전원을 보강하니 잘 움직입니다.
앞부분에 HC-SR04 초음파 거리측정 센서를 달았습니다.
9V 아두이노 전원공급용 커넥터
6V 건전지 전원 외에 9V 건전지를 아두이노 전원연결용 커넥터를 이용해서 추가해 주었습니다. 그 이외 구성은 블루투스 자동차와 같습니다. 한 번 더 정리하자면 아두이노 우노, L298N DC 모터 드라이버 모듈, 바퀴달린 모터 2개, 앞바퀴용 캐스터 바퀴, 전원은 AA 건전지 4개 들어가는 건전지 홀더(6V) 와 9V 건전지, HC-SR04 초음파 센서, 배선용 미니 브레드보드 정도 들어갔네요. 본체는 하드보드지를 잘라서 만들었습니다. 부품들의 고정은 양면테이프로 고정했습니다.
◆ 연결
각각 부품의 연결은 다음과 같이 했습니다. 자세히 보고 싶은 분은 fritzing 파일을 다운받아서 보세요. L298N 에 연결되는 외부전원은 실제로 6V를 연결했는데 12V 까지 연결해도 상관이 없으므로 12V 내에서 연결하고싶은 전압의 전원을 연결하면 됩니다.
■ 자율주행 자동차 fritzing 파일
빨간선은 전원연결 + 이며 까만선은 GND ( - ) 입니다.
초음파 모듈의 Trig 는 D9, Echo 는 D8 에 연결했습니다.
모터 드라이버 모듈의 IN1 은 D7 에 연결하였고 차례대로 IN2 는 D6 에, IN3 는 D5, IN4 는 D4 에 연결 했습니다.
만약 소스는 문제가 없는데 모터가 원하는 방향과 거꾸로 돌아간다면 모터 드라이버 모듈에 연결된 모터의 배선을 서로 바꿔보세요. 그럼 원하는 방향으로 돌아갈 겁니다.
◆ 소스
기존의 블루투스 자동차의 소스를 수정하여 블루투스 관련 코드를 없애고 초음파 센서 관련 소스를 넣었습니다. 자동차의 동작제어는 전진, 좌/우 회전, 후진, 정지 기능이 있습니다. 장애물 감지하는 초음파 센서의 값은 20cm 로 설정했습니다. 장애물 감지 시 후진->좌 또는 우회전->장애물 없으면 전진... 이런 식으로 무한반복 하는데 각 동작마다 delay 를 주었습니다. 이 부분도 사정에 맞게 수정하거나 기능을 강화하면 더욱 정교한 움직임이 가능할 듯 합니다.
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #include <SoftwareSerial.h> //시리얼 통신 라이브러리 호출 //모터 PIN 설정 #define LEFT_A1 4 //왼쪽 바퀴 #define LEFT_B1 5 //왼쪽 바퀴 #define RIGHT_A2 6 //오른쪽 바퀴 #define RIGHT_B2 7 //오른쪽 바퀴 //초음파 센서 PIN 설정 #define IR_TRIG 9 //TRIG 핀 설정 (초음파 보내는 핀) #define IR_ECHO 8 //ECHO 핀 설정 (반사된 초음파 받는 핀) void setup() { Serial.begin(9600); //시리얼모니터 //모터 핀모드 설정 pinMode(LEFT_A1, OUTPUT); pinMode(RIGHT_A2, OUTPUT); pinMode(LEFT_B1, OUTPUT); pinMode(RIGHT_B2, OUTPUT); //초음파 센서 핀모드 설정 pinMode(IR_TRIG, OUTPUT); pinMode(IR_ECHO, INPUT); } void loop() { float duration, distance; digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW); // echoPin 이 HIGH를 유지한 시간 duration = pulseIn(IR_ECHO, HIGH); // HIGH 였을 때 시간(초음파가 보냈다가 다시 들어온 시간)을 가지고 거리를 계산 한다. // 340은 초당 초음파(소리)의 속도, 10000은 밀리세컨드를 세컨드로, 왕복거리이므로 2로 나눠주면 거리가 cm 로 나옴 distance = ((float)(340 * duration) / 10000) / 2; Serial.print("\nDIstance : "); Serial.println(distance); if(distance < 20) { //장애물 감지 (20cm 이내) Serial.println("stop"); stop(); //정지(1초) Serial.println("backward"); backward(); //후진(0.5초) int rnd = random(0,2); //장애물 감지시 좌/우회전 랜덤처리 if(rnd == 0){ Serial.println("right"); right(); }else{ Serial.println("left"); left(); } }else{ //장애물 없음 Serial.println("forward"); forward(); } } void forward(){ digitalWrite(LEFT_A1, HIGH); digitalWrite(LEFT_B1, LOW); digitalWrite(RIGHT_A2, HIGH); digitalWrite(RIGHT_B2, LOW); } void backward(){ digitalWrite(LEFT_A1, LOW); digitalWrite(LEFT_B1, HIGH); digitalWrite(RIGHT_A2, LOW); digitalWrite(RIGHT_B2, HIGH); delay(500); } void left(){ digitalWrite(LEFT_A1, LOW); digitalWrite(LEFT_B1, HIGH); digitalWrite(RIGHT_A2, HIGH); digitalWrite(RIGHT_B2, LOW); delay(1000); } void right(){ digitalWrite(LEFT_A1, HIGH); digitalWrite(LEFT_B1, LOW); digitalWrite(RIGHT_A2, LOW); digitalWrite(RIGHT_B2, HIGH); delay(1000); } void stop(){ digitalWrite(LEFT_A1, LOW); digitalWrite(LEFT_B1, LOW); digitalWrite(RIGHT_A2, LOW); digitalWrite(RIGHT_B2, LOW); delay(1000); } | cs |
주행 동영상 입니다. 그럭 저럭 잘 움직이네요. 그냥 놔두면 지가 알아서 돌아다니니 왠지 블루투스 자동차 보다 마음이 편한 것은 왜 일까요? 조종해야 한다는 부담이 없어져서 그런가? ^^;
▶추가내용(2016.08.12) : 위 내용 중 잘못된 내용이 있어서 바로 잡습니다. L298N 의 5V 단자는 전원 입력이 아니라 5V 출력 단자 입니다. 고로 위의 Fritzing 회로도 중 모터 드라이버에 연결한 아두이노 5V 전원은 필요가 없습니다. 전원은 외부전원을 충분하게 공급해주고 모터 드라이버 5V 출력을 아두이노의 VIN 에 연결해서 아두이노의 전원으로 사용하는 것이 가장 바람직하다고 생각 됩니다. http://deneb21.tistory.com/277 참고