본문 바로가기

컴퓨터

라즈베리 파이 + Wii 리모컨(Wii Remote) + 눈차크(Nunchuk) 설정

Wii 리모컨는 매우 유용하게 활용할 수 있는 장치이다. 다수의 디지털 버튼들은 물론 가속도 센서(ADXL330)와 광학 센서(PixArt, 적외선 감지)도 탑재하고 있어 활용도가 높다. 사용하기에 따라서는 사용자 인터페이스 뿐만 아니라 밸런싱 로봇이나 적외선 감지 RC 카에도 충분히 활용 가능하다. 눈차크와 클래식 컨트롤러 또한 매력적인 장치이다. 파이썬 CWiid 모듈을 이용하면 이러한 장치들을 라즈베리 파이에 쉽게 연결하여 사용할 수 있다.

 

1. 파이썬 CWiid 설치

라즈베리 파이의 터미널에서 다음과 같이 입력하여 CWiid 모듈을 설치한다.

1

$ sudo apt-get install python-cwiid

2. 블루투스 드라이버 설치

라즈베리 파이에 다음과 같이 블루투스 드라이버를 설치한다.

1

$ sudo apt-get install --no-install-recommends bluetooth

–no-install-recommends 는 기본 드라이버 이외의 다른 추천 항목들을 설치하지 않는다는 의미이다.

3. 라즈베리 파이에 USB 블루투스 동글 연결

라즈베리 파이에 USB 블루투스 동글을 연결한다. 라즈베리 파이에서 사용할 수 있는 블루투스 동글은 eLinux 사이트에서 확인한다. 참고로, Billionton BT-0003, Soundclear SC-BD, 유니콘 XU-400B, 유니콘 BW-200U, 인파로 H-20,
퓨전 FNC bu-2096, 퓨전 FNC BU-4096 등의 동글들은 모두 정상적으로 사용할 수 있었다. 단, 퓨전 FNC BU-4096의 경우 라즈베리 파이(구형 모델 B)에 꽂을 때 파이가 재부팅되는 현상이 발생했다.

4. 블루투스 동글의 작동 상태 확인

1

$ sudo service bluetooth status

정상적으로 작동한다면 아래와 같이 출력된다.

1

[ OK ] bluetooth is running.

5. Wii 리모컨 검색

Wii 리모컨의 1, 2번 버튼을 동시에 누른 다음 라즈베리 파이에서 아래의 명령을 실행하여 리모컨을 검색한다.

1

$ hcitool scan

검색에 성공하면 아래와 같이 출력된다.

1

2

3

Scanning ...

 

         00:19:1C:B6:BB:41       Nintendo RVL-CNT-01

6. 파이썬 스크립트 작성

Wii 리모컨의 버튼 값을 파이썬으로 읽을 수 있도록 스크립트를 작성한다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

# -*- coding: utf-8 -*-

 

# based on Raspberry Pi Spi source

# http://www.raspberrypi-spy.co.uk/?p=1101

 

import cwiid

import time

 

def setup():

 

    ####################################

    # Wii Mote에 연결 시도

    ####################################

    print 'Wii Remote의 1 + 2 를 눌러주세요 ...'

    time.sleep(1)

 

    try:

      wii=cwiid.Wiimote()

    except RuntimeError:

      print "Wii Remote 연결 실패"

      quit()

 

    print "Wii Remote 연결 성공"

    print "연결을 종료하려면 PLUS와 MINUS 버튼을 동시에 눌러주세요."

 

    ####################################

    # Wii Mote가 처리할 영영 설정

    ####################################

    wii.rpt_mode = cwiid.RPT_BTN  

 

    wii.led = setLedNum()

    wii.rumble = True

    time.sleep(0.1)

    wii.rumble = False

 

    stateDict = wii.state

    stateList = list(stateDict)

 

    return wii

 

def setLedNum(led = None, bin = None):

    ledDict = {1: 1, 2:2, 3:4, 4:8}

    ledList = [1, 2, 4, 8]

    if led == None:

        import random

        led = random.randrange(4)

        led = ledList[led]

    else:

        led = ledDict[led]

    if bin != None:

        led = bin

    return led

 

def getButtons(wii):

    button_delay = 0.1

    buttons = wii.state['buttons']

 

    # Plus와 Minus 버튼을 동시에 누르면

    # rumble 후 종료

    if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):

        print '\n연결을 종료합니다...'

        wii.rumble = 1

        time.sleep(1)

        wii.rumble = 0

        exit(wii)

 

    # 버튼을 눌렀는지 확인하려면

    # wii.state['buttons']과 버튼의 번호(constants)를

    # bitwise AND 연산자로 처리

    if (buttons & cwiid.BTN_LEFT):

        print '왼쪽 방향 버튼'

        time.sleep(button_delay)

 

    if(buttons & cwiid.BTN_RIGHT):

        print '오른쪽 방향 버튼'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_UP):

        print '위쪽 방향 버튼'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_DOWN):

        print '아래쪽 방향 버튼'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_1):

        print '버튼 1'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_2):

        print '버튼 2'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_A):

        print '버튼 A'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_B):

        print '버튼 B'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_HOME):

        print 'Home 버튼'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_MINUS):

        print 'Minus 버튼'

        time.sleep(button_delay)

 

    if (buttons & cwiid.BTN_PLUS):

        print 'Plus 버튼'

        time.sleep(button_delay)   

 

def getAcc(wii):

    acc_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC

    acc = wii.state['acc']

    print "acc=",acc

    time.sleep(acc_delay)

 

def getIR(wii):

    ir_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_IR

    ir = wii.state['ir_src']

    print "ir=",ir

    time.sleep(ir_delay)  

 

def getNunchuk(wii):

    nunchuk_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_NUNCHUK

    nunchuk = wii.state['nunchuk']

    print "Nunchuk =",nunchuk

    time.sleep(nunchuk_delay)    

 

def getNunchukAcc(wii):

    nunchuk_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_NUNCHUK

    nunchuk = wii.state['nunchuk']['acc']

    print "Nunchuk Acc =",nunchuk

    time.sleep(nunchuk_delay)

 

def getNunchukButtons(wii):

    nunchuk_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_NUNCHUK

    nunchuk = wii.state['nunchuk']['buttons']

    if (nunchuk & cwiid.NUNCHUK_BTN_C):

        print 'Nunchuk 버튼 C'

        time.sleep(nunchuk_delay)

    if (nunchuk & cwiid.NUNCHUK_BTN_Z):

        print 'Nunchuk 버튼 Z'

        time.sleep(nunchuk_delay)  

 

def getNunchukStick(wii):

    nunchuk_delay = 0.1

    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_NUNCHUK

    nunchuk = wii.state['nunchuk']['stick']

    print 'Nunchuk Stick =', nunchuk

    time.sleep(nunchuk_delay)

 

if __name__ == "__main__":

    wii = setup()

    while True:

        getButtons(wii)

7. 파이썬 스크립트 실행

이제 파이썬 스크립트를 실행하고 Wii 리모컨의 버튼 1, 2를 동시에 누른다. 별 다른 문제가 없다면 라즈베리 파이와 Wii 리모컨이 연결되고, 리모컨의 버튼을 누를 때마다 터미널에 해당 버튼의 값이 출력된다.