The slave doesn’t really “figure out” the length while receiving. With the Wire library the full message is already buffered and the handler is called after the STOP condition, so the length is known at that point (the howMany parameter).
And as far as I know any additional protocol (like a length byte) is more about structuring the data than about the I²C mechanism itself.
Hi @chrisgadg
The master must tell the slave how many bytes it should receive or the number of bytes needs to be fixed, otherwise the slave has no idea.
But the onRequest() which is in the slave code appears to have no idea yet it does.
My solution is to send a transmission from the master to say how many bytes will be requesting in the proceeding request, then request, and at this the slave code has the number of requested bytes so I can act on it.
Any number of data bytes can be transferred from the
master to slave between the START and STOP conditions.
As already posted here the number of bytes transferred is defined by the controller application. This application which starts and stops a specific transmission has to make sure that the correct number is sent or received.
As a slave application you read or send after START until the bus goes into a STOP mode (or a repeated START, see 2.1.1 and 2.1.2 in the linked paper).
If you write a sketch for both sides you can create your own protocol on top of I2C, e.g. by defining that the first data byte will contain the number of following bytes or a command byte that tells the other side how many and what kind of data are following. (That's what @jim-p also wrote!)
Edit: This is probably the most comprehensive explanation for I2C use
There is nothing to tell the slave how many bytes to send. The requestFrom() from the master will always receive the requested number of bytes, regardless of how many the slave sends, if the slave sends less then the master sees a high level bus and assumes that represents data. The slave generally will either send a fixed amount of data, or however much is required based on a command previously sent from the master.
The onRequest interrupt just tells the slave device that the master is ready for reception. Nothing more.
The master device will read as many bytes as it expects.
Usually the number is implicitly known by both sides. If not it can be made depending on a previous transmission of the master which sends a command that explicitly or implicitly defines how many data shall be transferred. Or - the other way around - the slave sends a length byte as the first data. But that's application not I2C!
In the Save Sketch, the following function declaration is made in te setup() function:
Wire.onReceive(receiveEvent); //receiveEvent is name of callback function
void receiveEven(int howMany)
{
Serial.print(howMany, DEC); //shows 2 = bytes received from Master
}
Note: Whenever a data byte arrives at the slave from the master, the slave is interrupted. Therefore, the slave can count the number of interrupts that occur until the STOP condition appears on the I²C bus. The howMany argument is then loaded with the number of received bytes, excluding the slave address (i.e., number of interrupts minus one).
OnReceive() is a method that embeds the callback function: receiveEvent(int howMany(){} wich is called upon once STOP condition is asserted on the I2C bus by the Master. The variable howMany holds the number of bytes received by Slave from Master.
The I2C logic continuously monitors the bus states, and the corresponding actions prescribed by the I2C protocol are automatically carried out. The following diagram illustrates the START (SDA= 0, SCL = 1) and STOP (SDA = 1, SCL = 1) conditions of the I²C bus.
onRequest() is a method at the Slave side to declare/register a callback function: requestEvent(){} which is called upon when STOP condition is asserted on the I2C bus by the master after the execution of the following command:
Wire.requestFrom(slaveAddress, 3);
The Slave enters into the callback function and writes exactly 3 bytes (arg2 of requestFrom() method) into the I2C Buffer for onward transmission to Master. How does the Slave know this number is not known to me.