Here's how to get an mbed and AVR talking with I2C, with the mbed acting as Master and the AVR acting as Slave.
Let's say you want the mbed to query the Arduino to respond with 4 bytes of data.
The mbed will write an address byte with the read bit set, using the Arduino's address, and then it'll request to read four bytes. The protocol exchange looks like this:
1. Send a start sequence
2. Send 0xC1 ( I2C address of the slave with the R/W bit high (odd address)
3. Read data bytes from slave
4. Send the stop sequence.
(source: I2C Tutorial)
On the Arduino, call Wire.begin(7), where 7 is the Arduino's I2C address. That tells the Arduino I2C peripheral what messages to listen for. Then call Wire.onRequest() specifying a handler function that is called when the master requests data.
void handleI2CReceive(int numBytes)
{
char command = Wire.receive(); // pretty much just ignore the command
return;
}
void handleI2CRequest()
{
byte data[4];
// the code below just sends
// data from the global variable
// box, a struct with 4 char members
//
data[0] = box.x1;
data[1] = box.y1;
data[2] = box.x2;
data[3] = box.y2;
Wire.send(data, 4);
return;
}
void setup() {
Wire.begin(I2C_ADDRESS);
box.x1 = box.x2 = box.y1 = box.y2 = 0;
Wire.onRequest(handleI2CRequest);
Wire.onReceive(handleI2CReceive);
}
On the mbed, use the "raw" I2C library's start(), write(), read(), stop() methods and manually set the address. Take the I2C slave address, left shift once, and set bit 0 high to indicate a read operation. Then read four bytes. Like this:
cam.start();
data[0] = (0x7<<1 | 0x01); // send address + !write = 1
cam.write(data[0]); // send address
data[0] = cam.read(1);
data[1] = cam.read(1);
data[2] = cam.read(1);
data[3] = cam.read(0); // don't ack the last byte
cam.stop();
This only works when the slave has one "register". Suppose you have an Arduino that can respond with one of several ADC readings. The protocol exchange would first include the master writing the desired register number to the slave, sending another start, then reading the data. The Arduino would have to accept the register number and store that until the next read request, responding with the correct register's value.