Passing Serial data over I2C to another Arduino

Here I have an arduino mega (Master) and an Uno (Slave). Both of them are connected to my laptop over USB ports. I would like to turn on the LED on arduino Uno when I write the “ON” on the adruino mega’s Serial monitor which I have on my laptop’s screen. unfortunately it doesn’t work. :frowning:

I would be grateful if you let me know how can I solve this problem. :confused:

here’s the Master code which is connected to both I2C and serial ports. :smiley:

#include <Wire.h>

String Input_data_String = "";
char   Input_data_string[5];
const int ledPin =13;

void setup() {
     Wire.begin();
     Serial.begin(9600);
     while (!Serial) {
      }
}

void loop() {
 delay(10);
}

void serialEvent() {
  while (Serial.available()) { 
   
    char inChar = (char)Serial.read(); 
    Input_data_String += inChar;

 
    if (Contains(Input_data_String ,"Read")){        
      Input_data_String.toCharArray(Input_data_string,5);
      //Serial.println ("Message from Arduino");             
      Wire.beginTransmission(2);           // transmit to device #2
      Wire.write(Input_data_string);       // sends String
      Wire.endTransmission();              // stop transmitting
      Input_data_String ="";}

    if (Contains(Input_data_String ,"ON")){        
      Input_data_String.toCharArray(Input_data_string,5);
      //Serial.println ("Message from Arduino");             
      Wire.beginTransmission(2);           // transmit to device #2
      Wire.write(Input_data_string);       // sends String
      Wire.endTransmission();              // stop transmitting
      Input_data_String ="";}


     if (Contains(Input_data_String ,"OFF")){        
      Input_data_String.toCharArray(Input_data_string,5);
      //Serial.println ("Message from Arduino");             
      Wire.beginTransmission(2);           // transmit to device #2
      Wire.write(Input_data_string);       // sends String
      Wire.endTransmission();              // stop transmitting
      Input_data_String ="";}
   }
   
}

 bool Contains( String s, String search) {
    int max = s.length() - search.length();  
    for (int i=0; i<= max; i++) 
    {
    if (s.substring(i) == search) return true;  // or i
    }
    return false;  //or -1
    }

And here’s my slave code which is connected via I2C to the master.

#include <Wire.h>

String Data = "";
char data[5];

void setup() {
  Wire.begin(2);                
  Wire.onReceive(receiveEvent); 
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {
  delay(100);
}


void receiveEvent(int howMany) {
  while( Wire.available()){
    delay(500);
    Data += (char)Wire.read();
  }

if (Data == "ON"){             
      digitalWrite(13, HIGH);                       
      Data="";}
digitalWrite(13,LOW);

if (Data == "OFF"){             
      digitalWrite(13, LOW);                       
      Data="";}
  }

Your code seems to be confused: if you just want to send data from the Master to the Slave, look at the Wire.h example:

Master:

#include <Wire.h>

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

byte x = 0;

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

  x++;
  delay(500);
}

Slave:

#include <Wire.h>

void setup()
{
  Wire.begin(8);                // 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 (1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

If you want to send and receive String:

Master

#include <Wire.h>
#define I2CAddress 9

String text;

void getText(){
  if(Serial.available()) // check if we send a message
  {
    while(Serial.available())
    {
      char c = Serial.read(); // read the next character.
      text += c;
      delay(10);
    }  
  }
}

void sendText() {
  Wire.beginTransmission(I2CAddress); // transmit to device #9
  for(int i=0; i<(text.length()); i++){
    Wire.write(text[i]);
  }              
  Wire.endTransmission();    // stop transmitting
}

void setup() {
  Serial.begin(9600);
  Serial.println("Master here");
  
  // Start the I2C Bus as Master
  Wire.begin(); 
}

void loop() {
  text = "";
  while(text.length() == 0) { // Until we send text in the serial monitor
    getText();
    }
  if(text.length() > 0) {
     Serial.print("Send: " + text);
     sendText();
  }
  delay(500);
}

Slave:

#include <Wire.h>

#define I2CAddress 9
#define ledPin 13

void receiveString(int bytes) {
  String text = "";
  while (Wire.available()) { 
    char c = Wire.read(); // receive a byte as character
    text += c;
  }
  Serial.print("Printing: ");
  Serial.println(text);

  manageLed(text);
}

void manageLed(String cmd) {
  if(cmd == "ON")
    digitalWrite(ledPin,HIGH);
  else if(cmd == "OFF")
    digitalWrite(ledPin,LOW);
  else
    Serial.println("Unknown command: " + cmd);
}

void setup() {
  Serial.begin(9600);
  Serial.println("Slave here");
  
  // Start the I2C Bus as Slave on address 9
  Wire.begin(I2CAddress); 

   // Attach a function to trigger when something is received.
  Wire.onReceive(receiveString);

  // LED
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
}

void loop() {
  delay(10);
}

PS: I didn’t try the code on 2 arduinos