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

Ex-Staff (retired)
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

Ex-Staff (retired)
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

Ex-Staff (retired)
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

Ex-Staff (retired)
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