I2C broadcast and reply on Arduino M0+ I am trying to set up several ATSAM-based AVR chips in a master/slave broadcasting arrangement. I want the master to be able to send a broadcast message to I2C address 0, and then for slaves to respond with different information. I have seen other implementations where this has been successful since I2C devices will typically self-arbitrate and if they are configured to back-off when arbitration is lost, the master can repeat its request and iterate over all addresses on the bus.

The challenge is that while I have Wire.beginTransmission(0) working to reach my slaves from the master, I cannot get Wire.requestFrom(0,6) to work. The slave acts as though no message had arrived in the reply case. This is in the reduced case of one master and one slave. 

In the example below, changing RequestFrom to the slave address will work.

I am aware that on the SAMD architecture, ArduinoCore does not configure the SERCOM for I2C broadcasts so I made a one-line modification as follows to enable it:

sercom-&gt;I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress &amp; 0x7Ful ) | // 0x7F, select only 7 bits
                      SERCOM_I2CS_ADDR_ADDRMASK( 0x00ul ) |
                      SERCOM_I2CS_ADDR_GENCEN // added by JAG


My master code:

#include &lt;Wire.h&gt;

void setup() {

  Serial.begin(9600);
  Serial.println("Sketch start" );

  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {

  Serial.print("-- Top of loop:" );
  Serial.println( millis() );

  Wire.beginTransmission(0); // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission(true);    // stop transmitting


  // delay( 500 );

  uint8_t recvSize = Wire.requestFrom(0, 6);    // request 6 bytes from slave device #8

  Serial.print( "Got bytes: " );
  Serial.print( recvSize );
  Serial.print( "---&gt; ");

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



  x++;
  delay(500);
}


My slave code:

#include &lt;Wire.h&gt;

void setup() {
  Wire.begin(9);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println( "Starting up" );
}

void loop() {
  delay(500);
    Serial.print( "In top of loop (slave): " );
    Serial.println(millis() );
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 &lt; Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    SerialUSB.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  SerialUSB.println(x);         // print the integer 
}

// 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
  Serial.println( "&lt;&lt;&lt;&lt; Writing a response." );
}
If you broadcast data using Wire.send(data), the slaves would receive this in there onReceive handler but as far as I can remember, the I2C slave will not respond on a Wire.requestFrom(...) broadcast from the master. 

Imagine x slaves responding all at the same time to the request...