메이커 Maker

강아지 공놀이 로봇 '놀아주개' 05. 케이스와 전체 동작 코드

지구빵집 2021. 10. 17. 18:35
반응형

 

 

강아지 공놀이 로봇 '놀아주개' 05. 케이스와 전체 동작 코드 

 

Speak less, Listen more. 덜 말하고 더 많이 들어라.

React less, Observe more. 덜 반응하고 더 많이 관찰하라. 

 

위에서도 간략하게 언급되었다시피, 전반적인 작동 알고리즘은 장치가 발사한 공을 강아지가 물어와 입구에 다시 넣게 되면 스피커에서 주인의 칭찬 문구가 재생됨과 함께 상단의 먹이통에서 먹이가 나오는 것을 반복하는 것이다.

 

영상이 제대로 안나오고 있다. 뭐가 문제? 동작 영상



 

공의 발사는 야구장의 피칭머신에서 아이디어를 얻어 서로 역방향으로 회전하는 모터의 바퀴 사이에 공이 굴러가도록 하여 순간적으로 큰 가속도를 가지고 발사되도록 하였고, 투입된 공이 중간에 가속을 받아야 하므로 관의 중간에 양쪽으로 구멍을 뚫고, 안으로 회전하는 바퀴가 들어올 수 있도록 하였다.

 

이때 처음에는 공을 발사만 해야 하고, 이후로 공을 가져온 것에 대해 보상을 제공해야 하기 때문에 조건문을 활용하여 1차 시도에는 별다른 반응이 일어나지 않도록 코드를 작성하였다. 공의 인식은 입구에 부착된 컬러 센서로 이루어지며, 인식 오류를 최소화하고자 공의 색깔은 흰색, 입구와 공이 흘러가는 관의 색깔은 검은색으로 하여 색깔 대비를 이루었다.

 

또한, 강아지가 공을 물어왔을 때 간식을 받아먹을 충분한 시간이 필요하기 때문에 특정 시간이 지난 후에 공이 발사될 수 있도록 하는 컨트롤이 필요했다. 이를 위해 입구의 컬러 센서 바로 아래에 서보모터로 입구를 열고 닫을 수 있는 공간을 마련하였다. 마지막으로 먹이통은 내부를 경사지게 하고, 상단에 입구를 열고 닫을 수 있는 서보모터를 부착하여 입구가 열리면 먹이가 경사를 따라 내려옴으로써 강아지에게 제공되는 방식으로 설계하였다. 

 

하드웨어 제작에 사용된 공이 굴러가는 관

 

공을 물어와 넣으면 먹이가 나오고 다시 공을 던진다

 

이를 구현하기 위한 코드는 전반적으로 단순하지만 서보모터와 컬러 센서를 제대로 다루기 위해서 관련 라이브러리 2개를 추가할 필요가 있었다.

 

서보모터 관련 라이브러리를 사용하였으며, 아두이노 설치 시 포함되어 있는 기본 라이브러리 중 하나다. Servo myservo1와 같이 사용할 서보모터를 변수로 만들어 코드에서 다룰 수 있으며, setup 부분에서 myservo1.attach() 함수를 통해 서보모터 제어에 사용할 핀을 설정할 수 있다. 마지막으로 myservo1. write() 함수 내에 원하는 모터 각도를 입력하여 모터를 자유자재로 다룰 수 있다. 이때 해당 함수 뒤에 delay() 함수를 같이 사용해야 정상적인 제어가 가능하다.

 

컬러 센서 관련 라이브러리는 를 사용하였으며, 아두이노 기본 라이브러리가 아니기 때문에 라이브러리 관리 탭에서 추가 설치를 해야 한다. 컬러 센서를 사용하기 위한 기본 설정 코드는 아래와 같으며, 작성 시 컬러 센서의 LED에 불이 들어오며 근접한 물체의 RGB 정보를 받아올 수 있다. 자세한 설명은 주석으로 대체한다. 

 

전체 동작 코드를 추가한다. 아주 예술이다. 예술!

 

#include <Servo.h>
#include <Adafruit_TCS34725.h>
#define S_LED 7
#define RGB_INT 2
Servo myservo1;
Servo myservo2;
double m1;                                    // double형 변수 2개 선언
double m2;

int count = 0;
uint16_t r, g, b, c;
const int dirPinA = 10;
const int pwmPinA = 12;
const int dirPinB = 11;
const int pwmPinB = 13;

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X);
volatile boolean rgb_flag = false;

void setup() {
  myservo1.attach(8);
  myservo2.attach(9);
  myservo1.write(0);                          // 두 서보모터의 초기 각도 0도로 설정
  myservo2.write(0);
  delay(2000);
  pinMode(dirPinA, OUTPUT);
  pinMode(pwmPinA, OUTPUT);
  pinMode(dirPinB, OUTPUT);
  pinMode(pwmPinB, OUTPUT);
  pinMode(RGB_INT, INPUT_PULLUP);
  pinMode(S_LED, OUTPUT);
  pinMode(5, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(RGB_INT), RGB_isr, FALLING);
  Serial.begin(115200);
  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1);
  }

  tcs.write8(TCS34725_PERS, TCS34725_PERS_2_CYCLE);
  tcs.setInterrupt(true);
  Serial.flush();
}

void loop() {
  if (rgb_flag) {
    getRawData_noDelay(&r, &g, &b, &c);

    Serial.print("r: "); Serial.print(r);    Serial.print(",");
    Serial.print("g: "); Serial.print(g);    Serial.print(",");
    Serial.print("b: "); Serial.print(b);    Serial.print(",");
    Serial.print("c: "); Serial.println(c);
    tcs.clearInterrupt();
    rgb_flag = false;
    digitalWrite(S_LED, HIGH);
  }

  if (c > 300) {
    if (count >= 1) {
      delay(1000);
      myservo2.write(30);
      delay(500);
      digitalWrite(5, 1);
      digitalWrite(5, 0);
      myservo2.write(0);
      delay(6000);
    }
    delay(3000);

    digitalWrite(dirPinA, HIGH);
    analogWrite(pwmPinA, 250);
    digitalWrite(dirPinB, HIGH);
    analogWrite(pwmPinB, 250);
    delay(1000);

    myservo1.write(65);
    delay(500);
    digitalWrite(dirPinA, LOW);
    analogWrite(pwmPinA, 0);
    digitalWrite(dirPinB, LOW);
    analogWrite(pwmPinB, 0);
    delay(100);
    myservo1.write(0);
    delay(500);
    count = 1;
  }
}

void RGB_isr() {
  rgb_flag = true;
  digitalWrite(S_LED, LOW);
}

void getRawData_noDelay(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c) {
  *c = tcs.read16(TCS34725_CDATAL);
  *r = tcs.read16(TCS34725_RDATAL);
  *g = tcs.read16(TCS34725_GDATAL);
  *b = tcs.read16(TCS34725_BDATAL);
}

 

강아지 공놀이 로봇

 

 

 

반응형