08M2 AND NUNCHUK, is it possible to read the data and utilize?

JPU

Senior Member
Hi All

I was just wondering if it was possible to use an 08m2 to ready the data from a Wii nunchuk. I'm especially interested in the data from a the joystick on the nunchuk. I`ve read lots about Arduino doing it so I guess it can be done but has anyone tried it?

Any pointers or tips will be gratefully received.
Thanks

JPU
 

JPU

Senior Member
Hi Ibenson

Thanks, I was just reading that very thread when you posted to this thread!! WOW.

Do you think it could be adapted for an 08m2?
 

hippy

Technical Support
Staff member
Do you think it could be adapted for an 08m2?
I haven't looked at the specific code linked to but, as the Nunchuck uses I2C, any code for a Nunchuck should work on any PICAXE which supports I2C.

I actually have code for reading and reporting everything on a Nunchuck using an 08M2 which I developed myself. I will have to look at my notes to recall what the status of that code is but I will post that once I have done so.
 

hippy

Technical Support
Staff member
A quick check shows the 08M2 Nunchuck code is complete. It has a few debugging routines in which I will strip out then post the code.

I got into trying Wii bits when cheap parts became available in high street buy and sell stores; 50p for a Nunchuck with a joystick was too good to miss and that also includes accelerometer which I had not realised at the time. I had intended to create a complete and documented 'Wii controller interfacing' project but, as always happens, other things came along.

I'll rework what I do have and post that to the Finished Project section and provide a link from here.

One thing worth looking out for if interested in connecting Wii controllers is a cheap Motion Plus plug-in module from which a connector can easily be extracted to connect to a breadboard or PICAXE and have any wired Wii controller connect to. There are Wii controller extension cables which can be cut and bare-ended but I have never seen one.

Having a socket to plug Wii controllers into is well worth the investment, saves a lot of aggravation, means you don't have to open or cannibalise anything, and can borrow and easily try other controllers.
 

Bill.b

Senior Member
This code I developed some years ago for the Wii controller on a 28x2. I have not tested it on a 08M2.

I believe the shift right command >> is not available on the M2s
The data table section may be of some use in identifying the data structure.

Code:
'  Program to read data form a Wii Classic Controller into a picaxe 28X2.
'  Bill Brown  Bill.b   29th July 2013
'
'  I have tested the program with a 40X2 and it worked OK.  The program does not work correctlly with M2 chips
'  Some more work is required for M2s
'
'
' The Wii Receiver module required a 3.3volt supply. 
' In my test unit i derived the 3.3v by connection two IN4001 diodes in series  to the 5v supply giving approximatly 3.4v.
' 4k7 pullup reistors are unsed on the SCL and SDA - Connected to the +3.4v supply
'
' Data format for the 6 bytes of data from the Wii Classic Controller  (WiiByte0 - 5)
'---------------------------------------------------------------
'|Byte  |                            Bit                        |
'|------|-------------------------------------------------------|
'|      |  7   |   6  |   5  |   4  |   3  |   2  |   1  |   0  |
'|--------------------------------------------------------------|
'|  0   |    RX<4:3>  |         LX<5:0>                         |
'|--------------------------------------------------------------|
'|  1   |    RX<2:1>  |         LY<5:0>                         |
'|--------------------------------------------------------------|
'|  2   |RX<0> |  LT<4:3>    |         RY<4:0>                  |
'|--------------------------------------------------------------|
'|  3   |    LT<2:0>         |         RY<4:0>                  |
'|--------------------------------------------------------------|
'|  4   | BDR  |  BDD | BLT  | B-   |  BH  |  B+  | BRT  |  1   |
'|--------------------------------------------------------------|
'|  5   | BZL  |  BB  |  BY  |  BA  |  BX  | BZR  | BDL  | BDU  |
'!--------------------------------------------------------------! 
'
'LX,LY are the left analogue stick, X and Y (0 - 63). RX and RY are the right analogue stick, X and Y (0 - 31).
'LT and RT are the left and right triggers (0 - 31). The left analogue stick has twice the precision of the other stick
'
' BD(L,R,U,D) are the D-Pad direction buttons.  B(ZR,ZL,A,B,X,Y,+,H,-) are the discrete buttons.
'B(LT,RT) are the digital button click of the LT and RT. all Buttons are 0 when pressed.

