I am trying to set up a "keepAlive" system over IIC between two boards (Lolin D32). The process is this:
Master generates a random number (0-255)
Master saves it to an array
Master Wire.writes random number from that array to the slave
Slave immediately receives random number
Slave saves random number to its own array
delay 2 seconds----------
Master requests random number from slave
Slave sends random number directly from the array
Master saves random number into different location on its array to compare with the previous random number it sent
The problem is this:
The Slave reports that it is sending the same random number ( I have it serial print out the data from that array location before it sends it) The Master then serial prints the data that it is getting in 'live' and the numbers are not the same. The Master reports that the number it is getting is the random number generated in the previous loop.
My Questions
How is it that the old number is getting sent if the data in the array is showing as the current number and the data is being sent directly from that array position?
Is there some sort of buffer that needs to be cleared?
Additional information
The array stores more data than just the random number.
The other data in the array gets sent at the same time. The other data is not set up to change at the moment so I am unsure if that data is old as well. In other words, that data is static for now and always shows as the same thing.
The keepAlive() function will eventually compare the numbers in the two array locations but it doesn't do anything at the moment.
I am using the Wire.h lib.
Array:
Both the Slave and Master have a copy of this same array
Yes, you can see that I have serial print function for that data currently commented out in the code. It shows I am receiving 2 bytes when it is uncommented. In addition, I am serial printing the incoming data itself and it is matching the random number that is generated by the Master.
The data going to the Master has no issues. The data coming from the slave back to the master is where the issue is.
I am not sure at this point. I have already soldered my proto boards and it looks like Serial2 uses different pins that are already in use by other things on the board.
The IIC is working, just not as expected. I would like to solve this particular issue instead of trying something else right now.
In that link you sent, it stated that Wire.write just writes to a buffer and endTransmission actually does the sending. I did not have that in my onRequest function in the slave. I am trying that now...
Did the discussion you were trying to remember have anything to do with something like Wire.slaveWrite? According to the article it is required for esp32.
I thought that might empty the buffer of old numbers to make room for new numbers. It is not part of wire.h as far as I can tell. I took it out and nothing changed.
How long would it take to get there? I have a 2 second delay between getting the data and then sending it back. Also, I check to see if the random numbers have been posted in the array before i send the array and they are there.
I think the issue has something to do with the buffer being sent before the new numbers are added to the buffer.
It is the lowest part of that page, with "Warning" and "for ESP32 only!".
It turns out that I can link to the bottom of that page: I2C — Arduino-ESP32 2.0.6 documentation
The way I read it, is that they forgot to design the ESP32 to be used as a I2C Slave to Arduino boards. It took a few years, but there is now a workaround, although the buffer has to to be pre-filled.
I may abandon I2C as I couldn't figure out how to change the data type used in Wire.slaveWrite. It looks like it wants characters and I want to send a byte array. More specifically, only some parts of the array...
I am working on using serial2 right now. I have never used it before though and I have no idea what data types I can send using it. Wish me luck!
Wire.avail returns number of bytes ready to read, if used as a boolean then read one byte at a time, if you know you need two bytes, then wait till Wire.avail returns <1.
The same data types that you can send with Serial. In fact, the same data types that you can send with any object whose class inherits from the Stream class.
A little note: There is no such thing as waiting after a Wire.requestFrom(). That function is blocking. When it returns, the I2C bus session has completely finished and that was successful or not.
I prefer to check if the same number of bytes was received. The current implementation returns either zero or the same as requested, but checking for the same number looks good in the source code.
int n = Wire.requestFrom(i2c_address, 5); // request 5 bytes
if( n == 5) // did we get 5 bytes ?
{
// Hooray, the same number of bytes received as was requested !
// Read them with Wire.read() or Wire.readBytes().
...
}