IPB

Welcome Guest ( Log In | Register )

2 Pages V   1 2 >  
Reply to this topicStart new topic
> solved: direct connect Wii Nunchuk over I2C with NXT
t.wolf
post Nov 15 2008, 01:01 PM
Post #1


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



The cheap Nunchuk controller features an analog stick with a 3-axis-accelerometer for motion-sensing over a I2C-Connector.
http://www.wiili.org/index.php/Wiimote/Ext...rollers/Nunchuk


For technical details (pullups, I2c) see: http://forums.nxtasy.org/index.php?showtopic=3043&st=0

There are good C-Code for Nunchuk at http://www.windmeadow.com/node/42

used parts
1x Nunchuk (ebay 15EUR)
1/2 NXT cable (0,75EUR, at legoshop 7 hole cables for 10EUR)
2x resistors 33k (0,10EUR)
1x diode 1N4148 (0,10EUR)

...the Lego Accelerometer Sensor costs 55EUR by www.lego.de (Item: MS1040).

construction manual

1. Open the nunchuk case with a small screw-driver (1,5mm).
Video: http://www.youtube.com/watch?v=V4Jc2usqBIg

2. you are here: http://wiire.org/Wii/nunchuk

3. Now desolder the 1,8k pullup-resistors R1 and R2.
No fear of SMD. SMDs sticks to soldering iron
Attached File  R1.jpg ( 18.71k ) Number of downloads: 12

Attached File  R2.jpg ( 19.38k ) Number of downloads: 10


4. Now solder the new pullup resistors. The Lego reference design suggests 82kohm pullup resistors for i2c. I found out, that 33kohm is the best value for stable connection. I changed the SMD resistors, but if you have no SMS resistors use common 1/4W size and solder the resistors on the connection cables.
Additionally I mounted a drop-voltage-diode to reduce the voltage of the nunchuk.
see specification of motion sensor (3,6V) http://www.st.com/stonline/products/literature/ds/11668.pdf
Quite a few people connect the Nunchuk to 5V without problems. You decide.

circuit:
Attached File  circuit.png ( 3.38k ) Number of downloads: 14

Here you can see the diode. There are enough places for non-smd-resistors:
Attached File  diode.jpg ( 19.04k ) Number of downloads: 13


5. cut the cable and connect it:
Attached File  connect.jpg ( 20.28k ) Number of downloads: 10


6. ready:
Attached File  Nunchuk.jpg ( 26.79k ) Number of downloads: 9


7. Download the test programm . I use NXC with the enhanced firmware by John Hansen. I love FormatNum("%02X", ...).
NXT-G also is possible.
CODE
#include "NXCDefs.h"

byte CMDNunchukInit[] = {0xA4, 0x40, 0x00};
byte CMDNunchukWrite[] = {0xA4, 0x00};
byte CMDNunchukRead[] = {0xA4};

byte nbytes;
byte outbuf[];

// port is the NXT port
// i2c_cmd is the nunchuk internal address register
// at i2c_cmd=0...5 are 6 Byte of sensor values
// at i2c_cmd=0x20 ... 0x2F  you get 16 Byte of calibration data
sub NunchukGetParamter(byte port, byte i2c_cmd)
{
  // Initialize the Nunchuk
  SetSensorLowspeed(port);
  LowspeedWrite(port, 0, CMDNunchukInit); //ask for 0 bytes
  while(LowspeedStatus(port, nbytes)>0);

  // Wait(1) is needless, the NXT command interpreter delays next i2c access 3ms

  CMDNunchukWrite[1] =i2c_cmd; //at 0x00: 6 Bytes of sensor values
  LowspeedWrite(port, 0, CMDNunchukWrite);   // write Nunchuk register address
  while(LowspeedStatus(port, nbytes)>0);

  byte count = 6;
  LowspeedWrite(port, count, CMDNunchukRead); //ask for count bytes
  while(LowspeedStatus(port, nbytes)>0);
  
  if(nbytes == count){
    LowspeedRead(port, count, outbuf)  //read data from buffer
    for(int i=0; i<count; i++ ){
      outbuf[i]=(outbuf[i]^0x17) + 0x17;
    }
  }
  else {
    ArrayInit(outbuf,0,0);    //error
  }
}