#picaxe 28x2
setfreq m8
symbol WiiByte0   = b7        'Wii byte 0
symbol WiiByte1   = b8        'Wii byte 1
symbol WiiByte2   = b9        'Wii byte 2
symbol WiiByte3   = b10       'Wii byte 3
symbol WiiByte4   = b11       'Wii byte 4
symbol WiiByte5   = b12       'Wii byte 5
symbol WiiTemp0   = b13       'Wii Temperary storage byte 
symbol WiiLeftX   = b14       'Left stick X axis 0 - 63
symbol WiiLeftY   = b15       'Left stick Y axis 0 - 63
symbol WiiRightX  = b16       'Right stick X axis 0 - 31 
symbol WiiRightY  = b17       'Right stick Y axis 0 - 31
symbol WiiLeftT   = b18       'Left trigger 0 - 31
symbol WiiRightT  = b19       'Right trigger 0 - 31

i2cslave %010100100, i2cfast_16, i2cbyte     'I2C setup for Wii controller
hi2cout 0,($F0,$55)                          'Wii Configuration bytes 
pause 10
hi2cout 0,($FB,00)                           'Wii Configuration bytes 
pause 10
hi2cout 0, ($00)                             'Wii Request data 

'Main program start here

main:

hi2cout 0, ($00)                              'Wii Request data
pause 70
hi2cin 0,(WiiByte0,WiiByte1,WiiByte2,WiiByte3,WiiByte4,WiiByte5)        'Data from Wii Controller

'The following section arranges the data from the Wii bytes 0 - 4 into seperate bytes for used in the program

pause 50
WiiLeftX = WiiByte0 & %00111111     'Left stick X = Bits 0 - 5 of wiibyte0
WiiLeftY = WiiByte1 & %00111111     'Left stick Y = Bits 0 - 5 of wiibyte1
WiiRightX = WiiByte2 & %00011111    'Right stick X = Bits 0 - 4 of wiibyte2
WiiRightY = WiiByte2 & %10000000    'Move bit 7 of wiibyte2 to Right stick Y
WiiRightY = WiiRightY >> 2          'shift right 2 places
WiiTemp0 = WiiByte1 & %11000000     'move bits 6 & 7 of wiibyte1 to temp
WiiRightY = WiiRightY OR WiiTemp0   'Combine temp and right stick Y
WiiRightY = WiiRightY >> 2          'Shift right 2 places
WiiTemp0 = WiiByte0 & %11000000     'move bits 6 & 7 of wiibyte0 to temp
WiiRightY = WiiRightY OR WiiTemp0   'Combine temp and right stick Y
WiiRightY = WiiRightY >> 3          'Shift right 3 places.  Right stick Y byte completed
WiiRightT = WiiByte3 & %00011111    'move Right Tigger bits 0 - 5 form wiibyte 3 to wiiRightT 
WiiLeftT = WiiByte3 & %11100000     'move left trigger bits 5 - 7 form wiibyte 3 to wiiLeftT
WiiLeftT = WiiLeftT >> 3            'shift right 3 positions.
WiiTemp0 = WiiByte2 & %01100000     'Move Left trigger bits 3 & 4 to temp	
WiiLeftT = WiiLeftT OR WiiTemp0     ' combine wiiLeftT and Temp
WiiLeftT = WiiLeftT >> 2            'Shift right 2 positions to complete wiiLeftT byte.

'debug

goto main

Bill
 

hippy

Technical Support
Staff member
Here's my Nunchuck code for 08M2

Initialisation is as follows; Device Address $A4, Write $55 to register $F0, write $00 to register $FB, read the 6 byte identifier from register $FA onwards ( $00 $00 $A4 $20 $00 $00 ), then repeatedly read the 6 bytes of Nunchuck data from register $00 onwards. The data is not encrypted.

Code:
    7   6   5   4   3   2   1   0
  .-------------------------------.
0 |             JX7:0             | Joystick X ( Left to Right )
  |-------------------------------|
1 |             JY7:0             | Joystick Y ( Down to Up )
  |-------------------------------|
2 |              X9:2             | Acceleration X ( msb )
  |-------------------------------|
3 |              Y9:2             | Acceleration Y ( msb )
  |-------------------------------|
4 |              Z9:2             | Acceleration Z ( msb )
  |-------.-------.-------.---.---|
5 |  Z1:0 |  Y1:0 |  X1:0 | C | Z | Acceleration lsbs + buttons
  `-------^-------^-------^---^---'
Output should appear something like this, joystick, axis and button data -

Code:
JX : 00011011     27    JOY LEFT
JY : 11111111     255   JOY UP
AX : 10100100 10  658   TILT RIGHT
AY : 10100001 11  647   TILT DOWN
AZ : 10011000 11  611
BT : 11111001     C-
Put the joystick up and left and press the Z button and the PICAXE program enters a fast detect mode which uses the joystick as a left, right, up and down button set.

Code in next post ...
 

hippy

Technical Support
Staff member
Code:
; **************************************************************************
; *                                                                        *
; *  Nunchuck Handler                                        NUNCHUCK-003  *
; *                                                                        *
; **************************************************************************

#Picaxe 08M2
#No_Data
#Terminal 4800

;        .-----_-----.              To Nunchuck
; 3V3 ---| V+     0V |--- 0V             .-.
;       -| SI    C.0 |-          .------>|O| PWR
;    .---| C.4   C.1 |--- SCL ---|-------|O| SCL
;    |  -| C.3   C.2 |--- SDA ---|-------|O| SDA
;    |   `-----------'           |   .---|O| 0V
;    `---------------------------'  _|_  `-'
;                    
; Nunchuck includes 1K8 pull-ups on SDA and SCL
; PICAXE uses internal pull-ups so externals are not needed

