Arduino code not working on baby o

I am trying to run code from arduino on baby o

basically it connects a wireless wiinunchuck with arduino I am not sure why it’s not working on baby o 328

here is the code (I am using the arduino ide to upload to the baby o)

// read out a Wii Nunchuck controller
// adapted to work with wireless Nunchuck controllers of third party vendors by Michael Dreher <michael@5dot1.de>

// adapt to your hardware config
#define POWER_VIA_PORT_C2_C3 1    // use port pins port C2 and C3 as power supply of the Nunchuck (direct plug using wiichuck adapter)
#define DEBUG_RCV_TEL 1

#define USE_NEW_WAY_INIT 1        // use "The New Way" of initialization <http://wiibrew.org/wiki/Wiimote#The_New_Way>
#define WII_IDENT_LEN ((byte)6)
#define WII_TELEGRAM_LEN ((byte)6)
#define WII_NUNCHUCK_TWI_ADR ((byte)0x52)

#include <Wire.h>
#include <string.h>
#include <utility\twi.h>
#undef int
#include <stdio.h>

uint8_t outbuf[WII_TELEGRAM_LEN];		// array to store arduino output
int cnt = 0;
int ledPin = 13;

void setup ()
{
  Serial.begin (115200);

#ifdef POWER_VIA_PORT_C2_C3    // power supply of the Nunchuck via port C2 and C3
  PORTC &=~ _BV(PORTC2);
  PORTC |=  _BV(PORTC3);
  DDRC |= _BV(PORTC2) | _BV(PORTC3);  // make outputs
  delay(100);  // wait for things to stabilize
#endif

  Wire.begin(); // initialize i2c
  // we need to switch the TWI speed, because the nunchuck uses Fast-TWI
  // normally set in hardware\libraries\Wire\utility\twi.c twi_init()
  // this is the way of doing it without modifying the original files
#define TWI_FREQ_NUNCHUCK 400000L
  TWBR = ((CPU_FREQ / TWI_FREQ_NUNCHUCK) - 16) / 2;

  nunchuck_init(0); // send the initialization handshake

  // display the identification bytes, must be "00 00 A4 20 00 00" for the Nunchuck
  byte i;
  if(readControllerIdent(outbuf) == 0)
  {
    Serial.print("Ident=");
    for (i = 0; i < WII_TELEGRAM_LEN; i++)
    {
      Serial.print(outbuf[i], HEX);
      Serial.print(' ');
    }
    Serial.println();
  }

  Serial.println("Finished setup");
}

// params:
//   timeout: abort when timeout (in ms) expires, 0 for unlimited timeout
//   return:  0 == ok, 1 == timeout
byte nunchuck_init (unsigned short timeout)
{
  byte rc = 1;

#ifndef USE_NEW_WAY_INIT
  // look at <http://wiibrew.org/wiki/Wiimote#The_Old_Way> at "The Old Way"
  Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR);	// transmit to device 0x52
  Wire.send (0x40);		// sends memory address
  Wire.send (0x00);		// sends sent a zero.  
  Wire.endTransmission ();	// stop transmitting
#else
  // disable encryption
  // look at <http://wiibrew.org/wiki/Wiimote#The_New_Way> at "The New Way"

  unsigned long time = millis();
  do
  {
    Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR);	// transmit to device 0x52
    Wire.send (0xF0);		// sends memory address
    Wire.send (0x55);		// sends data.  
    if(Wire.endTransmission() == 0) // stop transmitting
    {
      Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR);	// transmit to device 0x52
      Wire.send (0xFB);		// sends memory address
      Wire.send (0x00);		// sends sent a zero.  
      if(Wire.endTransmission () == 0)	// stop transmitting
      {
        rc = 0;
      }
    }
  }
  while (rc != 0 && (!timeout || ((millis() - time) < timeout)));
#endif

  return rc;
}


