본문 바로가기

Arduino

Arduino + Diablo 3 Macro (아두이노로 디아블로3 키 매크로 구현하기)

Arduino + Diablo 3 Macro (아두이노로 디아블로3 키 매크로 구현하기)


바야흐로 융합의 시대를 맞이하여..

관심분야인 아두이노와 디아블로3를 접목해봤습니다.


요즘에 무한으로 적들을 얼리는 꽁서리법사 셋팅을해서 디아를 하고 있습니다.

꽁서리를 해보신분은 당연히 아시겠지만... 키보드 1 2 3 1 2 3 1 2 3 ....무한연타 혹은 마우스 무한연타를 하다보면

손가라가 관절염에 대한 걱정과 함께 내가 이짓을 하면서 까지 게임해야하나 하는 생각이 문득문득 듭니다.


그래서 많은 꽁서리분들이 자동으로 키 입력을 해주는 키보드 매크로 프로그램을 사용하기도하고

게임용 키보드 마우스에서 지원하는 매크로 프로그램을 씁니다.

저도 오토핫키라는 매크로 프로그램을 써서 플레이를 합니다.

편하긴 한데 혹시나.. 외부 프로그램 사용 때문에 영정(영구정지)을 당할까 불안한건 사실입니다.

(그런데 사실 지금까지 매크로 프로그램때문에 영정당했다는 얘기는 본적도 들은적도 없습니다.)




매크로 기능때문에 관심을 두시는 분이라면 그냥 오토핫키 프로그램 쓰시거나

매크로기능 있는 마우스 사서 쓰는게 백배는 편합니다.


그래서 아두이노가 있는김에!! 키보드로 인식시켜 키 매크로 하드웨어를 만들어보았습니다.

PC입장에서는 그냥 HID 키보드 하나 더 붙는것으로 인식합니다.


아두이노를 USB키보드로 인식시키는 것이 쉽게 될까 고민했는데...

이미 완성된 펌웨어가 존재해서 아주아주 쉽게 완성시킬 수 있었습니다.

제가가진 아두이노는 UNO 버전입니다. 그런데 이놈은 HID 인터페이스로 바로 붙지 않습니다.

Atmega8 이놈의 펌웨어를 업데이트 해줘야 합니다.

(아두이노 레오나르도 버전은 HID로 쉽게 붙는다고 하는군요..)


펌웨어 업데이트 방법은 아래 아두이노 사이트를 참고하시면 됩니다.

http://arduino.cc/en/Hacking/DFUProgramming8U2

DFU모드로 변경하는 방법때문에 삽질을 좀 했습니다. 

위 아두이노 사이트에는 10Kohm을 사용해서 DFU모드로 진입하는

방법이 나와있습니다. 전 위 방법대로 했구요 

(DFU모드 진입은 위 페이지 설명대로 저항을 붙이고 전원 연결 -> 점퍼 케이블 쇼트 (LED깜빡임확인) -> 쇼트해제)

저항없이 하는방법도 있는데 그건 아래 링크참고 하시면 됩니다.

http://arduino.cc/forum/index.php/topic,52447.msg374201.html#msg374201


위 방법을 습득하고 위 아두이노 링크에서 원본용 펌웨어를 다운받아놓은 다음 HID 펌웨어를 올립니다. 

그런데 일단 펌웨어를 올리면 아두이노가 키보드로만 인식되므로 그전에 스케치를 작성해서 업로드해 놓아야 합니다!!

물론 잘못해도 다시 원본 펌웨어를 올리면 됩니다.

하지만 키보드로 인식되는동안 쓰래기값이 타이핑이 마구 되어서 펌웨어를 다시 쓰는데 무척 힘들었어요 ㅜㅜ

(ssh접속으로 해결)

 

HID펌웨어는 여기에 다운받은후

http://hunt.net.nz/users/darran/weblog/b3029/Arduino_UNO_Keyboard_HID_version_03.html

아래 페이지 설명을 참고해서 스케치 작성과 펌웨어 업로드!