task main()
{
  while (true)
  {
    NunchukGetParamter(S1, 0x00);          //see comment for i2c_cmd
    if (ArrayLen(outbuf)==6) {
       string Nunchuk="aXaYgXgYgZCZ";
       if ((outbuf[5]&0x01)!=0) {Nunchuk[11]=122;}  //Show Z-Button
       if ((outbuf[5]&0x02)!=0) {Nunchuk[10]=99;}   //Show C-Button
       ClearScreen();
       for(int i=0; i<ArrayLen(outbuf); i++ ) {
         TextOut(15*i, LCD_LINE3, SubStr(Nunchuk, 2*i, 2));
         TextOut(15*i, LCD_LINE5, FormatNum("%02X", outbuf[i]));
       }
       CircleOut((outbuf[0]-0x1E)/2, (outbuf[1]-0x1E)/3, 3);    //analog stick
       RectOut((outbuf[2]-0x46), (outbuf[3]-0x46)/2, 6, 6);    //acceleration value
    }
    Wait(100);
  }
}

the code draw a circle controlled by the analog stick and a rectangle controlled by the acceleration sensor


8. a video at youtube:
http://www.youtube.com/watch?v=HFQtyna58Kg
Go to the top of the page
 
+Quote Post
elcanario
post Nov 16 2008, 09:47 AM
Post #2


Newbie
*

Group: Members
Posts: 8
Joined: 29-December 07
Member No.: 4,421



Great job!

Would you have any test results on the polling speed, the resolution and the maximum g-range?

Go to the top of the page
 
+Quote Post
mike1
post Nov 16 2008, 11:14 AM
Post #3


Advanced Member
***

Group: Members
Posts: 1,384
Joined: 29-March 07
From: a black hole in a Gallaxy far far away
Member No.: 1,687



I believe on the documentation of the Acelleration chip, I think it was 2G.


--------------------
Seeing if I can combine VB.net and NXT together :]

Status: Worried that my hard drive will fail... T.E.C Date is in 5 days...
Go to the top of the page
 
+Quote Post
t.wolf
post Nov 16 2008, 03:15 PM
Post #4


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



QUOTE(elcanario @ Nov 16 2008, 09:47 AM) *
Would you have any test results on the polling speed, the resolution and the maximum g-range?

for details about the resolution read the first link: http://www.wiili.org/index.php/Wiimote/Ext...rollers/Nunchuk

the datasheet of ST Microelectronics LIS3L02AL 3-axis accelerometer: http://www.st.com/stonline/products/literature/ds/11668.pdf

some people ask me for working RobotC-Code
CODE
byte CMDNunchukInit[] = {0x03, 0xA4, 0x40, 0x00};
byte CMDNunchukWrite[] = {0x02, 0xA4, 0x00};
byte CMDNunchukRead[] = {0x01, 0xA4};

byte outbuf[6];
int outbuf1[6];   //ubyte workaround for RobotC

//  This function allows conversion of an unsigned byte to a signed int
//  This is a workaround for RobotC
int ubyteToInt(ubyte _byte) {
    int _ret = 0;
    _ret = (_byte & 0x80) ? (_byte & 0x7F) + 0x80 : _byte;
    return _ret;
}

// port is the NXT port, i2c_cmd is the nunchuk internal address register
// at i2c_cmd=0...5 are 6 Byte of sensor values
// at i2c_cmd=0x20 ... 0x2F  you get 16 Byte of calibration data

