[TicTacToe/02] CNC Plotter 제어

01. 스텝 모터

Step Motor 28BYJ-48 기준

스텝 모터는 움직이던 관성에 영향을 받지 않고, 일정한 각도만큼 회전하는 모터다. 스텝 모터는 신호를 읽고 해당하는 동작을 절차적으로 수행하며 모터를 회전시킨다. 구현에 사용한 28BYJ-48 모터는 5 wires 유니폴라 구조며, 정밀한 제어가 가능한 half-step 시퀀스를 이용한다. (더 자세한 서보 모터의 구조와 시퀀스는 아래 참고 자료를 읽는 것을 추천한다.)

alt text

28BYJ-48 스텝 모터의 5 wires는 각각 전원선, IN1-4와 연결된다. 5 wires 유니폴라 방식은 두 개의 코일로 구성되어 있는데, 각각의 코일은 IN1과 IN3, IN2와 IN4과 연결되어 있다. 각각의 선에 0-7 순서로 신호를 전달하면 시계 방향으로 모터가 회전한다. 시계 반대 방향으로 모터를 돌리고 싶다면, 역순으로 신호를 전달하면 된다.

// Switching Seq 
// Step  | IN1 IN2 IN3 IN4
// ----- | ----------------
//   0   |  0   0   0   1
//   1   |  0   0   1   1
//   2   |  0   0   1   0
//   3   |  0   1   1   0
//   4   |  0   1   0   0
//   5   |  1   1   0   0
//   6   |  1   0   0   0
//   7   |  1   0   0   1


02. 아두이노용 라이브러리 제작

아두이노는 Stepper라는 스텝 모터 제어 라이브러리를 제공한다. 원래는 Stepper 라이브러리를 이용해 제어 프로그램을 작성할 예정이었으나, 디지털 핀에 꼽힌 x와 y축 담당 스텝 모터가 단방향으로만 이동하는 오류가 발생했다. 이 오류는 랜덤으로 발생해 명확한 원인을 알아내기 어려웠다. 예를 들어, 처음에는 양방향으로 잘 돌아가던 모터가 같은 코드 상에서 갑자기 단방향으로만 돌아가는 모습을 보였다. 이 문제를 해결하고자 28BYJ-48 스텝 모터를 제어하는 전용 라이브러리를 다시 만들었다.

C++ 기초 다지기

스텝 모터 제어 라이브러리와 로봇 제어 코드는 전부 C++으로 구현했다. C++의 클래스와 포인터, 참조, 복사를 다룬 아래 두 글은 라이브러리를 구현하며 공부한 내용이다.

01 C++ Class

02 C++ Pointer & Reference

문제 상황 및 해결

  1. 모터의 속도 저하 문제.
    하나 하나 핀을 설정해주는 것과 그 내용을 함수로 묶은거랑 움직임 속도 차이가 난다. 하드웨어적인 문제라서 정확한 원인은 모르겠다.

  2. 병렬 연산을 지원하지 않는 아두이노.
    대각선을 그리기 위해서는 x,y 축이 동시에 움직여야 한다. 하지만 아두이노는 병렬 연산을 지원하지 않기 때문에 std::thread()를 사용할 수 없다. 처음에는 아두이노에서의 멀티 테스킹을 가능케 만드는 Scheduler를 사용하려고 했다. 구현해야 하는 대각선 그리는 코드는 n_steps를 받아 그 크기만큼 x, y 스텝모터를 동시에 움직여야 하는데, 스케줄러는 정적 함수만을 파라미터로 받기 때문에 구현이 불가능했다. 이 문제는 MultiStepper(&stepper_x, &stepper_y) 클래스를 구현해 해결했다.

  3. 한 방향으로만 도는 모터. Seiral 통신을 통해 direction과 step_signal이 오류 없이 변화하는 것을 확인했음에도 회전 방향이 달라지지 않았다. 이 문제는 step 사이의 더 큰 delay() 값을 주며 해결되었다. 너무 적은 -나의 초깃값은 30이었다- 딜레이 시간은 모터에게 신호를 제대로 전달하지 못한다는 것을 알 수 있었고, 여러 시도 후 500을 딜레이 값으로 설정했다.

03. 그림 그리기 제어 코드

TicTacToeArtist

틱택토 아티스트 클래스는 3개의 스텝 모터를 이용해 O / X, 판을 그리는 제어용 클래스다. StepMotor.h 라이브러리를 이용해 3개의 스텝 모터 클래스를 선언한 후, 인자로 받아 사용한다.

#include "StepMotor.h"

Stepper stepper_x(8, 9, 10, 11);
Stepper stepper_y(3, 4, 5, 6);
Stepper stepper_z(A5, A4, A3, A2);

TicTacToeArtist artist(21, 21, &stepper_x, &stepper_y, &stepper_z);

void setup(){
    Serial.begin(115200);
    Serial.println("Setup complete");
};

void loop() {
    Serial.println("delay");
    delay(3000);
    artist.resetPosition();
    artist.drawGameBoard();   // 게임 보드 그리기
    delay(2000);              // 잠시 대기

    Serial.println("Drawing X...");
    artist.drawX(0);           // 'X' 그리기
    delay(2000);              // 잠시 대기
    
    Serial.println("Drawing Circle...");
    artist.drawCircle(0);      // 'O' 그리기
    delay(2000);              // 잠시 대기


    Serial.println("end");
    delay(1000000);
};


-> 로봇 제어 코드 바로가기

04. 시리얼 통신 제어

로봇은 AI의 선택을 현실세계로 가져오는 역할이며, 이를 구현하기 위해 python에서 시리얼 통신을 실행했다. 이 부분은 오목 로봇팔 구현과 매커니즘이 유사하기 때문에 별도로 설명하지 않는다. 방법이 궁금하다면 하단의 오목 문서에서 확인할 수 있다.
02 오목 로봇 회로 제작 및 제어

실제 움직임

움짤

  • 이 버전은 최종 완성본으로, 로봇 제작을 제외한 AI • CV 부분은 강화시스터즈 01 세션 부원이 마무리했다.

코드 바로가기

  1. CV-AI-Robotics (동아리 일환)
  2. 듀얼 에이전트 RL 구현



Comments