How to make sure I2C master has received data? (Arduino slave)

Hi,

Sorry this might sound like a stupid question, I spent a whole day searching about it but didn't find a clear answer.

When using Arduino as I2C slave, is there a way to make sure the data sent to the master in a request event has been successfully received?

When Arduino is the master, this can be verified from the output of Wire.endTransmission(). But in slave mode, Wire.write() is used and it always returns the number of bytes that it tries to send, regardless of the result.

Thanks

How do you know that a post you submitted was successfully received by the forum?

Can you not use that same technique?

PaulS:
How do you know that a post you submitted was successfully received by the forum?

Can you not use that same technique?

I don't know much about the program on the MCU that I'm communicating with (which is the I2C master), so if what you meant was that I should check this from the responses, I cannot be sure that it is programmed to respond after successfully receiving data. And most probably, it is not programmed to respond at all, since what I am trying to do is to emulate a sensor (InvenSense MPU-6050) with Arduino, and all the master needs to do is to keep asking the sensor for data!

And if what you meant was something else...well, sorry I didn't get it!

Thanks

If you have no control over the master, you can NOT be sure that the master got the reply. On the other hand, why do you need to worry about it? The master should be handling the failure to get a response.

PaulS:
If you have no control over the master, you can NOT be sure that the master got the reply.

But theoretically there must be a way to make sure the message has been received, based on the ACK/NACK bit from the master.

PaulS:
On the other hand, why do you need to worry about it? The master should be handling the failure to get a response.

I'm trying to fake the output of a tilt sensor to make the master send speed commands to a motor, and I'm getting weird responses. I'm not sure if it's because the master is not receiving the messages properly or I'm not sending the right messages.

But theoretically there must be a way to make sure the message has been received, based on the ACK/NACK bit from the master

Feel free to hack the library, then.

or I'm not sending the right messages.

That would be my guess.

Knowing that the master got crap won't help.

PaulS:
That would be my guess.

Okay then, I'll continue based on this hypothesis. Thank you very much :slight_smile:

Why not post your code. Then, we can see whether what you are sending seems reasonable?

Why not set up another Arduino as master, to see what the other master actually receives?

That's often my first line of attack on simulating or emulating something. Write my own master and use that to check my simulated thing. It really helps you understand the protocol if you try to re-implement both sides of the conversation.

skepticmind:
But theoretically there must be a way to make sure the message has been received, based on the ACK/NACK bit from the master.

I'm trying to fake the output of a tilt sensor to make the master send speed commands to a motor, and I'm getting weird responses. I'm not sure if it's because the master is not receiving the messages properly or I'm not sending the right messages.

With the I2C protocol, when the Master is reading data from the Slave, it emits clock pulses, The Slave emits data bits. The slave can stall the Master by 'stretching' the clock pulse. after 8 clock pulses the Slave monitors the data line for an ACK from the Master. If it sees an NAK it stops sending bits, A STOP, or START will also abort the Read operation.

The Standard Arduino WIRE library DOES NOT report the number of bytes the Master accepted. The OnRequest event can queue up to 32 bytes for transmission. BUT, there is no validation of actual transmission.

I modified the library to solve this problem. But, there are of course drawbacks:

  • Only one byte at a time is returned by the OnRequest call. So, the Wire library has to call OnRequest multiple times, every time the Master sends an ACK (more overhead)
  • The OnRequest Event must track the 'sent' bytes
  • The foreground Slave process must interrogate the WIRE library status, number of expected/actual bytes transmitted.
  • The hardest part, is figuring out when a failure has occurred, and how to respond.

chuck.

chucktodd:
With the I2C protocol, when the Master is reading data from the Slave, it emits clock pulses, The Slave emits data bits. The slave can stall the Master by 'stretching' the clock pulse. after 8 clock pulses the Slave monitors the data line for an ACK from the Master. If it sees an NAK it stops sending bits, A STOP, or START will also abort the Read operation.

The Standard Arduino WIRE library DOES NOT report the number of bytes the Master accepted. The OnRequest event can queue up to 32 bytes for transmission. BUT, there is no validation of actual transmission.

I modified the library to solve this problem. But, there are of course drawbacks:

  • Only one byte at a time is returned by the OnRequest call. So, the Wire library has to call OnRequest multiple times, every time the Master sends an ACK (more overhead)
  • The OnRequest Event must track the 'sent' bytes
  • The foreground Slave process must interrogate the WIRE library status, number of expected/actual bytes transmitted.
  • The hardest part, is figuring out when a failure has occurred, and how to respond.

chuck.

Is your modified version of the Wire library available?

skepticmind:
Is your modified version of the Wire library available?

It is not current with the Arduino Environment. I think that last I pushed was 1.6.5.

on github

Chuck.