sub NunchukGetParamter(tSensors port, byte i2c_cmd)
{
  // Initialize the Nunchuk
    SensorType[port] = sensorI2CCustom;
    sendI2CMsg(port, CMDNunchukInit[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING); // Wait for I2C bus to be ready

  CMDNunchukWrite[2] =i2c_cmd;

    sendI2CMsg(port, CMDNunchukWrite[0], 0);

  while (nI2CStatus[port] == STAT_COMM_PENDING); //Wait for I2C bus to be ready

  byte count = 6;
    sendI2CMsg(port, CMDNunchukRead[0], count);

  while (nI2CStatus[port] == STAT_COMM_PENDING); // Wait for I2C bus to be ready

  if(nI2CBytesReady[port] == count){

      readI2CReply(port, outbuf[0], 6);

    for(int i=0; i<count; i++ ){
        outbuf1[i]=ubyteToInt(outbuf[i]);   //ubyte workaround for RobotC
      outbuf1[i]=(outbuf1[i]^0x17) + 0x17;
    }
  }
  else {
      memset(outbuf, 0, 0);       //RobotC
  }
}

task main()
{
  while (true)
  {
    NunchukGetParamter(S1, 0x00);          //see comment for i2c_cmd

    if (sizeof(outbuf)==6)    {

       char Nunchuk[16];
       strcpy(Nunchuk, "aXaYgXgYgZCZ");

       if ((outbuf1[5]&0x01)!=0) {Nunchuk[11]=122;}  //Show Z-Button
       if ((outbuf1[5]&0x02)!=0) {Nunchuk[10]=99;}   //Show C-Button

       eraseDisplay();   //RobotC

       for(int i=0; i<6; i++ ) {  //RobotC

         nxtDisplayStringAt(15*i,50,"%c", Nunchuk[2*i]);
         nxtDisplayStringAt(15*i+5,50,"%c", Nunchuk[2*i+1]);

         nxtDisplayStringAt(15*i,40,"%02X", outbuf1[i]);
       }

       nxtDrawCircle((outbuf1[0]-0x1E)/2, (outbuf1[1]-0x1E)/3, 3);

       nxtDrawCircle((outbuf1[2]-0x46), (outbuf1[3]-0x46)/2, 6);
    }
    wait1Msec(100);
  }
}


the code draw a small circle controlled by the analog stick and a large circle controlled by the acceleration sensor

Go to the top of the page
 
+Quote Post
t.wolf
post Nov 17 2008, 04:15 AM
Post #5


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



QUOTE(Charlie @ Nov 16 2008, 12:30 AM) *
t.wolf -- WOW great job!!! I wish I had more time to do cool stuff like this!
I believe you could use something like the TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER http://focus.ti.com/lit/ds/symlink/p82b96.pdf -- it should eliminate the need to hack into the Nunchuck and desolder the resistors, as it would provide isolation between the NXT and the nunchuck.
I did get a sample and it worked great with a Parallax BS2 microcontroller -- just haven't had a chance to try it with my NXT.

I think this could be useful for all other NXT to i2c projects as well. Does any one else think this would be helpful, or am I missing something?

You are right.
alternative: use the simple level shifter with two MOSFETs
see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf and Philips AN97055
Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego


Edit: This is not tested but I think, that this circuit don't beat the low-level-voltage problem of NXT (4,7k input resistor)
Use an IC like TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER.
Google for -> i2c level shifter

----------------------

Alternatives for cut up the cord on your Nunchuck
variant 1:
Four thick wires soldered on a circuit board. I used a breadboard for connection:


variant 2:
a commercial adapter: http://store.fungizmos.com/index.php?main_...products_id=212


variant 3:
an old floppy adapter and a plug-in connector of an old ISA card.
Go to the top of the page
 
+Quote Post
McKaamos
post Nov 17 2008, 12:41 PM
Post #6


Member
**

Group: Members
Posts: 26
Joined: 17-November 08
From: The Netherlands
Member No.: 6,274



Looks absolutely awesome!

Is there already an NXT-G block available? I'm not much of a programmer so I'd rather steer clear of RobotC, NXC and other fancy programming languages.
I am pretty good with a soldering iron, if I may say so myself, so modifying a Wii Nunchuck shouldn't be a problem.


--------------------
If you ain't Dutch, you ain't much ;)
Go to the top of the page
 
+Quote Post
esmetabot
post Nov 17 2008, 04:20 PM
Post #7


Member
**

Group: Members
Posts: 29
Joined: 29-October 06
Member No.: 414



QUOTE(t.wolf @ Nov 17 2008, 10:15 AM) *
You are right.
alternative: use the simple level shifter with two MOSFETs
see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf
Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego


----------------------

Alternatives for cut up the cord on your Nunchuck
variant 1:
Four thick wires soldered on a circuit board. I used a breadboard for connection:


variant 2:
a commercial adapter: http://store.fungizmos.com/index.php?main_...products_id=212


variant 3:
an old floppy adapter and a plug-in connector of an old ISA card.


Hi if you use Variant 2, do you have a schema to connect the adapter with NXT Wire?

Fantastic work!
Go to the top of the page
 
+Quote Post
t.wolf
post Nov 18 2008, 06:18 PM
Post #8


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



QUOTE(McKaamos)
Is there already an NXT-G block available?

you can write a NXT-G program with i2c blocks:
http://www.mindsensors.com the NXT-G Blocks Repository
IIC_Read.zip - I2C Read block version 1.0b by xw25adc 09/29/2007
IIC_Write.zip - I2C Write block version 1.0b by xw25adc 09/29/2007

