Can't send data from several master Arduinos to a single slave Arduino over I2C

Hello all,

I am trying to send data from 7 RFID MFRC522 readers, each connected to an Arduino behaving as a master, to a single shared Arduino that is behaving as a slave. So 7 master Arduinos and 1 slave Arduino. I've done this so I can control when the data would be sent to the slave Arduino as it should only transmit data when an RFID tag is read by the reader. Atleast, from my basic understanding of I2C protocol, this is what I've implemented because I need to only send data when I want to.

To get started, I only connected one Arduino(Master) to the slave. It worked perfectly and data is being transmitted as I need it to. Now, when I connected two Arduinos (Master) to the slave, nothing is working. None of the masters are sending data to the slave or maybe if they are, it isn't showing on the serial monitor over my slave.

P.S. I haven't used any pull-up resistors as a single master-slave connection was working without any. Is this the problem? If so, how do I use them for a design where I have 7 Masters and 1 slave.

Master Arduino#1

#include <SPI.h>
#include <MFRC522.h>
#include <FileIO.h>
#include <Wire.h>

#define RST_PIN         9        // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance





void setup() {
  Serial.begin(9600);   // Initialize serial communications with the PC
  Wire.begin(); // join i2c bus (address optional for master)
  //while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)

  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  //mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
  //Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
  pinMode(50,INPUT);
 
}



void loop() {

  
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

 

//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

//Serial.print("UID Tag: ");
String content= "";
byte letter;
for (byte i=0; i<mfrc522.uid.size;i++)
{

     //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     //Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0": " "));
     content.concat(String(mfrc522.uid.uidByte[i] , HEX));
}

Serial.println();
Serial.print("Message : ");
content.toUpperCase();




if (content.substring(1) =="30 D6 3D A6")

{
  
  Wire.beginTransmission(8); // transmit to slave
  Wire.write("Person 1 is in the premises");
  delay(1000);
  Wire.endTransmission();    // stop transmitting
}

if (content.substring(1) =="A0 47 CE A4"){

  Wire.beginTransmission(8); // transmit to slave
  Wire.write("Person 2 is in the premises");
  delay(1000);
  Wire.endTransmission();    // stop transmitting


}

Now, this is the code I wrote for the second Master. I changed the adress from 8 to 9.

Master Arduino#2

#include <SPI.h>
#include <MFRC522.h>
#include <FileIO.h>
#include <Wire.h>

#define RST_PIN         9        // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance





void setup() {
  Serial.begin(9600);   // Initialize serial communications with the PC
  Wire.begin(); // join i2c bus (address optional for master)
  //while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)

  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  //mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
  //Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
  pinMode(50,INPUT);
 
}



void loop() {

  
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

 

//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

//Serial.print("UID Tag: ");
String content= "";
byte letter;
for (byte i=0; i<mfrc522.uid.size;i++)
{

     //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     //Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0": " "));
     content.concat(String(mfrc522.uid.uidByte[i] , HEX));
}

Serial.println();
Serial.print("Message : ");
content.toUpperCase();




if (content.substring(1) =="30 D6 3D A6")

{
  
  Wire.beginTransmission(9); // transmit to slave
  Wire.write("Person 1 is in the premises");
  delay(1000);
  Wire.endTransmission();    // stop transmitting
}

if (content.substring(1) =="A0 47 CE A4"){

  Wire.beginTransmission(9); // transmit to slave
  Wire.write("Person 2 is in the premises");
  delay(1000);
  Wire.endTransmission();    // stop transmitting


}

And this is the code for my slave:

#include <Wire.h>

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

void loop() {
  delay(100);
}

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

So 7 master Arduinos and 1 slave Arduino.

This is a fundamental error in the architecture. It must be the other way around: one master and seven slaves. If that is not practical in your project, I2C is the wrong choice.

  Wire.begin(8);                // join i2c bus with address #8
  Wire.begin(9);                // join i2c bus with address #8

An I2C slave can have only one address, at least on the AVR hardware.

So keeping this in mind, do you have any fix for this within I2C whereas I make all of the 7 Arduinos slaves and 1 master and implement the same design? Whereas I only send data from the slaves when a certain action is performed (A tag comes in range of the reader)?

Or could you suggest any other communication protocal? I looked up SPI but it looked like slave select would've been a problem and from my understanding of UART, it could only work between two devices and not more than that.

A CAN bus might the solution, any node can send a request to any other node (up to 120 nodes).

Or could you suggest any other communication protocal? I looked up SPI but it looked like slave select would've been a problem and from my understanding of UART, it could only work between two devices and not more than that.

With SPI you have exactly the same problem as with I2C: one master, several slaves. As ard_newbie suggested, a CAN bus might work, you might also get it to work with an RS-485 bus but you have to take care in hardware that you have some congestion recognition. Ethernet is another option, which is especially interesting if the Arduinos will not be placed close together.