[RESOLVED] Using WIRE - - - - a "timing" question...

The below two sketches are the basic form of WIRE I’m using between two Arduinos.

I started getting a lot of garbage instead of my data when I added more lines between
requestEvent() {
and
Wire.write("hello ");

My guess is the lines take too long to exicute, throwing the bits off where they should land.

How is WIRE properly timed? How can I make sure it stays correct?

These lines:

Wire.requestFrom(8, 6);
  while (Wire.available()) {
    char c = Wire.read();

don’t make sense to me. For if the data hasn’t been received yet, “available()” will fall through and nothing be read. There is nothing to time when “available” will be exicuted, too soon or too late.

And my problem seems to be with the timing between “requestEvent” and “Wire.write”, how soon? How late?

I’m sure it’s been designed with a way to keep everything timed exactly right.

#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}
#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

Wire.requestFrom() doesn't return until it receives an ack. So there will be something to read. There may be a timeout, but that would only be encountered with a hardware failure.

aarg:
Wire.requestFrom() doesn’t return until it receives an ack.

Thank you, aarg. That’s exactly what I neede to know. (And you answered only a few minutes after I asked.)

Figuring out the rest then became a matter of experimentation.

Using “Master Writer/Slave Receiver” didn’t have timing problems, because it allows you to use
“Wire.write(data)”
again and again, until you end the process with a call to
“Wire.endTransmission();”

But now that I’ve switched to “Master Reader/Slave Sender” the rules are very different. Once I call
“Wire.write(data)”
that’s the end of it! Calling
“Wire.write(data)”
again has no effect.

So my “for” loop that worked so well in “Master Writer”

for (byte i=0; i<5; i++)
     Wire.write(outAA[i]);

was now ther season I was getting garbage!

To prove this, I tried the following code, even adding a 1-second delay to prove timing was not the problem:

 delay(1000);
  Wire.write("1234567890");
//RESULT:    49:50:51:52:53:54:55:56:57:48:

For the first time, “Master Reader” worked perfectly.

As more proof that
“Wire.write(data)”
can only be called once, I tried the following (with the delay removed as well), and got garbage again except for the first byte, which came from the first
“Wire.write(data)”.

 Wire.write("1");
  Wire.write("2");
  Wire.write("3");
  Wire.write("4");
  Wire.write("5");
  Wire.write("6");
  Wire.write("7");
  Wire.write("8");
  Wire.write("9");
  Wire.write("0");
//RESULT:    48:255:255:255:255:255:255:255:255:255:

I tested the correct way to do it again, this time with numberic data. And found to send ten bytes, I must include the number “10”. It gave me the correct result.

 for (byte x=0; x<10; x++)
    outAA[x] = (x+30);
    Wire.write(outAA,10);
//RESULT:    30:31:32:33:34:35:36:37:38:39:

Then I thought to try sending fewer bytes. Would the word “Wire.avaialbe()” at the receiving end stop reading when no more bytes? No it didn’t. “Wire.available()” seemed to have no effecdt at all.

Wire.write(60);
//RESULT:    60:255:255:255:255:255:255:255:255:255:

Then I went to the recieving sketch and changed the number of bytes asked for from 10 to only 4. Then
“Wire.avaialbe()”
kicked in after the 4th byte, clearly responding to how many bytes were asked for instead of how many are actually available.

  Wire.requestFrom(8, 4);
  for (byte i=0; i<10; i++)
  {
    while (!Wire.available())
      Serial.println("Not Available");
    Bio[i] = Wire.read();
    Serial.print(Bio[i]);
    Serial.print(":");
  }
//RESULT:    60:255:255:255:Not Available
Not Available
Not Available
Not Available
   ...

Now I have plenty of info to complete this section and move on to other aspects of my project.

And again, thank you aarg! Just what I needed to know.[/code]