// params:
//   ident [out]: pointer to buffer where 6 bytes of identification is stored. Buffer must be at least 6 bytes long.
//                A list of possible identifications can be found here: <http://wiibrew.org/wiki/Wiimote#The_New_Way>
//   return:  0 == ok, 1 == error
byte readControllerIdent(byte* pIdent)
{
  byte rc = 1;

  // read identification
  Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR);	// transmit to device 0x52
  Wire.send (0xFA);		// sends memory address of ident in controller
  if(Wire.endTransmission () == 0)	// stop transmitting
  {
    byte i;
    Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN);	// request data from nunchuck
    for (i = 0; (i < WII_TELEGRAM_LEN) && Wire.available (); i++)
    {
      pIdent[i] = Wire.receive();	// receive byte as an integer
    }
    if(i == WII_TELEGRAM_LEN)
    {
      rc = 0;
    }
  }
  return rc;
}

void clearTwiInputBuffer(void)
{
  // clear the receive buffer from any partial data
  while( Wire.available ())
    Wire.receive ();
}


void send_zero ()
{
  // I don't know why, but it only works correct when doing this exactly 3 times
  // otherwise only each 3rd call reads data from the controller (cnt will be 0 the other times)
  for(byte i = 0; i < 3; i++)
  {
    Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR);	// transmit to device 0x52
    Wire.send (0x00);		// sends one byte
    Wire.endTransmission ();	// stop transmitting
    //delay(1);
  }
}

void loop ()
{
  delay (1000);
  send_zero (); // send the request for next bytes
  Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN);	// request data from nunchuck

  for (cnt = 0; (cnt < WII_TELEGRAM_LEN) && Wire.available (); cnt++)
  {
    outbuf[cnt] = nunchuk_decode_byte (Wire.receive ());	// receive byte as an integer
    digitalWrite (ledPin, HIGH);	// sets the LED on
  }

  // debugging
#ifdef DEBUG_RCV_TEL
  Serial.print("avail=");
  Serial.print(Wire.available(), DEC);
  Serial.print("  cnt=");
  Serial.println(cnt, DEC);
#endif

  clearTwiInputBuffer();

  // If we recieved the 6 bytes, then go print them
  if (cnt >= WII_TELEGRAM_LEN)
  {
    print ();
  }

}

// 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 ()
{
  int joy_x_axis = outbuf[0];
  int joy_y_axis = outbuf[1];
  int accel_x_axis = outbuf[2] * 2 * 2;
  int accel_y_axis = outbuf[3] * 2 * 2;
  int accel_z_axis = outbuf[4] * 2 * 2;

  int z_button = 0;
  int c_button = 0;

  // byte outbuf[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 outbuf[5]
  if ((outbuf[5] >> 0) & 1)
  {
    z_button = 1;
  }
  if ((outbuf[5] >> 1) & 1)
  {
    c_button = 1;
  }

  if ((outbuf[5] >> 2) & 1)
  {
    accel_x_axis += 2;
  }
  if ((outbuf[5] >> 3) & 1)
  {
    accel_x_axis += 1;
  }

  if ((outbuf[5] >> 4) & 1)
  {
    accel_y_axis += 2;
  }
  if ((outbuf[5] >> 5) & 1)
  {
    accel_y_axis += 1;
  }

  if ((outbuf[5] >> 6) & 1)
  {
    accel_z_axis += 2;
  }
  if ((outbuf[5] >> 7) & 1)
  {
    accel_z_axis += 1;
  }

  Serial.print (joy_x_axis, DEC);
  Serial.print ("\t");

  Serial.print (joy_y_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_x_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_y_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_z_axis, DEC);
  Serial.print ("\t");

  Serial.print (z_button, DEC);
  Serial.print ("\t");

  Serial.print (c_button, DEC);
  Serial.print ("\t");

  Serial.print ("\r\n");
}

// Decode data format that original Nunchuck uses with old init sequence. This never worked with
// other controllers (e.g. wireless Nunchuck from other vendors)
char nunchuk_decode_byte (char x)
{
#ifndef USE_NEW_WAY_INIT
  x = (x ^ 0x17) + 0x17;
#endif
  return x;
} 

I can upload the code but it doesn’t seem to be reading the nunchuck

any help is appreciated
thanks

If you are using a pre-1.0 Arduino IDE, then this code should work. I have it listed as working, but that was with a third party nunchuk, not a Nintendo one.

#define POWER_VIA_PORT_C2_C3 1 // use port pins port C2 and C3 as power supply of the Nunchuck (direct plug using wiichuck adapter)
//#define DEBUG_RCV_TEL 1

#define USE_NEW_WAY_INIT 1 // use "The New Way" of initialization <http://wiibrew.org/wiki/Wiimote#The_New_Way>
#define WII_IDENT_LEN ((byte)6)
#define WII_TELEGRAM_LEN ((byte)6)
#define WII_NUNCHUCK_TWI_ADR ((byte)0x52)

#include <Wire.h>
#include <string.h>
#include <utility\twi.h>
#undef int
#include <stdio.h>

uint8_t outbuf[WII_TELEGRAM_LEN]; // array to store arduino output
int cnt = 0;
int ledPin = 13;

void setup ()
{
  Serial.begin (19200);
  
  #ifdef POWER_VIA_PORT_C2_C3 // power supply of the Nunchuck via port C2 and C3
  PORTC &=~ _BV(PORTC2);
  PORTC |= _BV(PORTC3);
  DDRC |= _BV(PORTC2) | _BV(PORTC3); // make outputs
  delay(100); // wait for things to stabilize
  #endif
  
  Wire.begin(); // initialize i2c
  // we need to switch the TWI speed, because the nunchuck uses Fast-TWI
  // normally set in hardware\libraries\Wire\utility\twi.c twi_init()
  // this is the way of doing it without modifying the original files
  #define TWI_FREQ_NUNCHUCK 400000L
  TWBR = ((CPU_FREQ / TWI_FREQ_NUNCHUCK) - 16) / 2;
  
  nunchuck_init(0); // send the initialization handshake
  
  // display the identification bytes, must be "00 00 A4 20 00 00" for the Nunchuck
  byte i;
  if(readControllerIdent(outbuf) == 0)
  {
    Serial.print("Ident=");
    for (i = 0; i < WII_TELEGRAM_LEN; i++)
    {
      Serial.print(outbuf[i], HEX);
      Serial.print(' ');
    }
    Serial.println();
  }
  
  Serial.println("Finished setup");
}

// params:
// timeout: abort when timeout (in ms) expires, 0 for unlimited timeout
// return: 0 == ok, 1 == timeout
byte nunchuck_init (unsigned short timeout)
{
  byte rc = 1;
  
  #ifndef USE_NEW_WAY_INIT
  // look at <http://wiibrew.org/wiki/Wiimote#The_Old_Way> at "The Old Way"
  Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
  Wire.send (0x40); // sends memory address
  Wire.send (0x00); // sends sent a zero.
  Wire.endTransmission (); // stop transmitting
  #else
  // disable encryption
  // look at <http://wiibrew.org/wiki/Wiimote#The_New_Way> at "The New Way"
  
  unsigned long time = millis();
  do
  {
    Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
    Wire.send (0xF0); // sends memory address
    Wire.send (0x55); // sends data.
    if(Wire.endTransmission() == 0) // stop transmitting
    {
      Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
      Wire.send (0xFB); // sends memory address
      Wire.send (0x00); // sends sent a zero.
      if(Wire.endTransmission () == 0) // stop transmitting
      {
        rc = 0;
      }
    }
  }
  while (rc != 0 && (!timeout || ((millis() - time) < timeout)));
  #endif
  
  return rc;
}


// params:
// ident [out]: pointer to buffer where 6 bytes of identification is stored. Buffer must be at least 6 bytes long.
// A list of possible identifications can be found here: <http://wiibrew.org/wiki/Wiimote#The_New_Way>
// return: 0 == ok, 1 == error
byte readControllerIdent(byte* pIdent)
{
  byte rc = 1;
  
  // read identification
  Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
  Wire.send (0xFA); // sends memory address of ident in controller
  if(Wire.endTransmission () == 0) // stop transmitting
  {
    byte i;
    Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN); // request data from nunchuck
    for (i = 0; (i < WII_TELEGRAM_LEN) && Wire.available (); i++)
    {
      pIdent[i] = Wire.receive(); // receive byte as an integer
    }
      if(i == WII_TELEGRAM_LEN)
    {
      rc = 0;
    }
  }
  return rc;
}

void clearTwiInputBuffer(void)
{
  // clear the receive buffer from any partial data
  while( Wire.available ())
  Wire.receive ();
}


void send_zero ()
{
  // I don't know why, but it only works correct when doing this exactly 3 times
  // otherwise only each 3rd call reads data from the controller (cnt will be 0 the other times)
  for(byte i = 0; i < 3; i++)
  {
    Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
    Wire.send (0x00); // sends one byte
    Wire.endTransmission (); // stop transmitting
  }
}

void loop ()
{
  Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN); // request data from nunchuck
  
  for (cnt = 0; (cnt < WII_TELEGRAM_LEN) && Wire.available (); cnt++)
  {
    outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
    digitalWrite (ledPin, HIGH); // sets the LED on
  }
  
  // debugging
  #ifdef DEBUG_RCV_TEL
  Serial.print("avail=");
  Serial.print(Wire.available());
  Serial.print(" cnt=");
  Serial.println(cnt);
  #endif
  
  clearTwiInputBuffer();
  
  // If we recieved the 6 bytes, then go print them
  if (cnt >= WII_TELEGRAM_LEN)
  {
    print ();
  }
  
  send_zero (); // send the request for next bytes
  delay (20);
}

// 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 ()
{
  int joy_x_axis = outbuf[0];
  int joy_y_axis = outbuf[1];
  int accel_x_axis = outbuf[2] * 2 * 2;
  int accel_y_axis = outbuf[3] * 2 * 2;
  int accel_z_axis = outbuf[4] * 2 * 2;
  
  int z_button = 0;
  int c_button = 0;
  
  // byte outbuf[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 outbuf[5]
  if ((outbuf[5] >> 0) & 1)
  {
    z_button = 1;
  }
  if ((outbuf[5] >> 1) & 1)
  {
    c_button = 1;
  }
  
  if ((outbuf[5] >> 2) & 1)
  {
    accel_x_axis += 2;
  }
  if ((outbuf[5] >> 3) & 1)
  {
    accel_x_axis += 1;
  }
  
  if ((outbuf[5] >> 4) & 1)
  {
    accel_y_axis += 2;
  }
  if ((outbuf[5] >> 5) & 1)
  {
    accel_y_axis += 1;
  }
  
  if ((outbuf[5] >> 6) & 1)
  {
    accel_z_axis += 2;
  }
  if ((outbuf[5] >> 7) & 1)
  {
    accel_z_axis += 1;
  }
  
  Serial.print (joy_x_axis, DEC);
  Serial.print ("\t");
  
  Serial.print (joy_y_axis, DEC);
  Serial.print ("\t");
  
  Serial.print (accel_x_axis, DEC);
  Serial.print ("\t");
  
  Serial.print (accel_y_axis, DEC);
  Serial.print ("\t");
  
  Serial.print (accel_z_axis, DEC);
  Serial.print ("\t");
  
  Serial.print (z_button, DEC);
  Serial.print ("\t");
  
  Serial.print (c_button, DEC);
  Serial.print ("\t");
  
  Serial.print ("\r\n");
}

// Decode data format that original Nunchuck uses with old init sequence. This never worked with
// other controllers (e.g. wireless Nunchuck from other vendors)
char nunchuk_decode_byte (char x)
{
  #ifndef USE_NEW_WAY_INIT
  x = (x ^ 0x17) + 0x17;
  #endif
  return x;
}

I haven’t taken the time to make it work with 1.0 though.

I am using pre 1.0 its 22 I think the code will compile and load but for some reason doesn’t work on the baby O. I was thinking it may be a problem with the timer or something like that not sure. I am a noob so my abilities are limited.

it is a third party nunchuck also.

Hello,

The Arduino TWI code assumes the AVR is running at 16 MHz (as standard Arduinos do), but the Baby Orangutan runs at 20 MHz. I think this causes the TWI frequency to be higher than the library thinks it is. You should be able to fix this by adding this line near the top of your program:

#define CPU_FREQ 20000000L

If that does not work, could you describe exactly how your program is not working (How is it behaving differently than you expect it to?) and how you have everything connected? Does this program work for you on a standard Arduino, such as the Uno?

- Kevin