Uno as I2C slave

I am interested in using an Uno as an I2C slave. I want to be able to read inputs, and set output through I2C. I have had some success before, but have always had problems with arrays of char. If a char element is 0, then none of the rest of the array elements seem to exist (they all seem to be 0). I have messed around a little trying to get things to work, but so far no go. One work-around I came up with is to (for example) split a 10-bit ADC reading in half, and using two bytes of 5 bits for the data. The other 3 bits of the bytes I set to 1's, just so that the element wouldn't ever equal 0.

I think the reason of this behavior is related to the Arduino seeing an element of a string with the value of 0 as being NULL (the end of the string).

In this case though, I am not using characters, and I want full freedom. I don't really care about signed vs. unsigned, as I can deal with that in code.

I only need help with the slave part (probably just array information). I am using an NXT as the master, and have I2C working just fine.

Can you post your code?

Basically you should be able to send up to 32 bytes by specifying a length, eg.

Wire.send (buf, 10);  // send 10 bytes

Well, you sort of indirectly answered my question, so thanks!

I want to take it further than what it is. Here is the (now working) program that I am using now:

#include <Wire.h>

int val_0;
int val_1;
int val_2;
int val_3;
byte buf[8];

void setup()
{
  Wire.begin(2);                // address #2 (NXT address 0x04)
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  val_0 = analogRead(0);
  val_1 = analogRead(1);
  val_2 = analogRead(2);
  val_3 = analogRead(3);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  buf[0] = val_0;
  buf[1] = val_0 >> 8;
  buf[2] = val_1;
  buf[3] = val_1 >> 8;
  buf[4] = val_2;
  buf[5] = val_2 >> 8;
  buf[6] = val_3;
  buf[7] = val_3 >> 8;
 
  Wire.send(buf, 8);
}

Now I want to have a register structure for I2C. I want to be able to read any one (or more in sequence) of the bytes from the registers I want to (according to the NXT which is the master). Using the above as an example, I want to be able to read just "registers" 6 and 7 (ADC 3). If registers aren't really usable, what about being able to sense which register I am requesting, and the length, and then building the buffer accordingly? On the NXT side (with the above Arduino program), it doesn't matter what register I request, the Arduino just starts sending from the beginning.

have you seen this tutorial - http://www.arduino.cc/en/Tutorial/MasterReader - ?

No I hadn't, but that is too basic for what I want. I can already do all that (except switch the SDA and SCL pins from 4 and 5 to 5 and 4 XD).

It sounds like you're trying to do what most I2C devices do, that is have the master set a starting address and read back X amount of bytes starting from that address. If that's what you're trying to accomplish you need to add the receiveEvent also like this:

#include <Wire.h>

int val_0;
int val_1;
int val_2;
int val_3;
byte addressPointer = 0;  //address pointer variable
byte buf[8];

void setup()
{
  Wire.begin(2);                // address #2 (NXT address 0x04)
  Wire.onRequest(requestEvent); // register event
  Wire.onReceive(receiveEvent); // this is so the Master can set the starting address
}

void loop()
{
  val_0 = analogRead(0);
  val_1 = analogRead(1);
  val_2 = analogRead(2);
  val_3 = analogRead(3);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  buf[0] = val_0;
  buf[1] = val_0 >> 8;
  buf[2] = val_1;
  buf[3] = val_1 >> 8;
  buf[4] = val_2;
  buf[5] = val_2 >> 8;
  buf[6] = val_3;
  buf[7] = val_3 >> 8;
 
  Wire.send(buf + addressPointer, 8 - addressPointer);
}

void receiveEvent(int howMany)
{
  addressPointer = Wire.receive();
}

Assuming you wanted to read just registers 6 and 7 (using an Arduino as a Master example) you would use this:

Wire.beginTransmission(2); //slave address
Wire.send(6);  //set the address pointer 
Wire.endTransmission();
Wire.requestFrom(2,2);  //request 2 bytes from the slave from address 6
x = Wire.receive();
y = Wire.receive();

Thank you very much for the help. I will test it when I get a chance.