[SOLVED] Using Wire to communicate in both directions.

These are the “Master” and “Slave” sample sketches from this page for usine Wire.

// MASTER READER

#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);
}

// SLAVE SENDER

#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
}

In the MASTER sketch, the line “Wire.requestFrom(8, 6);” is asking SLAVE sketch number 8 to send 6 bytes of information. But what effect does the number “6” have?

The MASTER then says “while (Wire.available())”, admitting it doesn’t know how many bytes are actrually going to be sent back. And at the same time, I don’t see any way for the SLAVE sketch to know that “6” is the number of bytes asked for.

In my case, the SLAVE sketch needs to know how many bytes are asked for, because this will determine what is replied; specificallly, the battery condition (one byte) or a set of bio-feedback values (ten bytes).

+++++++++++++++++++

A second question: Is there a way (within Wire) for the SLAVE sketch to send un-requested info to the MASTER sketch at odd times without the MASTER needing to continuously poll for it?

CosmickGold:
But what effect does the number "6" have?

The master issues a START bit and sends a packet with the address of the slave (8 here) with the read bit set. So the slave knows it has to respond. After that the the master generates the clock so the slave can send data back. After each packet a now START bit is issued by the master so the slave knows it can keep sending. The master does that 5 times here. The 6th time it will send a STOP to tell the slave the transmittion is over.

CosmickGold:
I don't see any way for the SLAVE sketch to know that "6" is the number of bytes asked for.

It does not know. That's part of the protocol used to determine what is asked from the slave.

CosmickGold:
In my case, the SLAVE sketch needs to know how many bytes are asked for, because this will determine what is replied; specificallly, the battery condition (one byte) or a set of bio-feedback values (ten bytes).

Then you first write to tthe slave to tell him to get the battery condition or the bio-feedback ready. Now the slave knows what to do and upon request sends it back. And because the master also knows what to expect back it changes the request length accordingly. The slave just hopes it can send it all back.

CosmickGold:
A second question: Is there a way (within Wire) for the SLAVE sketch to send un-requested info to the MASTER sketch at odd times without the MASTER needing to continuously poll for it?

As a slave, no. But I2C is Multi Master. If the bus is free a node can switch from slave to masterand just transmits. But this requires the master to switch back to slave as well after transmission so it listens as well.

I think that the slave will need two handlers Wire.onReceive() and Wire.onRequest().

Take a look at the two other examples in the Wire library-- master_writer and slave_receiver as well as what you have posted for slave_sender and master_reader.

The Master will send twice. Once using the standard master_writer format which will send a command and Wire.onReceive will interpret that and set up what the slave to do what comes next with the Wire.onRequest. I have seen a switch case in the Wire.onRequest() based on what the slave received in Wire.onReceive.

Great answers from both of you, teaching me a few new things. With all you said in mind, I added a wire between an output pin of the slave and an input pin of the master, so the slave can use that wire to tell the master it wants to say something.