장애물 척척 피하는 똑똑한 로봇 만들기 (초보편)
페이지 정보

본문
장애물 척척 피하는 똑똑한 로봇 만들기 (초보편)
장애물을 척척 피하는 로봇을 만드는 것은 로봇에게 '눈'을 달아주고 스스로 '생각'해서 '움직이도록' 하는 아주 흥미로운 과정입니다. 초보자분들도 쉽게 따라 할 수 있도록, 가장 기본적인 초음파 센서를 이용한 장애물 회피 로봇 만들기를 자세히 설명해 드릴게요. 라인트레이서 로봇과 비슷한 방식으로 '인지 - 판단 - 행동'의 기본 원리를 다시 한번 익힐 수 있습니다.
1단계: 장애물 회피 로봇의 '원리' 이해하기
장애물 회피 로봇은 다음과 같은 간단한 원리로 움직입니다.
인지 (센서): 로봇 앞쪽에 달린 '초음파 센서'가 주변의 물체까지의 '거리'를 측정합니다.
판단 (컨트롤러/코드): 측정된 거리 값을 아두이노가 읽어들여, 현재 로봇 앞에 '장애물이 있는지', '얼마나 멀리 있는지'를 판단합니다.
장애물이 없을 때 (멀리 있을 때): 계속 앞으로 직진.
장애물이 가까이 있을 때 (위험 거리 이내): 일단 정지. 그리고 다른 방향(예: 왼쪽, 오른쪽)에 장애물이 없는지 확인 후 그쪽으로 회전.
행동 (모터): 아두이노의 판단에 따라 모터를 제어하여 로봇의 움직임(직진, 정지, 회전)을 결정합니다.
2단계: 필수 준비물 확인 및 구매
라인트레이서 로봇과 유사하지만, 라인 센서 대신 초음파 센서가 사용됩니다.
컨트롤러:
아두이노 우노 R3 (Arduino Uno R3) 호환 보드: 1개
USB 케이블: 아두이노와 컴퓨터 연결용.
로봇 섀시:
2WD 로봇 자동차 섀시 키트: 1개 - 모터, 바퀴, 프레임, 캐스터 포함 (라인트레이서와 동일)
액추에이터:
모터 드라이버 (L298N): 1개
SG90 마이크로 서보 모터: 1개 (선택 사항이지만, 센서를 움직여 장애물 감지 시야를 넓히는 데 유용)
센서:
초음파 센서 모듈 (HC-SR04): 1개
전원:
AA 배터리 홀더 (4개용): 1개 (모터 전원용)
AA 배터리: 4개
(선택 사항) 9V 배터리 & 스냅 커넥터: 아두이노 별도 전원용.
연결 재료:
브레드보드: 1개 (선택 사항)
점퍼 케이블 (수-수, 수-암): 넉넉하게
공구:
드라이버 세트, 니퍼, 양면테이프 또는 글루건.
3단계: 로봇의 '몸' 조립하기 (기계적 조립)
라인트레이서 로봇과 거의 동일한 방식으로 조립하되, 초음파 센서의 위치가 다릅니다.
로봇 섀시 조립: 프레임, 모터, 바퀴, 캐스터 등을 조립합니다.
아두이노/모터 드라이버 고정: 아두이노 보드와 모터 드라이버(L298N)를 로봇 프레임에 고정합니다.
초음파 센서 부착:
SG90 서보 모터와 결합: 서보 모터의 축에 초음파 센서를 고정하여, 센서가 좌우로 회전하며 장애물을 감지할 수 있도록 합니다. 이 서보 모터를 로봇 앞쪽에 고정합니다. (센서의 감지 시야를 넓히는 데 큰 도움이 됩니다.)
서보 모터 없이 고정: 서보 모터 없이 로봇 앞쪽에 초음파 센서를 고정할 수도 있습니다. 이 경우 센서는 정면만 감지합니다.
높이: 초음파 센서의 송수신부가 바닥과 수평을 이루도록, 그리고 로봇의 높이 중앙에 위치하도록 고정하는 것이 좋습니다.
4단계: 로봇의 '신경망' 연결하기 (전기 배선 - L298N 모터 드라이버 기준)
라인트레이서 로봇과 대부분 동일합니다.
모터와 L298N 모터 드라이버 연결: (라인트레이서와 동일)
L298N OUT1, OUT2 → 왼쪽 모터
L298N OUT3, OUT4 → 오른쪽 모터
전원부 연결: (라인트레이서와 동일)
AA 배터리 홀더의 + → L298N +12V (또는 VCC)
AA 배터리 홀더의 - → L298N GND
L298N 드라이버와 아두이노 연결: (라인트레이서와 동일)
L298N IN1 → 아두이노 핀 8
L298N IN2 → 아두이노 핀 9
L298N IN3 → 아두이노 핀 10
L298N IN4 → 아두이노 핀 11
L298N ENA → 아두이노 핀 5 (PWM 핀)
L298N ENB → 아두이노 핀 6 (PWM 핀)
L298N GND → 아두이노 GND (가장 중요!)
초음파 센서 (HC-SR04)와 아두이노 연결:
HC-SR04 VCC → 아두이노 5V
HC-SR04 GND → 아두이노 GND
HC-SR04 Trig (트리거 핀) → 아두이노 핀 4 (아무 디지털 핀이나 가능)
HC-SR04 Echo (에코 핀) → 아두이노 핀 7 (아무 디지털 핀이나 가능)
(선택 사항) SG90 서보 모터와 아두이노 연결:
SG90 오렌지/노란색 (Signal) → 아두이노 핀 12 (PWM 핀 중 아무거나 가능)
SG90 빨간색 (VCC) → 아두이노 5V
SG90 갈색/검은색 (GND) → 아두이노 GND
배선 시 주의사항: (라인트레이서와 동일) 모든 배선은 전원이 없는 상태에서 하고, 정확한 연결을 거듭 확인해야 합니다.
5단계: 로봇의 '명령' 프로그래밍하기 (아두이노 코딩)
이제 로봇에게 장애물 회피 방법을 가르쳐 줄 차례입니다. 아두이노 IDE를 사용하여 코드를 업로드합니다.
5.1. 아두이노 IDE 설정 (라인트레이서와 동일)
5.2. 장애물 회피 로봇 기본 코드 (SG90 서보 모터 포함 예시)
cpp
#include <Servo.h> // 서보 모터 라이브러리 포함
// 모터 제어 핀 정의 (L298N 기준)
const int motor1_in1 = 8;
const int motor1_in2 = 9;
const int motor2_in1 = 10;
const int motor2_in2 = 11;
const int motor1_ena = 5; // 왼쪽 모터 속도 (PWM 핀)
const int motor2_enb = 6; // 오른쪽 모터 속도 (PWM 핀)
// 초음파 센서 핀 정의
const int trigPin = 4;
const int echoPin = 7;
// 서보 모터 핀 정의
const int servoPin = 12;
// 모터 속도 (0-255)
const int base_speed = 150; // 기본 전진 속도
const int turn_speed = 100; // 회전 시 모터 속도
// 장애물 감지 거리 임계값 (cm)
const int obstacle_threshold = 20; // 20cm 이내면 장애물로 간주
Servo myservo; // 서보 객체 생성
void setup() {
pinMode(motor1_in1, OUTPUT);
pinMode(motor1_in2, OUTPUT);
pinMode(motor2_in1, OUTPUT);
pinMode(motor2_in2, OUTPUT);
pinMode(motor1_ena, OUTPUT);
pinMode(motor2_enb, OUTPUT);
pinMode(trigPin, OUTPUT); // 초음파 트리거 핀을 출력으로 설정
pinMode(echoPin, INPUT); // 초음파 에코 핀을 입력으로 설정
myservo.attach(servoPin); // 서보 모터를 핀에 연결
myservo.write(90); // 서보 모터를 중앙 (90도)으로 초기화
delay(500);
Serial.begin(9600); // 시리얼 통신 시작 (디버깅용)
}
void loop() {
long duration, distance;
// 1. 초음파 센서로 전방 거리 측정
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // 에코 핀으로부터 돌아오는 시간 측정
distance = duration * 0.034 / 2; // 시간을 거리(cm)로 변환 (음속: 340m/s = 0.034cm/us)
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// 2. 측정된 거리에 따른 로봇 행동 판단
if (distance > obstacle_threshold) {
moveForward(); // 장애물이 멀리 있으면 전진
} else {
stopRobot(); // 장애물이 가까우면 일단 정지
delay(300); // 잠시 대기
// 3. 좌우 거리 측정 (서보 모터가 있을 경우)
int leftDistance = measureDistance(160); // 왼쪽으로 센서 돌려 측정
delay(200);
int rightDistance = measureDistance(20); // 오른쪽으로 센서 돌려 측정
delay(200);
myservo.write(90); // 센서 다시 중앙으로
Serial.print("Left Dist: ");
Serial.print(leftDistance);
Serial.print(" Right Dist: ");
Serial.println(rightDistance);
// 4. 장애물이 없는 방향으로 회전
if (leftDistance > rightDistance) {
turnLeft(); // 왼쪽이 더 멀면 왼쪽으로 회전
} else {
turnRight(); // 오른쪽이 더 멀면 오른쪽으로 회전 (같으면 기본값)
}
delay(500); // 충분히 회전
}
}
// 거리 측정 함수 (서보 모터를 사용하여 특정 각도에서 측정)
int measureDistance(int angle) {
myservo.write(angle);
delay(300); // 서보가 해당 각도로 이동할 시간을 줌
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
return duration * 0.034 / 2;
}
// 로봇 제어 함수들 (라인트레이서와 동일)
void moveForward() {
digitalWrite(motor1_in1, HIGH); digitalWrite(motor1_in2, LOW);
analogWrite(motor1_ena, base_speed);
digitalWrite(motor2_in1, HIGH); digitalWrite(motor2_in2, LOW);
analogWrite(motor2_enb, base_speed);
}
void turnLeft() {
digitalWrite(motor1_in1, LOW); digitalWrite(motor1_in2, HIGH); // 왼쪽 모터 후진 (제자리 회전)
analogWrite(motor1_ena, turn_speed);
digitalWrite(motor2_in1, HIGH); digitalWrite(motor2_in2, LOW); // 오른쪽 모터 전진
analogWrite(motor2_enb, turn_speed);
}
void turnRight() {
digitalWrite(motor1_in1, HIGH); digitalWrite(motor1_in2, LOW); // 왼쪽 모터 전진
analogWrite(motor1_ena, turn_speed);
digitalWrite(motor2_in1, LOW); digitalWrite(motor2_in2, HIGH); // 오른쪽 모터 후진 (제자리 회전)
analogWrite(motor2_enb, turn_speed);
}
void stopRobot() {
digitalWrite(motor1_in1, LOW); digitalWrite(motor1_in2, LOW);
analogWrite(motor1_ena, 0);
digitalWrite(motor2_in1, LOW); digitalWrite(motor2_in2, LOW);
analogWrite(motor2_enb, 0);
}
5.3. 코드 업로드 및 테스트
위 코드를 아두이노 IDE에 복사하여 붙여넣기 합니다.
스케치(Sketch) → 컴파일/업로드(Upload)를 클릭하여 코드를 아두이노 보드에 업로드합니다.
툴(Tools) → 시리얼 모니터(Serial Monitor)를 열어 초음파 센서가 정확한 거리를 측정하는지 확인합니다. 로봇 앞에 손을 가져다 대거나 멀리 떨어뜨려가며 값이 변하는지 보세요.
6단계: 로봇 테스트 및 최적화
이제 똑똑한 로봇을 시험할 시간입니다!
테스트 환경 준비: 로봇이 자유롭게 움직일 수 있는 넓은 공간을 확보하고, 다양한 높이와 재질의 장애물(박스, 책 등)을 배치합니다.
시험 운행: 로봇에 전원을 켜고 작동을 시작합니다.
디버깅 및 조정:
장애물 감지 실패: 초음파 센서의 각도나 높이가 적절한지 확인합니다. 너무 높거나 낮으면 장애물을 감지하지 못할 수 있습니다.
거리 임계값: obstacle_threshold 값을 조절하여 로봇이 너무 일찍 멈추거나 너무 가까이 가서 부딪히지 않도록 최적의 거리를 찾습니다.
회전 동작: turn_speed와 delay 값을 조정하여 로봇이 충분히 회전하여 장애물을 피할 수 있도록 합니다.
모터 방향: 로봇이 회전할 때 예상한 방향으로 도는지 확인합니다. 만약 반대로 돌면 turnLeft()나 turnRight() 함수 내의 모터 제어 라인을 수정합니다.
모터 속도: base_speed와 turn_speed 값을 조정하여 로봇의 전반적인 움직임을 부드럽게 하거나 빠르게 만듭니다.
축하합니다! 이제 당신만의 장애물 회피 로봇이 완성되었습니다!
이 로봇은 로봇에게 '공간 인지' 능력을 부여하고 스스로 '생각'해서 위험을 '회피'하는 방법을 가르쳐주는 프로젝트입니다. 이 코드는 가장 기본적인 회피 로직이지만, 여기서 더 나아가 다양한 센서를 추가하거나, AI 알고리즘을 도입하여 더욱 똑똑하고 유연하게 움직이는 로봇을 만들 수 있습니다. 로봇 공학의 세계는 무궁무진합니다!
- 이전글리모컨으로 조종하는 RC카, 직접 만들면 더 재밌다! 25.11.20
- 다음글세상에서 가장 쉬운 라인트레이서 로봇 만들기 25.11.20
댓글목록
등록된 댓글이 없습니다.
