I've been reading about i2c and thought it sounded like a nice solution for communication between arduinos. I've got two set up and communicating to each other, but I've got a few questions.
It works, but I don't understand how or why.
I've read that wire.write() sends one byte at a time, and that it is the master's job to receive the data and reconstruct it into the appropriate format. They also have to agree on the data structure being sent to do this.
Simply trying
wire.write(w)
(With w being an unsigned int) and then receiving it on the master with
int x = Wire.read
results in two lines being printed to the serial monitor, even when I used Serial.print(x) and not Serial.println. It looked like it was printing the first byte, then reading x into the second byte and overwriting the first, printing the value of x in between overwriting it.
I played with it for a few hours before finding that this works:
Slave:
Wire.write((byte *)&w, sizeof(unsigned int));
Master:
Wire.requestFrom(2, 2); // request 2 bytes from slave device #2
while(Wire.available()) // slave may send less than requested
{
x = Wire.read();
y = Wire.read();
z = y * 256 + x;
Question being, although this works great, what exactly is going on here?
I'm guessing that the single line of code on the slave device sends the two bytes to the master (Defined by sizeof() ?). It somehow knows to send one byte the first Wire.read, and the second byte on the second Wire.read (Is this a parameter that must be given, or does it always do this? If I were to send an unsigned long, would it send out the 4 bytes through the master reading 4 times in a row? Surely there must be come kind of confirmation by the master that it's read byte 1 out of 4, send the next one on the next read please?)
The master then reads the first byte sent into x, then reads again and is sent the second byte which it reads into y, and somehow combines them into the original 2-byte int with z = y * 256 + x (Some kind of bitshifting magic?).
Could somebody kindly walk me through what the line on the slave device does, step by step, and how the master recompiles the two bytes into one variable?
Also wondering if there is there a better/faster way to do this. Eventually there will be several slaves sending information to the master, all of the information will be either an unsigned int or unsigned long.
The purpose of this being that the slave device takes readings and does some processing, sends the constantly changing result to the master for displaying on an lcd screen.
Apologies if this is long and rambling. I found a few topics searching about this but didn't understand them very well. Trying to understand more about bitwise operators now but an example of how it works in this code would be really helpful.