QUOTE(esmetabot)
Hi if you use Variant 2, do you have a schema to connect the adapter with NXT Wire?

Cut down your quote please!

this is the wiring diagram to connect the adapter with NXT Wire (see above): http://freenet-homepage.de/tomasf/nunchuk/circuit.png
Go to the top of the page
 
+Quote Post
MrQuincle
post Nov 20 2008, 03:55 AM
Post #9


Member
**

Group: Members
Posts: 21
Joined: 21-March 07
From: Delft, Holland
Member No.: 1,607



QUOTE(t.wolf @ Nov 17 2008, 04:15 AM) *
You are right.
alternative: use the simple level shifter with two MOSFETs
see Philips Application note: http://www.nxp.com/acrobat_download/applic...s/AN10441_1.pdf and Philips AN97055
Rp left: 1,8k insight Nunchuk / Rp right: 82k Lego


Edit: This is not tested but I think, that this circuit don't beat the low-level-voltage problem of NXT (4,7k input resistor)
Use an IC like TI P82B96 DUAL BIDIRECTIONAL BUS BUFFER.
Google for -> i2c level shifter


So, it's not possible to use this level shifter? It is indeed the thing that I have tried, but it doesn't work out. What exactly is the low-level-voltage problem you refer too? I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope.
Go to the top of the page
 
+Quote Post
t.wolf
post Nov 20 2008, 05:59 PM
Post #10


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



QUOTE(MrQuincle @ Nov 20 2008, 03:55 AM) *
I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope.

You are right. See my detailed description of the series resistors of 4,7kohm in this post:
http://forums.nxtasy.org/index.php?showtop...ost&p=23376
Go to the top of the page
 
+Quote Post
t.wolf
post Nov 23 2008, 10:21 AM
Post #11


Member
**

Group: Members
Posts: 25
Joined: 20-February 08
From: Germany
Member No.: 4,776



QUOTE(MrQuincle @ Nov 20 2008, 03:55 AM) *
I've used the Rp resistance at the NXT side of 82k as Lego prescribes. Apparently the NXT is not able to get the SDA or SCL lines to 0V if I look on a oscilloscope.


How to beat the series resistors of 4,7kohm inside NXT without desoldering the internal 1,8k pullup-resistors of Nunchuk?

Try this simple bidirectional level shifter with a npn and pnp transistor. I have not tested my proprietary development, but the free Spice Simulator : LTspice IV simulate the circuit and works OK. With the two transistors (BC550 / BC560) the NXT pull down the LOW Level to 0,8V on the Nunchuk side. The 1,8k pullup inside the Nunchuk is the voltage source of this level booster.
If the Nunchuk sinks the I2C-level to LOW the supply voltage of complementary Darlington transistors is zero.
Attached File  level.png ( 3.7k ) Number of downloads: 6

Hint: For DATA- and CLOCK-line you need 4 transistors and two resistors ;-)
Go to the top of the page
 
+Quote Post
DaveB
post Dec 11 2008, 04:41 PM
Post #12


Newbie
*

Group: Members
Posts: 1
Joined: 11-December 08
Member No.: 6,452



I found this post while search for some Wii Nunchuk info. If someone has made a video of this adapted Wii Nunchuk in action please post up a link. I'd love to put the video up on my Wii Nunchuk website. Awesome use of the device.
Go to the top of the page
 
+Quote Post
mike1
post Dec 11 2008, 06:40 PM
Post #13


Advanced Member
***

Group: Members
Posts: 1,384
Joined: 29-March 07
From: a black hole in a Gallaxy far far away
Member No.: 1,687



It should be on NXTasy.org blog. It should be a few posts down...


--------------------
Seeing if I can combine VB.net and NXT together :]

Status: Worried that my hard drive will fail... T.E.C Date is in 5 days...
Go to the top of the page
 
+Quote Post
NXTreme
post May 28 2009, 05:48 PM
Post #14


Advanced Member
***

Group: Members
Posts: 207
Joined: 25-May 09
From: El país del taco!
Member No.: 7,516



How'd I program it in NXT-G? Would the accel sensor block work? Thanks! Never mind, I figured it out.


--------------------
One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them
On Earth where shadows lie.
Go to the top of the page
 
+Quote Post
NXTreme
post Jun 27 2009, 07:47 PM
Post #15


Advanced Member
***

Group: Members
Posts: 207
Joined: 25-May 09
From: El país del taco!
Member No.: 7,516