http://hunt.net.nz/users/darran/weblog/faf5e/Arduino_UNO_Keyboard_HID_part_2.html


USB키보드의 키코드는 아래 문서 참고

http://www.usb.org/developers/devclass_docs/Hut1_11.pdf


 

그리고 버튼 세개를 연결해서..

시작버튼, 정지버튼, 나머지 하나 이렇게 해봤습니다.

제가 사용한 스케치를 참고용으로 올립니다.


/* Arduino USB Keyboard HID demo

*/


uint8_t buf[8] = { 0 }; /* Keyboard report buffer */


void setup();

void loop();


#define KEY_LEFT_CTRL 0x01

#define KEY_LEFT_SHIFT 0x02

#define KEY_RIGHT_CTRL 0x10

#define KEY_RIGHT_SHIFT 0x20


int Macro_start = 2;

int Macro_stop = 3;

int Macro_etc = 4;


int STATUS_LED = 8;


int macro_run = 0;


char *str = "------------->8-------------";


void setup() 

{

    Serial.begin(9600);

    pinMode(Macro_start, INPUT);

    pinMode(Macro_stop, INPUT);

    pinMode(Macro_etc, INPUT);

    pinMode(STATUS_LED, OUTPUT);

    delay(200);

}


void loop() 

{

  

  macro_run = digitalRead(Macro_start);

  int etc_run = digitalRead(Macro_etc);

  char *chp = str;

  

  digitalWrite(STATUS_LED, LOW);

  

  while (macro_run) {

      macro_run = !digitalRead(Macro_stop);

      

      digitalWrite(STATUS_LED, HIGH);

     

      buf[2] = 30; // Keyboard 1

      Serial.write(buf, 8); // Send keypress

      buf[0] = 0;

      buf[2] = 0;

      Serial.write(buf, 8); // Release key

      delay(30);

      

      buf[2] = 31; // Keyboard 2

      Serial.write(buf, 8); // Send keypress

      buf[0] = 0;

      buf[2] = 0;

      Serial.write(buf, 8); // Release key

      delay(30);

      

      buf[2] = 32; // Keyboard 3

      Serial.write(buf, 8); // Send keypress

      buf[0] = 0;

      buf[2] = 0;

      Serial.write(buf, 8); // Release key

      delay(30);

  }

  

  if (etc_run) {

    digitalWrite(STATUS_LED, HIGH);

    

    buf[2] = 88; // Keyboard Enter

    Serial.write(buf, 8); // Send keypress

    buf[0] = 0;

    buf[2] = 0;

    Serial.write(buf, 8); // Release key


    while (*chp) {

      if ((*chp >= 'a') && (*chp <= 'z')) {

   buf[2] = *chp - 'a' + 4;

      } else if ((*chp >= 'A') && (*chp <= 'Z')) {

   buf[0] = KEY_LEFT_SHIFT; /* Caps */

   buf[2] = *chp - 'A' + 4;

      } else if ((*chp >= '1') && (*chp <= '9')) {

        buf[2] = *chp - 19;

      } else {

   switch (*chp) {

   case ' ':

    buf[2] = 0x2c; // Space

break;

   case '-':

      buf[2] = 0X2d; // -

      break;

   case '>':

               buf[0] = KEY_RIGHT_SHIFT;

      buf[2] = 0X37; // >

      break;

   default:

     /* Character not handled. To do: add rest of chars from HUT1_11.pdf */

buf[2] = 0x37; // Period

       break;

   }

      }

      Serial.write(buf, 8); // Send keypress

      buf[0] = 0;

      buf[2] = 0;

      Serial.write(buf, 8); // Release key

      chp++;

    }

    

    buf[2] = 88; // Keyboard Enter

    Serial.write(buf, 8); // Send keypress

    buf[0] = 0;

    buf[2] = 0;

    Serial.write(buf, 8); // Release key


    delay(500);

  } // etc_run

}

 

그러면 아래와 같이 쓸수 있습니다. ㅎㅎ

 



수정하려면 펌웨어를 다시 올려야 하는 단점이 ㅎㄷㄷㄷ