1

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->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
 SERCOM_I2CS_ADDR_ADDRMASK( 0x00ul ) |
 SERCOM_I2CS_ADDR_GENCEN // added by JAG

My master code:

#include <Wire.h>
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( "---> ");
 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 <Wire.h>
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 < 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( "<<<< Writing a response." );
}
asked Apr 4, 2017 at 2:04

2 Answers 2

1

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...

answered Feb 21, 2018 at 19:58
0

The I2C protocol supports bus arbitration only for masters sending (if more than one master in the bus starts sending at the same time). So, if any slave device would really respond to the General call address 0 with data, the data would geht corrupted if another slave would send data too. With this background it is reasonable, why an I2C slave device wouldn't respond to a request at the General call address.

If you have too many chips in the bus or don't want to address Thema directly due to another reason, you can send a trigger message to the General call address and let the other chips send their data as masters. Keep in mind, that in this case all involved chips must implement correct bus arbitration (and I'm not sure if the Wire library supports this).

answered Feb 21, 2018 at 22:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.