Sponsors of Wiimoteproject.com
IR Pens for Wiimote Whiteboard
Pages: [1]
Print
Author Topic: 2 nunchuck with arduino HELP  (Read 20101 times)
0 Members and 1 Guest are viewing this topic.
*
Karma: +0/-0
Posts: 11
Offline Offline
View Profile Email
« on: January 03, 2009, 07:55:19 AM »

Im trying to get 2 wii nunchucks to communicate with the arduino on the I2C bus. I know that the nunchucks have the same slave address, but I wasn't sure if there was a way to create a switch between the two DATA lines of the nunchucks.

for example:
Both nunchucks are connected to the same system clock (SCL) pin on the arduino...but there is a binary switch to choose which nunchuck's data line is connected to SDL on the arduino (and will be controlled by another pin on the arduino).
I'm just getting familiar with I2C, does this seem workable?

Is there a way to change the address of one of the slaves?
or
Is there a way to implement a 2nd i2c bus with programming and different analog pins?

maybe somebody could explain the I2C better for me then google :0)

THanks,

bd
Logged
Support Admin
*
Karma: +49/-0
Posts: 1178
Offline Offline
benpaddlejones@live.com.au View Profile WWW Email
« Reply #1 on: January 03, 2009, 02:14:33 PM »

johnnyonthreespots

Please watch the multiple postings!

benpaddlejones Smiley
p.s. I have removed the other two as this is the correct place for this question.
Logged


See my full profile and links on my Google Profile: http://www.google.com/profiles/benpaddlejones
*
Karma: +0/-0
Posts: 11
Offline Offline
View Profile Email
« Reply #2 on: January 20, 2009, 02:03:59 AM »

Alright, it seems that my idea has baffled it's viewers speachless ;0)

 But I'll keep anyone posted on my progress...

I have 2 ideas I am going to try out.

1) Using BJT transistors and diodes I will try to use the arduino microcontroller to switch the SDA line between the nunchucks.

2) Using Relays, I will control the SDA lines.

The goal is to keep each nunchuck 'thinking' that it is talking continuously to the arduino...yet have the arduino 'Choose' which nunchuck to listen to at a given moment (using a control pin off the arduino)

whish me luck
Logged
*
Karma: +0/-0
Posts: 11
Offline Offline
View Profile Email
« Reply #3 on: February 02, 2009, 08:19:24 PM »

- SUCCESS -

Here's how to do it. All you need is 2 transistors (basic npn switch transistors), and 2 resistors and the use of 2 more arduino pins.

For the 2 nunchucks, I tied the 2 ground (white) wires, tied the 2 clock (yellow) wires, and tied the 2 power (red) wires. You have to make 2 switches (thus 2 transistors) each of which will disconnect the nunchuck's data (green) wire from the arduino.

Programming Note:
when you start up the 'system' , you'll need to have both nunchuck's data (green) wire connected to the arduino in order to initiate both at the same time. Then you can swap between each nunchuck.

Edited*
 Note: There is an error in the above statement. You must initiate each nunchuck individually in order for the arudino to store the correct values per nunchuck.

Link on transistor switches:
http://www.kpsec.freeuk.com/trancirc.htm


At first I tried using 1 npn and 1 pnp transistor, but I couldn't get the nunchuck to push its data through a pnp transitor...I'm not so sure why yet...but this would require the use of only 1 extra arduino pin, instead of 2...
« Last Edit: February 11, 2010, 10:31:38 PM by johnnyonthespot » Logged
*
Karma: +0/-0
Posts: 11
Offline Offline
View Profile Email
« Reply #4 on: February 03, 2009, 10:04:38 AM »

Code:
/* This program is designed to allow two Wii Nunchucks to operate on the same I2C bus
by the use of 2 BJT transisters. This file includes a demenstration of each nunchuck
controlling their own LED by use of their z_button (made with arduino - 0010 Alpha), circuit schematic can be found at this forum:
http://www.wiimoteproject.com/tech-chat/2-nunchuck-with-arduino-help/
Nunchuks operate off of 3v3 supplied by arduino
First Few lines of twi.h edit...
#define ATMEGA8

#ifndef CPU_FREQ^M
#define CPU_FREQ 16000000L
#endif

#ifndef TWI_FREQ^M
#define TWI_FREQ 100000L
#endif

found at:
http://www.windmeadow.com/node/42

have fun

bd
(aka:johnnyonthespot)
*/
#include <Wire.h>
#include <string.h>

#undef int
#include <stdio.h>

uint8_t outbuf1[6];             // array to store nunchuck1 output
uint8_t outbuf2[6]; // array to store nunchuck2 output
int cnt = 0;                    // count to make sure 6 bytes are received from nunchuck
int nunPin1 = 8;                // Digital pin to select nunchuck1
int nunPin2 = 9;                // Digital pin to select nunchuck2
int led1 = 2;                   // Pin connected to LED1 (turns off when nunchuck1's z_button is pushed
int led2 = 3;                   // pin connected to LED2 (turns off when nunchuck2's z_button is pushed
int state = LOW;                // keeps tabs on which nunchuck is being read (Low = n1, High = n2)

