I'm using the Wire library with an Arduino Nano Every, as I2C master.
I realized that the byte sent count returned by the .write() method is incorrect. Example:
Wire.beginTransmission(address);
n = Wire.write(buffer, buffer_size);
Wire.endTransmission();
the n variable, as documentation states, gets the number of bytes sent. But if the I2C lines are disconnected and there's no slave to respond, so no bytes are sent, the .write() method returns the same buffer size value meaning that all the payload has been sent.
On the oscilloscope I see that the address byte is sent, there's no ack on the 9th bit, and the bus goes back to the idle state; this means that the Wire library handles properly the missing ack skipping on sending the payload but fails to report back the problem. I'm expecting the .write() method to return 0, meaning no payload bytes transmitted.
Why? What I'm missing? How can I properly handle a communication problem?
That is incorrect. Wire.write() returns the number of bytes placed in the library's internal buffer. Use the return value from Wire.endTransmission() to determine if theI2C bus transfer was successful.
@gfvalvo is right, just ignore the return value by Wire.write().
// --------------------------------------------
// Write data over the I2C bus
// --------------------------------------------
Wire.beginTransmission(address);
Wire.write(buffer, buffer_size);
int error = Wire.endTransmission();
if (error == 0)
{
// good
}
// --------------------------------------------
// Read data via the I2C bus
// --------------------------------------------
int n = Wire.requestFrom(address, buffer_size);
if (n == buffer_size)
{
// good
}