Hello, i tried to connect one esp8266(master) and one esp32(slave) with the I2C protocol, but i noticed a problem when i request at the slave some bytes. When the data i receive from the slave they are one "step backwards". The firts data are always all 0xFF the second time i request it return the first data i request. thi is the code:
The onRequest callback is called when another master requests data. The slave is not allowed to do begin/endTransmission() in that callback. See the slave_sender example.
DrDiettrich is right and another issue is that you should call onRequest() only once during setup.
However the problem that you are reporting is unrelated.
ESP32 slave mode is awkward, that's why it took so long to have it at all in the Arduino code base, and Espressifs current documentation doesn't help clarifying things, particularly their examples lead you to think that it works just like we are used to while it doesn't.
I'm not an expert and did not test it fully yet, but here's what I deducted from my tests so far:
ESP32 needs the buffer prefilled before the I2C interrupt happens. So whatever you write in the event() ISR comes too late, it will only be sent in the next occurrence. As a consequence you
need to prefill the buffer in the main loop before the interrupt happens,
run the risk of incomplete replies because of that, and
are not able to generate the data for sending on the fly. E.g. if you want your slave to return the value of some pin's state you cannot read it on the fly, but find some other way to have the current value ready.
I briefly mentioned this problem only recently here. In case you read German, the problem is also discussed here. Here is the current version of how I tried to solve the problem in my AccelStepperI2C firmware:
For a variation of option 2 see my above example code. Just think of the slave as a real slave device which only acts on a previous command, i.e. some data with the desired behavior sent by the master immediately before the request. Timing and/or sanity checks are crucial, though, as the slave could send bogus or incomplete data if it didn't get enough time to prepare the desired data before receiving the request. That's one of the reasons I added CRC8 checksums in my example above.