아두이노

장애물 피하는 로봇 만들기

반응형

1. 프로젝트 소개

대부분 아두이노를 처음 시작할 때 주로 가장 먼저 만들어보는 초음파 센서를 이용해 장애물을 피하는 로봇을 만들어 봅니다. 오픈소스도 정말 많고 아두이노, 모터드라이버, 모터 2개와 초음파 센서만 있어도 그럴듯한 로봇을 만들수 있기 때문이 아닌가 합니다. 하지만 쉽게 만들수 있는것 만큼 장애물 회피율이 떨어지는 단점도 있습니다. 그래서 이 프로젝트에서는 초음파센서의 인지 범위를 서보모터를 이용해 더 넓히고 더욱 정확한 회피가 가능한 로봇을 만들어 볼것입니다.

 

2. 준비물

아두이노 우노(오렌지 보드), 모터쉴드, 서보모터, DC모터 2개, 배터리

 

3. 하드웨어

                                                    

 

 

하드웨어는 위의 그림과 같이 구성했습니다. 몸체는 집에있던 로봇키트를 이용했고(다른 키트나 자작품도 상관없음) 앞쪽에 볼을 달아서 전체적인 균형을 잡았습니다. 서보모터와 초음파센서를 그림과 같이 결합시켰는데, 따라서 서보모터가 회전함에 따라 초음파센서 또한 같이 회전할 수있죠. 사진상 잘 보이지 않지만 로봇의 몸체 아래쪽에 건전지 팩을 장착하여 모터쉴드와 아두이노에 전력을 공급합니다.

 

2. 작동영상

기존의 장애물 피하는 로봇보다 회피를 더 잘합니다.

 

3. 소스코드

#include 

 

Servo myservo;

int pos = 0;

int trig = 7;

int echo = 6;

 

void setup() {

  Serial.begin(9600);

  myservo.attach(5);

  pinMode(trig, OUTPUT);

  pinMode(echo, INPUT);

  pinMode(12, OUTPUT);

  pinMode(9, OUTPUT);

  pinMode(13, OUTPUT);

  pinMode(8, OUTPUT);

}

 

void loop() {

 

  for(pos = 0; pos < 180; pos +=5)//서보모터 각도 pos를 5도 단위로 회전 

  {

    myservo.write(pos);

    delay(15); //서보모터가 돌아가기 위한 시간

 

     digitalWrite(trig, LOW);

  digitalWrite(echo, LOW);

  delayMicroseconds(2);

  digitalWrite(trig, HIGH);

  delayMicroseconds(10);

  digitalWrite(trig, LOW);//초음파 센서 작동

 

  unsignedlong duration1 = pulseIn(echo, HIGH);

  float distance1 = duration1 / 29.0 / 2.0;//측정한 거리를 cm단위로

 

  if (distance1 > 15)//만약 거리가 15cm 이상이면

  {

   forward();//전진 함수

  }

 

  if (distance1 < 15 && pos < 90)//만약 15cm이하, 왼쪽에 장애물이 있으면

  {

   turn_right();//우회전 함수

  }

 

  if (distance1 < 15 && pos > 90)//만약 15cm이하, 오른쪽에 장애물이 있으면

  {

   turn_left();//좌회전 함수

  }

 

  }

 

  for(pos = 180; pos>=1; pos-=5)//이 아래부터는 서보모터를 반대로 회전하면서 같은 과정을 거침 

  {                            

    myservo.write(pos);          

    delay(15);

 

  digitalWrite(trig, LOW);

  digitalWrite(echo, LOW);

  delayMicroseconds(2);

  digitalWrite(trig, HIGH);

  delayMicroseconds(10);

  digitalWrite(trig, LOW);

 

  unsignedlong duration2 = pulseIn(echo, HIGH);

  float distance2 = duration2 / 29.0 / 2.0;

 

  if (distance2 > 15)

  {

   forward();

  }

 

  if (distance2 < 15 && pos < 90)

  {

   turn_right();

  }

 

  if (distance2 < 15 && pos > 90)

  {

   turn_left();

  }

 

  }

 

}

 

void freeze()//혹시 몰라 만들어본 정지 함수

{

  digitalWrite(12, LOW);

  digitalWrite(9, HIGH);

  analogWrite(3100);

  digitalWrite(13, HIGH);

  digitalWrite(8, HIGH);

  analogWrite(11100);

  delay(400);

}

 

void forward()//전진 함수

{

  digitalWrite(12, LOW);

  digitalWrite(9, LOW);

  analogWrite(3200);

  digitalWrite(13, HIGH);

  digitalWrite(8, LOW);

  analogWrite(11200);

}

 

void turn_right()//우회전 함수

{

  digitalWrite(12, HIGH);

  digitalWrite(9, LOW);

  analogWrite(3200);

  digitalWrite(13, HIGH);

  digitalWrite(8, LOW);

  analogWrite(11200);

  delay(400);

}

 

void turn_left()//좌회전 함수

{

  digitalWrite(12, LOW);

  digitalWrite(9, LOW);

  analogWrite(3200);

  digitalWrite(13, LOW);

  digitalWrite(8, LOW);

  analogWrite(11200);

  delay(400);

}

 

void back()//유턴 함수

{

  digitalWrite(12, HIGH);

  digitalWrite(9, LOW);

  analogWrite(3200);

  digitalWrite(13, HIGH);

  digitalWrite(8, LOW);

  analogWrite(11200);

  delay(1000);

}

 

반응형
    # 테스트용