-EDIT- Double post.


--------------------
One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them
On Earth where shadows lie.
Go to the top of the page
 
+Quote Post
AZ_RobotLab
post Feb 14 2010, 10:37 AM
Post #16


Newbie
*

Group: Members
Posts: 6
Joined: 14-February 10
Member No.: 9,561



QUOTE(NXTreme @ May 28 2009, 03:48 PM) *
How'd I program it in NXT-G? Would the accel sensor block work? Thanks! Never mind, I figured it out.

Could you post a picture of your program or attach it to a reply? I have made the sensor and would like to know how to program it in NXT-G. I already have the I2C Read/Write blocks but do not know how to use them for the nunchuck.

Thanks! AZ_RobotLab
Go to the top of the page
 
+Quote Post
AZ_RobotLab
post Feb 14 2010, 10:43 AM
Post #17


Newbie
*

Group: Members
Posts: 6
Joined: 14-February 10
Member No.: 9,561



Whoops! Double post.
Go to the top of the page
 
+Quote Post
NXTreme
post Feb 18 2010, 10:40 PM
Post #18


Advanced Member
***

Group: Members
Posts: 207
Joined: 25-May 09
From: El país del taco!
Member No.: 7,516



I actually never created the program, I never got around to buying a Nunchuk (I did find them for $8 on eBay though). It seems fairly easy. Get the multibyte I2C read block from this page. This page makes it seem like all you need to do is write 0x00 to register 0x40 at address 0x52 and read back 6 bytes (possible with the multibyte block; not possible with the regular I2C block). Then you need to interpret the bytes coming back.

I will try to get a nunchuk as soon as possible so that I can actually make sure that this works. For eight dollars.... biggrin.gif


--------------------
One King to rule them all, One King to find them,
One King to bring them all and in the darkness bind them
On Earth where shadows lie.
Go to the top of the page
 
+Quote Post
AZ_RobotLab
post Feb 18 2010, 11:08 PM
Post #19


Newbie
*

Group: Members
Posts: 6
Joined: 14-February 10
Member No.: 9,561



QUOTE(NXTreme @ Feb 18 2010, 08:40 PM) *
I actually never created the program, I never got around to buying a Nunchuk (I did find them for $8 on eBay though). It seems fairly easy. Get the multibyte I2C read block from this page. This page makes it seem like all you need to do is write 0x00 to register 0x40 at address 0x52 and read back 6 bytes (possible with the multibyte block; not possible with the regular I2C block). Then you need to interpret the bytes coming back.

I will try to get a nunchuk as soon as possible so that I can actually make sure that this works. For eight dollars.... biggrin.gif


Thanks!
Go to the top of the page
 
+Quote Post
AZ_RobotLab
post Feb 23 2010, 08:01 PM
Post #20


Newbie
*

Group: Members
Posts: 6
Joined: 14-February 10
Member No.: 9,561



I tried t.wolf's RobotC code and got three errors with the portion of code below when I tried to compile it.
CODE

60    if (sizeof(outbuf)==6) {
61       char Nunchuk[16];
62       strcpy(Nunchuk, "aXaYgXgYgZCZ");
63
64       if ((outbuf1[5]&0x01)!=0) {Nunchuk[11]=122;}  //Show Z-Button
65       if ((outbuf1[5]&0x02)!=0) {Nunchuk[10]=99;}   //Show C-Button
66
67       eraseDisplay();   //RobotC
68
69       for(int i=0; i<6; i++ ) {  //RobotC
70
71         nxtDisplayStringAt(15*i,50,"%c", Nunchuk[2*i]);
72         nxtDisplayStringAt(15*i+5,50,"%c", Nunchuk[2*i+1]);
73
74         nxtDisplayStringAt(15*i,40,"%02X", outbuf1[i]);
75       }


Here are the errors:
Line 62 = **Error**:Procedure call Parameters don't match declaration for 'strcpy(byte &pToBuffer, const byte &pFromBuffer)'

Line 71 **Error**:Multiple overloads for 'nxtDisplayStringAt' match [including some typedef promotions]

Line 72 **Error**:Multiple overloads for 'nxtDisplayStringAt' match [including some typedef promotions]

Does anybody know how to fix this?
Go to the top of the page
 
+Quote Post

2 Pages V   1 2 >
Reply to this topicStart new topic

 



Lo-Fi Version Time is now: 1st August 2010 - 04:30 AM