nmd89:
@Chuck:I'm sorry I didn't update the code after running a simpler test on it. Yes, I want to get 28 bytes from the slave. I should have put "Wire.requestFrom(8, 28). The master should request 28 bytes from the slave. On request, the slave gets information from the IMU and the four pressure sensors. The slave is having trouble getting information from the IMU because the clock from the master cuts out. I would need the slave to behave as a master after getting a request from the original master. Is there a way to do that?
Your description of the problem does not match with my experience.
I have used 2 UNO's + RTCC + EEPROM + MPC23008(LCD20x4) + MCP23008(4x4 Keypad) all on the same I2C bus.
Both Uno were I2C masters, and Slaves.
There was not much effort, just check the return codes on requestFrom() and endTransmission().
Make sure you do not leave a transaction with a Re-Start, i.e. ( endTransmission(false)); Because this is how the I2C bus can be held between Transactions. i.e. reading from an EEPROM, first you have to Write() the address, then Read() the data back.
Wire.beginTransmission(0x51);
Wire.Write((uint8_t) 0);
Wire.Write((uint8_t) 7);
uint8_t err = Wire.endTransmission(false); // hold the bus so that the other master cannot interfere
if (err==0){ // good set address for read
err=Wire.requestFrom(0x51,20); // when this cmd executes the bus will be release for the other master.
if(err==20){// good read of data
char buf[20];
uint8_t i=0;
while(Wire.available()) buf[i++]=Wire.read();
Serial.write(buf,i);
}
}
One priviso, the Wire.h library has a gotcha in the OnRequest() handling. You are only allowed ONE Wire.write() inside the OnRequest() Handler. Each time you issue a Wire.write() while inside the OnRequest() handler, the Wire.h library reinitialized the outgoing I2C buffer, so, only the Last Wire.write() is actually sent to the requesting Master (if the master requested 10 bytes and you were filling the request one byte at a time, only the last byte plus 9 0xFF would be received by the master).
There has been talk about fixing this 'feature' in a future release of the environment. To work around it, build up a buffer and use the Wire.write(buf[],len); function call instead of the single byte Wire.write(byte); call.
Chuck.
p.s. attached is a modified Wire.h library that includes addition error detection, and timeout support, it includes examples of multiple master code for UNO's that bounce data back and forth.
The major difference is that a Wire.write(7); will actually send 2 bytes, a 0 and a 7 because the compiler promotes constants to ints (2bytes) and I added an overloaded Wire.write(uint16) that actually sends both bytes.
Just use the library manager to install from this zip. After it is installed you will get a warning about duplicated Wire.h:
Multiple libraries were found for "Wire.h"
Used: C:\Users\user\Documents\Arduino\libraries\Wire
Not used: C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire
To remove my library just delete the whole subdirectory, on my system:
C:\Users\user\Documents\Arduino\libraries\Wire
Wire.zip (16 KB)