I2C 2xMega2560 & 1xUno R3 connection problem

Hi,

Connected following devices by I2C:

Mega 2560(Master) - SDA(Pin20); SCL(Pin21); GND.
Mega 2560(Slave1) - SDA(Pin20); SCL(Pin21); GND.
Uno R3(Slave2) - SDA(A4); SCL(A5); GND.

When connected 2 Mega2560 Master-Slave1, it is connected and I can send and receive data. But if connecting Uno R3(Slave2) too, I2C is not working. How I can fix the problem?

Here is my Master Sketch:

#include <Wire.h>
///MASTER Receiver///

void setup()
{
  Wire.begin(1);        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  Wire.onRequest(requestEvent);
}

void loop()
{
  Wire.requestFrom(2, 20);    // request 6 bytes from slave device #2   ////Receiving Slave ID2; Mega2560////

  while(Wire.available())    // slave may send less than requested
  { 
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }
  delay(500);
  
  Wire.requestFrom(3, 20);    // request 6 bytes from slave device #3       ///Receiving Slave ID3; Uno R3///
   while(Wire.available())    // slave may send less than requested
  { 
    char d = Wire.read(); // receive a byte as character
    Serial.print(d);         // print the character
  }
  delay(500);
  
}
void requestEvent()
{
  Wire.write("Amigo go home to fly "); // respond with message of 6 bytes           ///Sending///
                       // as expected by master
}

And here is my Uno R3(Slave2) Sketch:

#include <Wire.h>

///SLAVE Sender///