Symbol SCL = C.1 : Symbol pinSCL = pinC.1
Symbol SDA = C.2 : Symbol pinSDA = pinC.2
Symbol PWR = C.4

; **************************************************************************
; *                                                                        *
; *  Main Program                                                          *
; *                                                                        *
; **************************************************************************

PowerOnReset:
  Pause 2000
  Gosub VoltCheck
  PullUp %000110
  High PWR
  Pause 1000

Initialise:
  SerTxd( CR, LF, "Looking for Nunchuck ...", CR, LF, CR, LF )
  Do
    Gosub InitNunchuck
    Gosub FindNunchuck
  Loop Until b0 <> 0

MainLoop:
  Do
    SerTxd( CR, LF )
    Gosub ReadNunchuck
    If w0 = 0 Then
      SerTxd( "Nunchuck removed", CR, LF, CR, LF )
      Reset
    End If
    Gosub DumpNunchuck
    If b10 < $40 And b11 > $C0 And b2 = "Z" Then FastLoop
    Pause 1000
  Loop

; Put joystick to Up + Left and press Z for fast monitoring

FastLoop:
  SerTxd( CR, LF, "Fast monitoring", CR, LF, CR, LF )
  b1 = 0
  Do
    HI2cIn $00, ( b10,b11,b12,b13,b14,b0 )
    b0 = b0 & 3 ^ 3
    Select Case b10
      Case < $40 : bit5 = 1 ; LEFT
      Case > $C0 : bit4 = 1 ; RIGHT
    End Select
    Select Case b11
      Case < $40 : bit2 = 1 ; DOWN
      Case > $C0 : bit3 = 1 ; UP
    End Select
    If b0 <> b1 Then
      LookUp bit5, ( "-", "L" ), b15
      LookUp bit4, ( "-", "R" ), b14
      LookUp bit3, ( "-", "U" ), b13
      LookUp bit2, ( "-", "D" ), b12
      LookUp bit1, ( "-", "C" ), b11
      LookUp bit0, ( "-", "Z" ), b10
      SerTxd( b15,b14,b13,b12,b11,b10, CR, LF )
      b1 = b0
    End If
  Loop

; **************************************************************************
; *                                                                        *
; *  Check PSU Voltage                                                     *
; *                                                                        *
; **************************************************************************

VoltCheck:
  Do
    CalibAdc10 w0
    w0 = 52378 / w0 * 2
    BinToAscii w0, b15,b14,b13,b12,b11
    SerTxd( "Vpsu = ", b13,".",b12,b11, "V")
    Select Case w0
      Case < 320 : SerTxd( " : Voltage < 3.2V" ) : Pause 500
      Case > 340 : SerTxd( " : Voltage > 3.4V" ) : Pause 500
    End Select
    serTxd( CR, LF )
  Loop Until w0 >= 320 And w0 =< 340
  Return

; **************************************************************************
; *                                                                        *
; *  Nunchuck Interfacing                                                  *
; *                                                                        *
; **************************************************************************

InitNunchuck:
  HI2cSetup I2CMASTER, $A4, I2CFAST, I2CBYTE
  HI2cOut $F0, ( $55 )
  HI2cOut $FB, ( $00 )
  Return

  ; 00 00 A4 20 00 00 = Nunchuck

FindNunchuck:
  HI2cIn $FA, ( b10,b11,b12,b13,b14,b15 )
  b0 = b10 : Gosub Hex
  b0 = b11 : Gosub Hex
  b0 = b12 : Gosub Hex
  b0 = b13 : Gosub Hex
  b0 = b14 : Gosub Hex
  b0 = b15 : Gosub Hex
  w0 = b11 + b12 + b13 + b14 + b15 ^ $4FB    ; 5 x $FF = $4FB 
  If w0 = 0 Then NoneNunchuck
  If b10 <> $00 Then FailNunchuck
  If b11 <> $00 Then FailNunchuck
  If b12 <> $A4 Then FailNunchuck
  If b13 <> $20 Then FailNunchuck
  If b14 <> $00 Then FailNunchuck
  If b15 <> $00 Then FailNunchuck
  SerTxd( "Nunchuck found", CR, LF )
  b0 = 1
  Return