void
setup ()

  pinMode(nunPin1, OUTPUT);
  pinMode(nunPin2, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  digitalWrite(nunPin1, HIGH);   // both nunchucks must start out high
  digitalWrite(nunPin2, HIGH);   //in order to initiate both at once
  Wire.begin (); // join i2c bus with address 0x52
  nunchuck_init ();              // send the initilization handshake
}

void
nunchuck_init ()
{
  Wire.beginTransmission (0x52);  // transmit to device 0x52
  Wire.send (0x40);   // sends memory address
  Wire.send (0x00);   // sends sent a zero. 
  Wire.endTransmission ();   // stop transmitting
}

void
send_zero ()
{
  Wire.beginTransmission (0x52); // transmit to device 0x52
  Wire.send (0x00); // sends one byte
  Wire.endTransmission (); // stop transmitting
}

void
change_nunchuck()      // Swaps between nunchucks
{
  if (state == LOW)
  {
    digitalWrite(nunPin1, LOW);
    digitalWrite(nunPin2,HIGH);
    state = HIGH;
  }
  else
  {
    digitalWrite(nunPin1, HIGH);
    digitalWrite(nunPin2,LOW);
    state = LOW;
  }
}

void
loop ()
{
 
  Wire.requestFrom (0x52, 6); // request data from nunchuck
  while (Wire.available ())
    {
      outbuf1[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
      cnt++;
    }

  // If we recieved nunchuck1's 6 bytes, then go get nunchuck2's data
  if (cnt >= 5)
    {
      cnt = 0;
      change_nunchuck ();
      send_zero ();
      delay (10);        // This is necessary to ensure communication goes well
     
    Wire.requestFrom (0x52, 6); // request data from nunchuck
    while (Wire.available ())
      {
        outbuf2[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
        cnt++;
      }
    }

// if we received nunchuck2's 6 bytes, then output z_button status through LEDs
if (cnt >= 5)
{
  print ();
  change_nunchuck();
}
  cnt = 0;
  send_zero (); // send the request for next bytes
  delay (10);   //required
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void
print ()
{
//Nunchuck1's Data
  int joy_x_axis1 = outbuf1[0];
  int joy_y_axis1 = outbuf1[1];
  int accel_x_axis1 = outbuf1[2] * 2 * 2;
  int accel_y_axis1 = outbuf1[3] * 2 * 2;
  int accel_z_axis1 = outbuf1[4] * 2 * 2;

  int z_button1 = 0;
  int c_button1 = 0;

//Nunchuck2's Data 
  int joy_x_axis2 = outbuf2[0];
  int joy_y_axis2 = outbuf2[1];
  int accel_x_axis2 = outbuf2[2] * 2 * 2;
  int accel_y_axis2 = outbuf2[3] * 2 * 2;
  int accel_z_axis2 = outbuf2[4] * 2 * 2;

  int z_button2 = 0;
  int c_button2 = 0;

 // byte outbuf1[5] and outbuf2[5] contains bits for z and c buttons
 // it also contains the least significant bits for the accelerometer data
 // so we have to check each bit of byte outbufn[5]
  if ((outbuf1[5] >> 0) & 1)
    {
      z_button1 = 1;
    }
  if ((outbuf1[5] >> 1) & 1)
    {
      c_button1 = 1;
    }
   
if ((outbuf2[5] >> 0) & 1)
    {
      z_button2 = 1;
    }
    if ((outbuf2[5] >> 1) & 1)
    {
      z_button2 = 1;
    }

//Lights up corrosponding LEDs
  if (z_button1 == 1)
  { 
    digitalWrite (led1, HIGH);   
  }
  else
  {                               
    digitalWrite (led1, LOW);   
  }
 
  if (z_button2 == 1)
  { 
    digitalWrite (led2, HIGH);   
  }
  else
  {       
    digitalWrite (led2, LOW);   
  } 
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char
nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}
Logged
*
Karma: +0/-0
Posts: 2
Offline Offline
View Profile
« Reply #5 on: June 05, 2010, 09:49:18 PM »

- SUCCESS -

Here's how to do it. All you need is 2 transistors (basic npn switch transistors), and 2 resistors and the use of 2 more arduino pins.

For the 2 nunchucks, I tied the 2 ground (white) wires, tied the 2 clock (yellow) wires, and tied the 2 power (red) wires. You have to make 2 switches (thus 2 transistors) each of which will disconnect the nunchuck's data (green) wire from the arduino.

Programming Note:
when you start up the 'system' , you'll need to have both nunchuck's data (green) wire connected to the arduino in order to initiate both at the same time. Then you can swap between each nunchuck.

Edited*
 Note: There is an error in the above statement. You must initiate each nunchuck individually in order for the arudino to store the correct values per nunchuck.

Link on transistor switches:
http://www.kpsec.freeuk.com/trancirc.htm


At first I tried using 1 npn and 1 pnp transistor, but I couldn't get the nunchuck to push its data through a pnp transitor...I'm not so sure why yet...but this would require the use of only 1 extra arduino pin, instead of 2...

Correct me if I'm wrong but couldn't you use 3 transistors and 1 pin? Two npn and 1 pnp Tie one npn and the pnp transistor to the control pin. the npn would control one data line directly while the pnp would control the second npn which had the data line through it?
Logged
Pages: [1]
Print
Jump to:  

Clicky Web Analytics