void setup()
{
  Serial.begin(9600);
  Wire.begin(3);                // join i2c bus with address #3
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  Wire.requestFrom(1, 20);    // request 6 bytes from slave device #1      ///Receiving from Master ID1; Mega2560///

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

void requestEvent()
{
  Wire.write("Hello my dear0000000 "); // respond with message of 6 bytes         ///Sending to Master ID1; Mega2560///
                       // as expected by master
}

Why is the slave requesting data from the master? Seems to me that you don't understand master and slave relationships.

Where is the Mega slave code? Seems to me you didn't understand POST ALL OF YOUR CODE.

Because I want to use it like Multi Master.

Master - Receiver
Master - Transmitter
Slave - Receiver
Slave - Transmitter

Master device requesting any changes of Slaves Inputs. And controling Slaves Outputs.
Slaves transfering data and waiting command from Master

Here is Mega2560(Slave1) Sketch(this is working with Master):

#include <Wire.h>
///SLAVE Sender///

void setup()
{
  Serial.begin(9600);
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  Wire.requestFrom(1, 20);    // request from master device #1      ///Receiving///

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

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Wire.write("Hello I`m Mega2560  "); // respond with message of 6 bytes         ///Sending///
                       // as expected by master
}

What happens if you connect one Mega as master and one Uno as slave (but not the other Mega)?

Also, you could test with no code in loop() of either slave. Just leave the requestEvent() functions to respond to the polls from the master.

Hackscribble: What happens if you connect one Mega as master and one Uno as slave (but not the other Mega)?

Same problem. It is not responding when Mega2560(Slave1) is out

Hackscribble: Also, you could test with no code in loop() of either slave. Just leave the requestEvent() functions to respond to the polls from the master.

Ok. I`ll try this version

I solved problem. GSM/GPRS shield connected to Uno R3(Slave2) I removed 2 GSM/GPRS shield pins which connected to A4 and A5 of Uno R3.

Now both function (GSM and I2C) working normally. And Master receiving/transfering data from/to Slave1 and Slave2. :D

I have a new problem:
Slave2(Uno R3 with GSM module) send data to Master.
Master after read the data from Slave2, must send this data which read Slave2, to Slave1.
Master read data from Slave2 normally but is not sending to Slave1 after reading from Slave2. Because commands - Wire.beginTransmission(), Wire.write(), Wire.endTransmission() is not works in void receiveEvent()

How I can solve this problem? I try some versions but is not working. Please help.

There is sketch Slave2 Uno R3 with GSM module:

#include <Wire.h>

#include <SoftwareSerial.h>
 
SoftwareSerial gprsSerial(7, 8);
 
 
void setup()
{
  Serial.begin(9600);
    gprsSerial.begin(19200);
 
    // Setup for receiving sms
    // Delay between command
    
    gprsSerial.print("AT+CREG=?\r");  //request network registration//
    delay(300);
    gprsSerial.print("AT+CSMS=?\r");  //request sms //
    delay(300);
    gprsSerial.print("AT+CSCA=?\r");  //request sms center address//
    delay(300);
    gprsSerial.print("AT+CMGF=1\r");  //set SMS mode as TEXT mode//
    delay(300);
    gprsSerial.print("AT+IFC=1, 1\r");
    delay(300);
    gprsSerial.print("AT+CPBS=\"SM\"\r");
    delay(300);
    gprsSerial.print("AT+CNMI=1,2,2,1,0\r"); //SMS indicator//
    delay(500);
    
    
    Wire.begin(3);    ///I2C setup///
    //Wire.onRequest(requestEvent);
}
 
String currStr = "";
// variable is set True, if current line is message
boolean isStringMessage = false;
 
void loop()
{
    if (!gprsSerial.available())
        return;
 
    char currSymb = gprsSerial.read();
     Serial.print(currSymb);
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //if current line - SMS message,
            //action
            if (!currStr.compareTo("Fan on")) {
                digitalWrite(greenPin, HIGH);
                Wire.beginTransmission(1);
                Wire.write(62);
                Wire.endTransmission();
                delay(100);
                gprsSerial.print("AT+CMGD=3\r");  //Delete All READ, SENT and UNSENT messages
            } else if (!currStr.compareTo("Fan off")) {
                digitalWrite(greenPin, LOW);
                Wire.beginTransmission(1);
                Wire.write(72);
                Wire.endTransmission();
                delay(100);
                gprsSerial.print("AT+CMGD=3\r");  //Delete All READ, SENT and UNSENT messages
            }
            isStringMessage = false;
        } else {
            if (currStr.startsWith("+CMT")) {
                //if current line starting with "+CMT",
                //next line is a message
                isStringMessage = true;
            }
            
        }
           
        currStr = "";
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
    }
}

There is Master Sketch:

#include <Wire.h>
///MASTER Receiver///

void setup()
{
  Wire.begin(1);        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  Wire.onReceive(receiveEvent);
  pinMode(42, OUTPUT);
}

void loop()
{
//Do Nothing
    
}



void receiveEvent(int howMany){  //Receiving data from Slave2 GSM module
  while (Wire.available() > 0){
    int b = Wire.read();
    Serial.print(b, DEC);
    if(b==62){
      digitalWrite(42, HIGH);  //Control receiving data from Slave2/GSM module or not//
    Wire.beginTransmission(2); //PROBLEM!!! NOT SENDING TO SLAVE1/IO//
    Wire.write(162);
    Wire.endTransmission();
    }else if (b==72){
    digitalWrite(42, LOW);  //Control receiving data from Slave2/GSM module or not//
    Wire.beginTransmission(2); //PROBLEM!!! NOT SENDING TO SLAVE1/IO//
    Wire.write(162);
    Wire.endTransmission();
    }
  }
  Serial.println(); 
}

And there is Slave1 I/O sketch:

#include <Wire.h>
///SLAVE Sender///

void setup()
{
  Serial.begin(9600);
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onReceive(receiveEvent);
  pinMode(48, OUTPUT);
}

void loop()
{
//Do Nothing
}

void receiveEvent(int howMany){ 
  while (Wire.available() > 0){
    int b = Wire.read();
    Serial.print(b, DEC);
    if(b==162){
    digitalWrite(48, HIGH);
    }else if(b==172){
    digitalWrite(48, LOW);
    }
    
  }
  Serial.println(); 
}