0

This code runs without issues, scoped and seen from serial output:

#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin();
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}

This one hangs on Wire.endtransmission():

#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin(10);
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}

The problem starts as soon as I assign an address in Wire.begin(). As I understand, a slave is also allowed to send data and temporarily becoming a master when addressing another device.

  • Is there another master on the bus, that would require the mkr to also be a slave? – chrisl May 13 at 9:08
  • Yes and no, I have three devices, master mkr, two trinket m0 slaves. I want to push data from the slaves to the master immediately when they receive said data. The way it is setup, data collision from the slaves is impossible as the master alterantely enables the sensors on the slaves (this is why I need it to be a master for coordination) but I also want to receive the data as soon as it arrives and not poll for it as I fear that might mess up my interrupts on the slaves. – Horst May 13 at 9:14
1

I want to push data from the slaves to the master immediately when they receive said data.

So that means, that each slaves becomes master directly after it has received data from the MKR. This is still a multi-master setup, even while you are avoiding collisions through a fixed protocol. The Wire library does not support multi-master.

But I also don't understand, why you would need this. Your protocol does this: The MKR sends data to a slave (triggering it and maybe also sending some commands). Then the slave should send data back to the master. Then the transmission ends. This is normally done in I2C with just one master. The master does a master write (via Wire.endTransmission() and sends some command data to the slave. The slave will prepare the data, that the master requested, in it's buffer. Then the master will start a master read (via Wire.requestFrom()) which reads the data from the slave.

So you don't need a multi-master setup for this. It does exactly, what you described, but with only one master.

| improve this answer | |
  • I found out the Wire library actually does support multi-master, but not on the ATSAMD – Horst May 14 at 12:45
  • I have no way to predict when the slave will receive it's data, so other than polling the slave continuously I won't know when the data arrived at the slave. – Horst May 14 at 12:46
  • In your original plan, you wanted to prevent collisions by essentially polling the slaves (writing data to them, so that they answer them selfs with a master transmission). If that is not an option anymore, you should think about a different communication interface, that better supports multi master scenarios – chrisl May 14 at 13:21
0

While the wire library supports multi-master for AVR, it doesn't for ATSAMD.

Temporary promotion to master is disabled when given a slave address, so the program will hang on wire.endTransmission().

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.