Use a Wii Motion Plus, using I2C interface ?

Discussion specific to the intelligent brick, sensors, motors, and more.
hergipotter
Posts: 48
Joined: 12 Jan 2011, 18:40
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by hergipotter »

oh good lord, i first have to find my magnifying glass for this...
link to my youtube channel under my avatar!
hergipotter
Posts: 48
Joined: 12 Jan 2011, 18:40
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by hergipotter »

Ok, i'm much to unexperienced with such things...

Image

I can't follow a trace to a resistor at all.
Seems like there isn't a trace from the CLK pin at all?! Or is it within another layer?
link to my youtube channel under my avatar!
dt22
Posts: 4
Joined: 02 Feb 2011, 17:33

Re: Use a Wii Motion Plus, using I2C interface ?

Post by dt22 »

it seem not easy ...

Mybe with a multimeter it could be possible to find the connections.
hergipotter
Posts: 48
Joined: 12 Jan 2011, 18:40
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by hergipotter »

I already searched with my multimeter but no resistor seems to be directly connected with on of the three pins...

Perhaps the pull-ups are integrated in the µC?
link to my youtube channel under my avatar!
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by mattallen37 »

That picture isn't clear enough. Try looking for two resistors that have the same values as each other, and are probably fairly close on the PCB. You are probably looking for something like 4k7 or 10k (maybe 2k2). The actual value isn't all that important, but it should be something like that.

Another option, you could try it with the existing resistors. It won't damage the NXT, as it has 4k7 protection resistors. It almost definitely won't work, but it is worth a try. nxtreme has had success using 10k with a compass, so you never know.

