Wire library: Odd timing issue with I2C , and the use of "Wire.onRequest"

I am emulating an I2C (slave)device.
The master sends an command to the Arduino (slave) program, the second byte tells the program what to send.

My program is something like this (simplified)

#include<Wire.h>
bool flag1 = LOW;
byte myData[15];

void setup()
{
  Wire.begin (10);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendEvent);
}

void loop()  {}

void receiveEvent(int howMany)
{
  if(Wire.read() == '32')  //check command
  {
    flag1 = true; //request has come
    //myData would be prepared here
    }
  }
}


void sendEvent(int howMany)
{
  if(flag1 == true)
  {
      Wire.write(myData,10);
      flag1 = false
  }
}

So: the master sends two bytes (slave address + command)
and the slave is supposed to reply with it's own address + number of bytes , then the data(bytes)

It seems that the library itself (in slave mode) is just sending away the slave address right away on and hence starts the "reply".
Is this by design? - why ?

Also: Wire.onRequest seems to be hammering at all times on an active I2C bus, hence the bool and test7wait for first after the command byte. .. but is it really necessary ?
If I know that the command byte is always one byte, I could write right away ?

It seems that the library itself (in slave mode) is just sending away the slave address right away on and hence starts the "reply".

No, the library doesn't do that. But the master has to address the slave so the slave device knows that it has to send the requested bytes. That's how I2C works.

Also: Wire.onRequest seems to be hammering at all times on an active I2C bus, hence the bool and test7wait for first after the command byte. .. but is it really necessary ?

What do you mean by "hammering"? The Wire.onRequest() routine only gets active if the master addressed that slave.

If I know that the command byte is always one byte, I could write right away ?

I2C is not the same as a UART connection. The slave cannot write anything if the master doesn't request it. Remember, the clock signal is only generated by the master!

AndreK:

void receiveEvent(int howMany)

{
  if(Wire.read() == '32')  //check command
  {
    flag1 = true; //request has come
    //myData would be prepared here
    }
  }
}

that comparison will never work. Wire.read() returns a byte (uint8_t) but you are comparing it to '3' (I think. can't check right now) since a two byte char evaluates to the first char. You should be comparing it to an actual number like 0x32 (hex) which is the same as 50 (dec)

I would urge you to look at the i2c send/receive examples in the IDE to see how a slave sketch should be written (File->Examples->Wire->slave_receiver and slave_sender)

If your master will send different commands for different data, you will need to either save the current command and fill in your data based on that, or use the command to send different data in the sendEvent() function.

#include<Wire.h>

byte myData[15];

byte cmd;

void setup()
{
  Wire.begin (10);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendEvent);
}

void loop()  {}

void receiveEvent(int howMany)
{
  cmd = Wire.read();
  switch (cmd ) {
    case 0x32:
      myData[0] = 45;
      break;

    case 0x44:  // some other command
      myData[0] = 16;
      break;

    case 0x66:
      myData[0] = 12;
      myData[1] = 45;
      break;

    default:  // unknown command, blank all the data
      for (int i = 0; i < 15; i++) myData[i] = 0;
  }
}


void sendEvent(int howMany)
{
    Wire.write(myData, 10);
}