FailNunchuck:
  SerTxd( "Not a Nunchuck", CR, LF )
  Pause 1000
  b0 = 0
  Return

NoneNunchuck:
  SerTxd( "No controller connected", CR, LF )
  Pause 1000
  b0 = 0
  Return

; **************************************************************************
; *                                                                        *
; *  Raed Nunchuck Data                                                    *
; *                                                                        *
; **************************************************************************

ReadNunchuck:

  ;     7   6   5   4   3   2   1   0  
  ;   .-------------------------------.
  ; 0 |             JX7:0             | Joystick X ( Left to Right )
  ;   |-------------------------------|
  ; 1 |             JY7:0             | Joystick Y ( Down to Up )
  ;   |-------------------------------|
  ; 2 |              X9:2             | Acceleration X ( msb )
  ;   |-------------------------------|
  ; 3 |              Y9:2             | Acceleration Y ( msb )
  ;   |-------------------------------|
  ; 4 |              Z9:2             | Acceleration Z ( msb )
  ;   |-------.-------.-------.---.---|
  ; 5 |  Z1:0 |  Y1:0 |  X1:0 | C | Z | Acceleration lsbs + buttons
  ;   `-------^-------^-------^---^---'

  HI2cIn $00, ( b10,b11,b12,b13,b14,b15 )
  w0 = b11 + b12 + b13 + b14 + b15 ^ $4FB    ; 5 x $FF = $4FB 
  Return

; **************************************************************************
; *                                                                        *
; *  Display Output Routines                                               *
; *                                                                        *
; **************************************************************************

DumpNunchuck:
  SerTxd( "JX" ) : b0 = b10                  : Gosub Joystick
                                               Select Case b0
                                                 Case < $40 : SerTxd( 9, "JOY LEFT" )
                                                 Case > $C0 : SerTxd( 9, "JOY RIGHT" )
                                               End Select
                                               SerTxd( CR, LF )

  SerTxd( "JY" ) : b0 = b11                  : Gosub Joystick
                                               Select Case b0
                                                 Case < $40 : SerTxd( 9, "JOY DOWN" )
                                                 Case > $C0 : SerTxd( 9, "JOY UP" )
                                               End Select
                                               SerTxd( CR, LF )

  SerTxd( "AX" ) : b0 = b12 : b1 = %00000100 : Gosub Accelerometer
                                               Select Case w0
                                                 Case < 400 : SerTxd( 9, "TILT LEFT" )
                                                 Case > 600 : SerTxd( 9, "TILT RIGHT" )
                                               End Select
                                               SerTxd( CR, LF )

  SerTxd( "AY" ) : b0 = b13 : b1 = %00010000 : Gosub Accelerometer
                                               Select Case w0
                                                 Case < 500 : SerTxd( 9, "TILT UP" )
                                                 Case > 620 : SerTxd( 9, "TILT DOWN" )
                                               End Select
                                               SerTxd( CR, LF )

  SerTxd( "AZ" ) : b0 = b14 : b1 = %01000000 : Gosub Accelerometer
                                               SerTxd( CR, LF )

  SerTxd( "BT" ) : b0 = b15                  : Gosub Buttons
  Return
  
Joystick:
  Gosub Bits
  SerTxd( "    ", #b0 )
  Return

Accelerometer:
  Gosub Bits
  b1 = b15 / b1 & 3
  w0 = b0 * 4 + b1
  SerTxd( #bit1, #bit0, "  ", #w0 )
  Return

Buttons:
  Gosub Bits
  LookUp bit1, ( "C", "-" ), b1
  LookUp bit0, ( "Z", "-" ), b2
  SerTxd( "    ", b1, b2, CR, LF )
  Return

Hex:
  b1 = b0 / $10 : Gosub Nibble
  b1 = b0 & $0F : Gosub Nibble
  SerTxd( " " )
  Return

Nibble:
  b1 = b1 + "0"
  If b1 > "9" Then : b1 = b1 + 7 : End If
  SerTxd( b1 )
  Return
  
Bits:
  SerTxd( " : ", #bit7,#bit6, #bit5, #bit4      )
  SerTxd(        #bit3,#bit2, #bit1, #bit0, " " )
  Return

; **************************************************************************
; *                                                                        *
; *  End Of Program                                                        *
; *                                                                        *
; **************************************************************************
 

JPU

Senior Member
Thank you all for your kind help.

Ive ordered a Numchuk and a small PCB break out board for the socket and so Ill give this a go and Im sure Ill be back with questions. Thanks Hippy!

JPU
 
Top