[철권8]인게임 화면 녹화

Aromahyang·2024년 2월 26일

개인프로젝트

목록 보기
4/5

▲ 결과물(오른쪽 아래를 주목하자)

💡 계기

철권8 인게임 화면을 녹화하기 위해 아두이노를 활용했다.
이번에는 특별히 서보모터도 사용했다.
Keyboard.h 라이브러리의 키보드 인풋이 철권7에서는 동작하였으나, 철권8에서는 동작하지 않아서 물리적 키 입력이 필요했기 때문이다.

듀얼센스처럼 동작하는 라이브러리가 있는지 등 라이브러리를 찾아보았지만, 그런 건 없어서 고민만 깊어지던 때에
마침 예전에 블루투스 스위치를 만드려고 샀었던 서보모터가 생각났다.
서보모터의 회전날이 직접 키를 입력하면 되겠다란 좋은 아이디어가 떠올랐다.

기능을 구현하고 녹화하는 동안 서보모터가 1개 뿐이라 나의 노동이 조금? 꽤? 들어간 거 같다..
서보모터가 더 많았더라면 나의 노동을 확 줄일 수 있었겠지만, 제한적인 환경이었고 한번 녹화해두면 다음 시리즈가 나오기 전까지 우려먹을 수 있기 때문에 서보모터 1개로 프로젝트를 진행했다.

📍 준비물

아두이노 레오나르도 보드(혹은 우노 보드)
서보모터 1개
수수 케이블 3개(빨강색, 주황색, 갈색)

이후 과정을 읽고 물리적 키보드 입력 매크로를 만들 때 완전 자동화를 하고 싶다면 서보모터를 여러 개 사용하는 걸 추천한다.

📹 인게임 녹화

아두이노 보드에 서보모터 연결

서보모터에 3가지 핀이 있다.

갈색선은 GND(Ground), 빨간선은 VCC, 주황색선은 데이터핀이다.
내가 사용한 서보모터는 3.3V~5V를 지원하기 때문에 빨간선을 5V에 연결했다.
주황색선은 아무 데이터핀에 연결하면 되는데, 나는 7번 핀에 연결하였다.
서보모터의 핀을 바로 아두이노 보드에 연결할 수 없으므로 수수 케이블을 이용해서 보드에 연결하면 된다.

아두이노 코드 작성

#include <Servo.h>

Servo servo;
const int servoPin = 7;
const int START = 90;
const int END = 180;
int pos;

void setup() {
    pos = START;
    pinMode(servoPin, OUTPUT);
    servo.attach(servoPin);
}

void loop() {
	for(pos = START; pos <= END; pos += 10) {
    	servo.write(pos);
        delay(100);
    }
	for(pos = END; pos <= START; pos -= 10) {
    	servo.write(pos);
        delay(100);
    }
}

Servo.h 라이브러리는 기본적으로 설치되어 있는 거 같은데, 만약 설치가 안 된 거 같으면 스케치 > 라이브러리 포함하기 > 라이브러리 관리에서 Servo를 검색해 설치할 수 있다.

setup()은 코드가 컴파일되고 보드에 업로드된 후 최초 1회만 실행된다.
변수를 초기화하거나 처음에 한 번만 함수를 실행할 경우 setup() 안에 작성하면 된다.
pinMode()는 특정 핀의 모드(INPUT, OUTPUT 등)를 설정한다.
servo.attach()는 서보 모터의 신호선을 설정하는데, 나는 7번에 데이터핀을 연결했으므로 7로 설정하였다.

loop()setup()이 실행된 후 반복적으로 실행되는 함수다.
servo.write()는 서보모터를 특정 각도로 세팅한다.
delay()는 밀리초(ms)만큼 이후 동작을 지연한다.
나는 모터가 잘 도는지, 모터의 각도가 어떻게 되는지 확인하기 위해 모터가 90~180도 사이를 계속 도는 코드를 작성하였다.

그 결과 (왜 그런지 모르겠으나) 서보모터를 정면에서 바라봤을 때 살짝 기울어져 있는 걸 알게 됐다..

서보모터의 각도를 대충 알았으니 서보모터를 키보드에 두었을 때 얼만큼 각을 움직이면 되는지 찾아보았고, 아래 코드는 전체 코드의 일부다.

#include <Servo.h>

Servo servo;
const int START = 120;
const int END = 140;
int pos = END;
int servoPin = 7;
int i = 0;

void rotateUp()
{
    for (pos = END; pos >= START; pos -= 10)
    {
        servo.write(pos);
        delay(100);
    }
}

void rotateDown()
{
    for (pos = START; pos <= END; pos += 10)
    {
        servo.write(pos);
        delay(100);
    }
}

void skip()
{
    rotateDown();
    delay(1000); // 1s
    rotateUp();
}

void record()
{
    rotateDown();
    delay(6000); // 6s
    rotateUp();
}

void setup()
{
	pinMode(servoPin, OUTPUT);
    servo.attach(servoPin);
}

void loop()
{
    int first = CHARACTER[0];
    int second = CHARACTER[1];
    /* 중략 */
    if (i <= first)
    {
        skip();
        i += 1;
    }
    else if (/* 중략 */)
    {
        record();
        /* 중략 */
        i += 1;
    else
    {
        servo.write(END);
    }
}

왜 처음에 서보모터가 특정 각도를 도는지(START와 END 사이를 돌더라도 키가 입력될만큼의 각을 움직이지 않는 거 같다.) 모르겠다만 그거에 맞춰서 변수 i를 조절했다.

그리고 나는 현재 있는 거에서 최대한 활용하는 편이기 때문에 서보모터가 키를 누르면서 움직이지 않도록 고정하기 위해 왼쪽에 AA건전지를 두고, 위에는 아이패드를 올려서 무게를 더해줬다.

이제 키보드가 물리적으로 입력되는 걸 확인했으니 화면 녹화를 시작하고(Window+Alt+R) 끄는 것만 내가 하고, 순서를 넘기는 건 서보모터가 했다.

이후 편집 과정을 어떻게 했는지는 다음 편에 다룰 수 있으면 다뤄보겠다.

참고

아두이노 예제 10. 서보모터 제어하기

profile
보여주기 식이 아닌 경험하고 배운 것을 소소하게 기록하였습니다.

0개의 댓글