I2C Send and Receive back.

can you help me with I2C Sending then Receiving back from the slave.

When i send 'H' or 'L' through Serial monitor, the slave will read, if it receive's 'H' from the Master then it will reply to the master "Success" and if it's 'L' then the slave will reply again "fail"

Master

//i2c Master Code(UNO)
#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  
  Wire.begin();


   Wire.requestFrom(5,5);
   while(Wire.available())
   {
     char c=Wire.read();
     Serial.print(c);
   }
}


void loop()
{
  while(Serial.available())
  {
    char c = Serial.read();
    
    if(c == 'H')
    {
      Wire.beginTransmission(5);
      Wire.write('H');
      Wire.endTransmission();
    }
    if(c=='L')
    {
     Wire.beginTransmission(5);
      Wire.write('L');
      Wire.endTransmission();
  }
}

Slave

//i2c Slave Code(Leonardo)
#include <Wire.h>

void setup()
{
  Wire.begin(5);
  Wire.onReceive(receiveEvent);
   Wire.onRequest(requestEvent);
 
}

void loop()
{
  delay(100);
}

void receiveEvent(int howMany)
{
  while(Wire.available())
  {
    char c = Wire.read();
    
    if(c == 'H')
    {
//
    }
   
  }
}

}
void loop()
{
  delay(100);
}

Are you being charged for each iteration of loop()? I don't think so. Get rid of the stupid delay().

  Wire.onReceive(receiveEvent);
   Wire.onRequest(requestEvent);

Do you know what these do? If not, it's time that you did some research.

I2C communication is all about interrupts. An interrupt happens, on the slave, when the master sends data. You've registered a function, receiveEvent (not exactly a meaningful or novel name), to be called when that happens.

An interrupt happens, on the slave, when the master sends a request for data. You registered a function, requestEvent (not exactly a meaningful or novel name), to be called when that happens.

You've implemented the function receiveEvent() that actually gets called when the master sends data, though it does nothing useful.

You have not implemented the function requestEvent that actually gets called when the master requests data. So, of course, nothing happens.

thank you sir, i manage to get what i want.

master

#include <Wire.h>

void setup()
{

  Wire.begin(); 
  

  Serial.begin(9600);
}

void loop()
{
  char s=Serial.read();
  if(s=='H')
  {
  // Request data from slave.
  Wire.beginTransmission(5);
  Wire.requestFrom(5,5);

   while(Wire.available())
   {
     char c=Wire.read();
     Serial.print(c);
   }
  delay(1000);
}
}

Slave

#include <Wire.h>

void setup()
{
  Wire.begin(5); 
  Wire.onRequest(requestform);
}
void loop()
{
}
void requestform()
{
  Wire.write("testing");
}

The proper way would be to have a global variable that the receiveEvent() writes to, and then implement the requestEvent() function, and have it send a response based on what was in the global variable.

But, if you are happy with your limited understanding of I2C, I'm fine with that.

Paul,

Can you provide a simple code structure that uses a global variable in a way that you suggested? I am new to programming as well, and am interested in learning about I2C communication.

Can you provide a simple code structure that uses a global variable in a way that you suggested?

Sure:

char masterSent;

void receiveEvent(int howMany)
{
  if(Wire.available())
  {
    masterSent = Wire.read();
  }
}

void requestEvent(int howMany)
{
   if(masterSent == 'H')
   {
       Wire.write("Hello");
   }
   else if(masterSent == 'W')
   {
       Wire.write("World");
   }
}