I happen to have an NXT-PICAXE project right in front of me. It is a simple setup, where the PICAXE (20X2) is an I2C slave, and the NXT is the master. I have the NXT reading values from it (it's ADC values). I just swapped out the pullups, to see when I stopped getting good readings. It worked up to 10k, but any stronger (even a 100k in parallel with the 10k), and it failed (on the clock line, but not data). I increased resistance to 1m, and it didn't work, so I tried 470k, and it works fine. It appears that the NXT is okay with anything in the 10k-470k ohm resistor range, but that was with a 20X2, other ICs might not be able to go to these limits.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by mattallen37 »

hergipotter wrote:...Perhaps the pull-ups are integrated in the µC?
That is possible, some u-controllers do integrate them, but usually the designer can turn them off. I think the PICAXE 20X2's have an option to have pullups internally on their I2C lines, but I have never looked into it.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
hergipotter
Posts: 48
Joined: 12 Jan 2011, 18:40
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by hergipotter »

Little Update:

I recently realised, that the cables on the motion plus have very different colors than with the nunchuk.

VCC - grey
SCL - red
SDA - green
GND - blue/black

But that doesn't change much, i still could not find the pull ups. But i found two resistors, that are close and have values of 10k, when tested in circuit (My multimeter tests the resistance between the two connectors of the resistor, that does not need to be the actual resistance value of the resistor). They're R13 and R4 on the other side of the pcb. R4 is connected with VCC on one side, but i could not find a connection to CLK or DATA on the other side. On the other hand R13 is connected to GND on one side. I'm not really sure what that means...

So i just tried to read the sensors without changing the resistors but it won't work.
I hope my code is correct.

Code: Select all

#define PORT S4
#define LOOPS 1

byte WMplusActivate[] = {0xA6, 0xFE, 0x04};
byte WMplusWrite[] = {0xA4, 0x00};
byte WMplusRead[] = {0xA4};

byte nbytes;
byte data[];

void initWMplus()
{
   LowspeedWrite(PORT, 0, WMplusActivate);
   while(LowspeedStatus(PORT, nbytes)>0);
}

void readWMplus()
{
   LowspeedWrite(PORT, 0, WMplusWrite);
   while(LowspeedStatus(PORT, nbytes)>0);


   LowspeedWrite(PORT, 6, WMplusRead);       //ask for 6 bytes
   while(LowspeedStatus(PORT, nbytes)>0);

   NumOut(15, LCD_LINE6, nbytes);    // Print number of bytes read
   if(nbytes == 6){
      LowspeedRead(PORT, 6, data)  //read data from buffer
      for(int i=0; i<6; i++ ){
         data[i]=(data[i]^0x17) + 0x17;  // decode data
      }
   }
   else {
      ArrayInit(data,0,0);    //error
   }
}

task main()
{
   SetSensorLowspeed(PORT);
   initWMplus();
   
   for (int j = 0; j < LOOPS; j++)
   {
      ClearScreen();
      readWMplus();

      /*if (ArrayLen(data)==6) {
          for(int i=0; i<ArrayLen(data); i++ ) {
            TextOut(15*i, LCD_LINE5, FormatNum("%02X", data[i]));  //hex: enhanced firmware
            //NumOut(15*i, LCD_LINE5, data[i]);  //dez: lego firmware
          }
      }      */
      
      Wait(100);
   }
   Wait(3000);
}
It just prints the number of bytes that were read but it always prints 0...
link to my youtube channel under my avatar!
hergipotter
Posts: 48
Joined: 12 Jan 2011, 18:40
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by hergipotter »

Finally a success!!
It seems, that there are no pull ups on the WMP at all. So i just put two 27k ones in there and it worked. Additionally i added two 1N 4148 diodes to lower the supply voltage. The NXT gives about 4.5V but the WMP normally works with 3.3V. Maybe it would also work with only one or no diode at all...

Some pictures and my testprogramm:
Image
Image
Image

Code: Select all

#define PORT S4
#define SHOW_CALIB_VALUES

byte WMplusActivate[] = {0xA6, 0xFE, 0x04};
byte WMplusWrite[] = {0xA4, 0x00};
byte WMplusRead[] = {0xA4};

byte nbytes;
byte data[];

int yaw, pitch, roll;      // variables holding sensor values
int yaw0, pitch0, roll0;   // variables for offset values


/* Initialises the Wii Motion Plus.
After this, the i2c address changes to 0xA4
*/
void initWMplus()
{
   LowspeedWrite(PORT, 0, WMplusActivate);
   while(LowspeedStatus(PORT, nbytes)>0);
}

/* Calibrates the offset values by
computing the average of ten readings
*/
void calibrateOffset()
{
   int i = 0;

   while (i < 10)     // read sensors 10 times
   {
      LowspeedWrite(PORT, 0, WMplusWrite);
      while(LowspeedStatus(PORT, nbytes)>0);


      LowspeedWrite(PORT, 6, WMplusRead);       //ask for 6 bytes
      while(LowspeedStatus(PORT, nbytes)>0);


      if(nbytes == 6)
      {
         LowspeedRead(PORT, 6, data);  //read data from buffer

         yaw0 += (((data[3]>>2)<<8) | data[0]) / 10;
         pitch0 += (((data[4]>>2)<<8) | data[1]) / 10;
         roll0 += (((data[5]>>2)<<8) | data[2]) / 10;
         
         i++;
      }

      Wait(50);
   }
   
   #ifdef SHOW_CALIB_VALUES
   {
      NumOut(55, LCD_LINE3, yaw0);
      NumOut(55, LCD_LINE4, pitch0);
      NumOut(55, LCD_LINE5, roll0);
      TextOut(5, LCD_LINE3, "yaw0: ");
      TextOut(5, LCD_LINE4, "pitch0: ");
      TextOut(5, LCD_LINE5, "roll0: ");

      Wait(3000);
   }
   #endif
}

/* Reads the sensor values.
After this, the raw values are stored in the data array
and the computed values can be read from yaw, pitch and roll variables
*/
void readWMplus()
{
   LowspeedWrite(PORT, 0, WMplusWrite);
   while(LowspeedStatus(PORT, nbytes)>0);


   LowspeedWrite(PORT, 6, WMplusRead);       //ask for 6 bytes
   while(LowspeedStatus(PORT, nbytes)>0);

   if(nbytes == 6){
      LowspeedRead(PORT, 6, data);  //read data from buffer

      yaw = (((data[3]>>2)<<8) | data[0]) - yaw0;
      pitch = (((data[4]>>2)<<8) | data[1]) - pitch0;
      roll = (((data[5]>>2)<<8) | data[2]) - roll0;
   }
   else {
      ArrayInit(data,0,0);    //error
   }
}

task main()
{
   SetSensorLowspeed(PORT);
   initWMplus();
   Wait(300);     // Wait some time after init
   calibrateOffset();
   
   while (true)
   {
      ClearScreen();
      readWMplus();

      if (ArrayLen(data)==6) {
         for(int i=0; i<ArrayLen(data); i++ ) {
            TextOut(15*i, LCD_LINE1, FormatNum("%02X", data[i]));  //hex: enhanced firmware
            //NumOut(15*i, LCD_LINE5, outbuf[i]);  //dez: lego firmware
          }
          
          NumOut(55, LCD_LINE3, yaw);
          NumOut(55, LCD_LINE4, pitch);
          NumOut(55, LCD_LINE5, roll);
          TextOut(5, LCD_LINE3, "yaw: ");
          TextOut(5, LCD_LINE4, "pitch: ");
          TextOut(5, LCD_LINE5, "roll: ");
      }
      Wait(200);
   }
}
Image
link to my youtube channel under my avatar!
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: Use a Wii Motion Plus, using I2C interface ?

Post by mattallen37 »

I am glad it work. Thanks for posting your results and example.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
nxtreme
Posts: 246
Joined: 29 Sep 2010, 03:53
Location: 192.168.1.2

Re: Use a Wii Motion Plus, using I2C interface ?

Post by nxtreme »

Wow, thanks for posting this! I had a bit of a hard time finding the resistors in my (knockoff) Nunchuck too. However, I finally measured the resistance from the clock and data pins to the power pin, to figure out what size pullups were installed. Then, I searched the board for two resistors that were of that value. Just a little hint for next time ;).

I'm hoping to eventually create a quadrotor, which would need 3x of gyros and 3x of accelerometers. It'd be especially fun to set it all up with the NXT, will have to bookmark this.

It almost looks to me like you soldered everything to the jack for the Nunchuck, not the end that goes into the WiiMote. That might be why you couldn't find any pullups, although I could be wrong :).

-EDIT- I just remembered that I was going to mention something else. I use 3.3V V-regs to drop the NXT's 4.5V down to 3.3V. I have only used the LP2950-33, but almost any would work just so long as you include the capacitors, which are necessary.
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.
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests