I2C WryteBite always nack - Solved

Hi,

I’m trying to connect a “chinese” nunchuck to the Wixel with the I2C library.
I know for sure that this works on the Arduino, but with the Wixel I keep getting nack on all the writings
Am I missing something?

/** example_usb_com app:
== Default pinout ==
P1_0 = I2C SCL	Branco
P1_1 = I2C SDA	Verde
*/

#include <wixel.h>
//#include <stdio.h>
#include <i2c.h>

/** Parameters ****************************************************************/

int32 CODE param_I2C_SCL_pin = 10;
int32 CODE param_I2C_SDA_pin = 11;
//int32 CODE param_I2C_freq_kHz = 100;
int32 CODE param_I2C_timeout_ms = 10;


/* VARIABLES ******************************************************************/


/** True if NACK. */
//int32 CODE yellowLedOn = 0;
BIT yellowLedOn = 0;

/** True if Timeout. */
BIT redLedOn = 0;

uint8 xxx[6];
/* FUNCTIONS ******************************************************************/

void updateLeds()
{
    LED_YELLOW(yellowLedOn);
    LED_RED(redLedOn);
}

void i2cWByte( uint8 x)
{
	BIT nack = 0;
   	nack = i2cWriteByte( x );
   	if ( i2cTimeoutOccurred )
   		{	redLedOn = 1;	}
   	else if ( nack )
   		{	yellowLedOn = 1;	}
   	else
   		{	redLedOn = 0;
   			yellowLedOn = 0;	}
}

void main()
{
	BIT nack = 0;

    i2cPinScl = param_I2C_SCL_pin;
    i2cPinSda = param_I2C_SDA_pin;
    i2cSetTimeout(param_I2C_timeout_ms);

    i2cStart();
   	i2cWByte(0x52);
   	i2cWByte(0xF0);
   	i2cWByte(0x55);
   	i2cStop();

   	delayMs(1);

   	i2cStart();
   	i2cWByte(0x52);
   	i2cWByte(0xFB);
   	i2cWByte(0x00);
   	i2cStop();

   	while(1)
    {
        updateLeds();

        i2cStart();
        i2cWByte( 0x52 );
        i2cWByte(0x00);
       	i2cStop();

       	delayMs(1);

       	i2cStart();
       	i2cWByte(0x53);
    	xxx[0] = i2cReadByte( 0 );
    	xxx[1] = i2cReadByte( 0 );
    	xxx[2] = i2cReadByte( 0 );
    	xxx[3] = i2cReadByte( 0 );
    	xxx[4] = i2cReadByte( 0 );
    	xxx[5] = i2cReadByte( 0 );
       	i2cStop();
    }
}

Hello,

I assume you’re talking about a Wii nunchuk (or a clone of it); do you have a datasheet for it? It might also be helpful if you could post your working Arduino code for comparison.

- Kevin

you right Kevin it’s a cheap wii nunchuck, and no, I don’t have a datasheet.

here you go, just the relevant Arduino code

        void begin() 
        {
            Wire.begin();
            cnt = 0;
            averageCounter = 0;
            // instead of the common 0x40 -> 0x00 initialization, we
            // use 0xF0 -> 0x55 followed by 0xFB -> 0x00.
            // this lets us use 3rd party nunchucks (like cheap $4 ebay ones)
            // while still letting us use official oness.
            // only side effect is that we no longer need to decode bytes in _nunchuk_decode_byte
            // see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255
            //  
            Wire.beginTransmission(0x52);	// device address
            Wire.send(0xF0);
            Wire.send(0x55);
            Wire.endTransmission();
            delay(1);
            Wire.beginTransmission(0x52);
            Wire.send(0xFB);
            Wire.send(0x00);
            Wire.endTransmission();
            update();            
        }

        void update() {

            Wire.requestFrom (0x52, 6);	// request data from nunchuck
            while (Wire.available ()) {
                // receive byte as an integer
                status[cnt] = _nunchuk_decode_byte (Wire.receive()); //
                cnt++;
            }
            if (cnt > 5) {
                cnt = 0;
                _send_zero(); // send the request for next bytes
            }

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

I2C uses 7-bit slave addresses; in the case of your nunchuk, it looks like this is 1010010b (0x52). When an I2C master begins communicating with a slave, it transmits this 7-bit address followed by an 8th bit that is either 0 for writing or 1 for reading, so the master would transmit 10100100b (0xA4) to write to your nunchuk or 10100101b (0xA5) to read from it.

Arduino’s Wire.beginTransmission() function takes just the 7-bit address and automatically adds the last 0, and similarly Wire.requestFrom() takes the address and automatically adds the last 1. However, the Wixel’s I2C library only has a single function that simply writes a byte (8 bits) to the I2C interface, so when you send 0x52, you are actually sending the 8-bit sequence 01010010b. You have to add the last bit to the address yourself, so try using “i2cWByte(0xA4)” instead of “i2cWByte(0x52)” and see if that works.

- Kevin

and that was it…
changing the write address to 0xA4 and read address to 0xA5, solved the problem.

Also changin the ack on the last i2cReadByte to 1.

Thanks