I'm writing a sketch using Arduino as slave emulating a sensors and answering to the master (it's MATEK flight controller) using the function onRequest...
My question is how can the slave know the number of bytes required by the master?
In a typical I2C communication scenario the master initiates communication and specifies the number of bytes it expects to receive from the slave (what you do in Arduino using the requestFrom() function)
There are certain cases where the master might not specify the number of bytes explicitly. For example in case of continuous reading or if the communication protocol between the master and slave involves fixed-length messages, the master and slave might "agree" on a predetermined message size
In practice, If you emulate a specific sensor, you should look what it expects and how it answers.
A slave with communication registers knows the size of each register. If so designed the slave can advance to the next register and transmit its content as well.
The end of transmission is implemented in the slave library. I guess that for a continued request the OnRequest callback is invoked repeatedly until the master terminates the transmission.
Since a slave can not stop any request it's up to the master to know the number of bytes sent by the slave.
In the case of the requestFrom() function, the master controls the number of bytes that it reads in. The master will read in the requested number of bytes, regardless of how many bytes the slave sends - if the slave stops sending somewhere in mid-process, the I2C line is pulled high by the pull-up resistor and the master reads that in as a high level, with no way to determine whether it is data from the slave or not.
The master should know how many bytes the slave will send. Often a command is sent to the slave first, then the data is requested, with the size of the data being known from the specific command that was sent.
You would really need to examine the data sheet for the slave device you are emulating to see how to properly interact with the master.
First of all I thank all of you for the quick and competent answers.
Yes, the emulates sensors should answer with a distance in cm based on 2 bytes (MSB and LSB), but I guess that the master in same cases asks for some status parameters, expecting a different number of bytes.
So I was thinking that consider that the master has the instruction Wire.requestFrom(add,#byte) I imaging that the slave can know how many bytes the master asked.
Ok for sure I find a working solution, I'm happy to write some more code and do more trials.
My understandings are: 1. The I2C communication is a protocol between Master and Slave, whcih means that there are pre-agreed rules/agreement as to how many data bytes would be exchanged using the following command--
byte m = Wire.requestFrom(slaveAddress, numberOfBytes);
2. If numberOfBytes = 3, then the Slave must write 3-byte data onto I2C Buffer after entering into the following routine:
3. The byte m = Wire.requestFrom(a, n); is a blocking code, which keeps generating SCL pulses until the n-number of data bytes are collected from the I2C Buffer of Slave and desposited into the I2C Buffer of Master. The m is always equal to n.
4. The Master executes the following codes (just after the requestFrom() method) to transfer the arrived 3-byte data from its unseen I2C Buffer into user variables:
Oh yes GolamMostafa, you're right that the the I2C communication should be based on a defined agreement rules, but in my case I didn't write the master code, and I want to emulate a sensor that according to the master request can answer with different parameters vaue and number of data.
Now I'm in the phase that the Master recognizes that the slave answered and so it continue to keep active the communication repeating the calls (if the slave is not recognized after the first call the master stop the communication), but the data value and/or byte number is not what the master was expecting.
If you go fo register level codings/instructions, you will be able to visualize what is going on behind all these HIGH Level Codes of Wire.h Library preapred by the smart Development Team of Arduino.cc.
in the function "onReceive" the slve can know the number of byte transmitted by the master, even is by the available() it is possible to know indirectly how many bytes remain to read.
In the function onRequest the slave has no way to know how many bytes the master wants to get.
Strange.
In a read request the slave can not know how many bytes the master wants to read, and the master can not know how many bytes the slave has actually sent.
Most likely the master is sending commands to the slave, to tell it what particular parameter it should send when it receives the next request. An emulator would need to receive and interpret the commands to know what to send.
If the Master can request a variable length of data, then you can fill the complete buffer with data in the onRequest handler. The buffer is 32 bytes for an Arduino Uno. I call it a trick that is (almost) allowed.
The Slave still does not know how many of that data is actually read by the Master.
I understand the bold "can" now.
If the requestEvent() has finished, then the interrupt driven Wire library finishes the I2C session on its own.
It could call a callback function to tell how much data was actually transferred. That would be nice to know. But we are stuck with the Wire library as it is.