아두이노에서 Wii 눈차크 사용하기 [Wii Nunchuck]
아두이노

아두이노에서 Wii 눈차크 사용하기 [Wii Nunchuck]

반응형

 

 

일본의 유명 게임회사인 닌텐도의 게임기 시리즈 중 닌텐도 Wii는 각각 3축 가속도계가 달린 Wiimote와 Wii Nunchuck을 게임 콘솔로 이용한다. (Nunchuck을 정확히 뭐라고 읽는지 애매하지만 눈차크나 넌척등으로 흔히 알려진듯 하다.)

특히 Nunchuck은 3축 각속도 센서, 2개의 버튼, 1개의 조이스틱이 포함되어있어 자작품 만들기에 유용한 컨트롤러이다. 게다사 I2C통신이 기본이라 아두이노에서 사용하기도 편하다.

 

 

알리에서 호환 컨트롤러를 저렴한 가격에 구할 수 있다.

 

 

Wii Nunchuck의 커넥터는 일반적인 커넥터와 다르다. 총 6개의 핀중에 4개만 사용하며

 

 

위의 사진에서 1번은 SDA, 3번은 3.3V (특이하게 3.3V전원을 이용한다.) 4번은 GND, 6번은 SCL이다. 특이한 커넥터이기 때문에 아두이노와 직접 연결하기가 쉽지는 않는데, 직접 납땜하거나 아래와 같은 아답터를 이용해도 된다.

 

 

사실 아두이노 코드는 구글링을 조금만 해도 수많은 라이브러리와 함께 Nunchuck을 사용할 수 있는 코드들이 나온다. 하지만 필자의 경우 I2C 공부도할겸 라이브러리를 사용하지 않고 Nunchuck의 통신프로토콜을 이용해 직접 코드를 작성해 보기로 했다.

 

http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus

반응형

대부분의 자료는 위의 링크를 참고했다. 위의 링크에도 나와있듯 Nunchuck의 I2C 통신 주소는 0X52이고 I2C 통신을 통해 데이터를 요구하면 아래 형식에 맞추어 데이터를 전송한다.

 

 

표에서 SX는 조이스틱의 X값, SY는 조이스틱의 Y값, AX<9:2>, AY<9:2>, AZ<9:2>는 각각 X, Y, Z축의 가속도 값의 처음 7자리, AX<1:0>, AY<1:0>, AZ<1:0>는 각각 X, Y, Z축의 가속도 값의 마지막 2자리를 의미하며 (C언어에서 기본적으로 배우는 bit 연산을 배웠다면 쉽게 이해가 될 것이다.) BC는 C버튼, BZ는 Z버튼의 상태이다.

따라서 Nunchuck은 기본적으로 6Byte의 데이터를 전송하며 이 값을 위에 표에 맞추어 적절히 연산하면 각각의 데이터를 얻을수있다. 그 밖의 레지스트리등의 정보는 위의 링크를 참고하자.

 

작성한 코드는 아래와 같다.

/* 이 소스코드의 저작권은 http://diy-project.tistory.com/에 있습니다.
소스코드는 자유롭게 사용가능하지만 대회 및 상업적 목적으로 이용시에 반드시
출처를 밝혀야 합니다.*/
#include <Wire.h>
#define ZERO_AX 530  
#define ZERO_AY 530
#define ZERO_AZ 530
#define WII_NUNCHUCK_I2C_ADDRESS 0x52
int counter;
uint8_t data[6];
void setup() 
{ 
  Serial.begin(9600);

  Wire.begin();
  Wire.beginTransmission(WII_NUNCHUCK_I2C_ADDRESS);
  Wire.write(0xFB);
  Wire.write(0x00);
  Wire.endTransmission();
//You may need this code for controller from other manufacturer.
/*Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xF0);
  Wire.write(0x55);
  Wire.endTransmission();*/
} 
void loop() 
{ 
  
    Wire.requestFrom(WII_NUNCHUCK_I2C_ADDRESS, 6);
    counter = 0;
   
    while(Wire.available())
    {
   
      data[counter++] = Wire.read();
    }
    
    Wire.beginTransmission(WII_NUNCHUCK_I2C_ADDRESS);
    Wire.write(0x00);
    Wire.endTransmission();
    if(counter >= 5)
    {
      int SX = data[0];
      int SY = data[1];
      double AX = ((data[2] << 2) + ((data[5] >> 2) & 0x03) - ZERO_AX);
      double AY = ((data[3] << 2) + ((data[5] >> 4) & 0x03) - ZERO_AY);
      double AZ = ((data[4] << 2) + ((data[5] >> 6) & 0x03) - ZERO_AZ);
      int BC =(data[5] >> 1) & 0x01;
      int BZ = data[5] & 0x01;

      Serial.print(BC);
      Serial.print("   ");
      Serial.print(BZ);
      Serial.print("   ");
      Serial.print(SX);
      Serial.print("   ");
      Serial.print(SY);
      Serial.print("   ");
      Serial.print(AX);
      Serial.print("   ");
      Serial.print(AY);
      Serial.print("   ");
      Serial.print(AZ);
      Serial.println("   ");
  
      delay(20);
    }
}

 

코드는 생각보다 간단하게 완성했다. 간단한 bit연산이며, 시리얼 모니터에 가속도 값과 버튼상태등을 출력한다. 속도가 마음에 들지 않다면 통신속도를 조절하면 된다.

참고로 Nunchuck 호환 컨트롤러의 경우 제조사에 따라 초기 세팅시 0XFB의 메모리로 설정되지 않은 경우가 있다. 혹시 통신이 안된다면 코드에도 나와있듯 0XF0로 시도해보면 된다.

 

반응형
    # 테스트용