I2C onReceive event Freeze Arduino

Hello

I am facing a problem with arduino uno

My project is
I have one arduino mega as master and one arduino uno as a slave on an I2C bus
The arduino uno in main loop reading many variables from canbus through mcp2515(Spi interface)
The arduino mega(master) periodically sending a string through I2C to the uno to tell which variable it wants
For example"<1,2,3>"
After that, the master sends a request event to slave and the slave response with the variables that the master wants.
So in this example, the salve will response with the value of a first, second and third variable.

My main problem is that the arduino uno(slave) freeze after a small time period
I have noticed that the problem is on onRecive interrupt event function because if I make bigger this function the arduino will freeze faster.
If I make onReceive function very small the arduino will freeze after a big time period.

Can anyone help me?
Thank you in advance

Sorry, as far as I am informed all mindreaders are on vacancy.

@OP

**A:**Let us assume that:

(1) MEGA (Master) will send command 0x01 to Slave-UNO; in response, the Slave will send content of PINB Register to Master.

(2) MEGA (Master) will send command 0x02 to Slave-UNO; in response, the Slave will send content of PINC Register to Master.

(3) MEGA (Master) will send command 0x03 to Slave-UNO; in response, the Slave will send content of PIND Register to Master.

B: Tentative I2C Bus Connection Diagram between MEGA and UNO.
i2c-1x.png

C: Master-MEGA Codes:

#include<Wire.h>

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

  //--requesting Slave to send content of PBR-Register--
  Wire.beginTransmission(0x23); //I2C Address  of Slve (UNO2)
  Wire.write(0x01); //command code for PIB Register
  Wire.endTransmission();

  //---reading data (from FIFO Buffer) that is to come from Slave--
  Wire.requestFrom(0x23, 1);  //1-byte data being reqiested
  byte x = Wire.read();    //x contains the value of PINB sent by UNO2
  Serial.println(x, BIN);   //Serial Monitor shows PINB values of Slave
}

void loop()
{

}

D: Slave-UNO Codes:

#include<Wire.h>
bool flag1 = LOW;

void setup()
{
  Serial.begin(9600);
  Wire.begin(0x23);    //Slave's I2C Address
  DDRB = 0x00;   //Port-B direction as input
  
  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendEvent);
}

void loop()
{

}

void receiveEvent(int howMany)
{
  byte x= Wire.read();
  if(x == 0x01)
  {
    flag1 = HIGH;  //command received to send Port-B (input = PINB) content 
  }
}

void sendEvent(int howMany)
{
  if(flag1 == HIGH)
  {
    Wire.write(PINB); //sending PINB value of Port-B Register
    flag1 = LOW;
  }
}

E: Operating Procedures:
(1) Build the circuit as per diagram of Step-B.
(2) Upload Master codes of Step-C.
(3) Upload Slave Codes of Step-D.
(4) Using jumpers engage Logic level at DPin-8 to 13 (PB0 - PB5) of Slave.
(5) Press and hold reset buttons of both Arduinos.
(6) Bring in Serial Monitor of Master at 9600 Bd.
(7) Release reset button of Slave.
(8) Release reset button of Master.
(9) Check that the content of PINB Register of Slave has correctly appeared on Serial Monitor of Master.

G: Add codes to Master and Slave sketches for the command codes 0x02 and 0x03 and the corresponding responses.

i2c-1x.png

Thank you for the responce

I have write the code as you say

But I a problem
The arduino uno(slave) freeze after a small time period
I have noticed that the problem is on onRecive interrupt event function because if I make bigger this function the arduino will freeze faster.
If I make onReceive function very small the arduino will freeze after a big time period.

So there is probably something fishy with your code.

But you are the only one who can see it, good luck.

@OP

You may practice this tutorial to see how Master and Slave exchanges data using I2C Bus under interactive session and then spend time to correct your codes which we don't see.

A: Let us assume that:

(1) MEGA (Master) will send command 0x01 to Slave-UNO when K1 is pressed; in response, the Slave will send content of PINB Register to Master.

(2) MEGA (Master) will send command 0x02 to Slave-UNO when K2 is pressed; in response, the Slave will send content of PINC Register to Master.

(3) MEGA (Master) will send command 0x03 to Slave-UNO when K3 is pressed; in response, the Slave will send content of PIND Register to Master.

B: Tentative I2C Bus Connection Diagram between MEGA and UNO.
i2c-1xc.png

C: Master-MEGA Codes:

#include<Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(2) == LOW)
  {
    //--requesting Slave to send content of PBR-Register--
    Wire.beginTransmission(0x23); //I2C Address  of Slve (UNO2)
    Wire.write(0x01); //command code for PIB Register
    Wire.endTransmission();

    //---reading data (from FIFO Buffer) that is to come from Slave--
    Wire.requestFrom(0x23, 1);  //1-byte data being reqiested
    byte x = Wire.read();    //x contains the value of PINB sent by UNO2
    Serial.print("Getting PINB value from Slave : ");
    Serial.println(x, BIN);   //Serial Monitor shows PINB values of Slave
  }

  if (digitalRead(3) == LOW)
  {
    //--requesting Slave to send content of PBR-Register--
    Wire.beginTransmission(0x23); //I2C Address  of Slve (UNO2)
    Wire.write(0x02); //command code for PIB Register
    Wire.endTransmission();

    //---reading data (from FIFO Buffer) that is to come from Slave--
    Wire.requestFrom(0x23, 1);  //1-byte data being reqiested
    byte x = Wire.read();    //x contains the value of PINC sent by UNO2
    Serial.print("Getting PINC value from Slave : ");
    Serial.println(x, BIN);   //Serial Monitor shows PINB values of Slave
  }

  if (digitalRead(4) == LOW)
  {
    //--requesting Slave to send content of PBR-Register--
    Wire.beginTransmission(0x23); //I2C Address  of Slve (UNO2)
    Wire.write(0x03); //command code for PIB Register
    Wire.endTransmission();

    //---reading data (from FIFO Buffer) that is to come from Slave--
    Wire.requestFrom(0x23, 1);  //1-byte data being reqiested
    byte x = Wire.read();    //x contains the value of PIND sent by UNO2
    Serial.print("Getting PIND value from Slave : ");
    Serial.println(x, BIN);   //Serial Monitor shows PINB values of Slave
  }
}

D: Slave-UNO Codes:

#include<Wire.h>
bool flag1 = LOW;
bool flag2 = LOW;
bool flag3 = LOW;

void setup()
{
  Serial.begin(9600);
  Wire.begin(0x23);    //Slave's I2C Address
  DDRB = 0x00;   //Port-B direction as input
  DDRC = 0x00;
  DDRD = 0x00;

  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendEvent);
}

void loop()
{

}

void receiveEvent(int howMany)
{
  byte x = Wire.read();
  if (x == 0x01)
  {
    flag1 = HIGH;  //command received to send Port-B (input = PINB) content
  }

  if (x == 0x02)
  {
    flag2 = HIGH;  //command received to send Port-B (input = PINB) content
  }

  if (x == 0x03)
  {
    flag3 = HIGH;  //command received to send Port-B (input = PINB) content
  }


}

void sendEvent(int howMany)
{
  if (flag1 == HIGH)
  {
    Wire.write(PINB); //sending PINB value of Port-B Register
    flag1 = LOW;
  }

  if (flag2 == HIGH)
  {
    Wire.write(PINC); //sending PINB value of Port-B Register
    flag2 = LOW;
  }

  if (flag3 == HIGH)
  {
    Wire.write(PIND); //sending PINB value of Port-B Register
    flag3 = LOW;
  }
}

E: Operating Procedures:
(1) Build the circuit as per diagram of Step-B.
(2) Upload Master codes of Step-C.
(3) Upload Slave Codes of Step-D.
(4) Using jumpers engage Logic level at DPin-8 to 13 (PB0 - PB5) of Slave.
(5) Press and hold reset buttons of both Arduinos.
(6) Bring in Serial Monitor of Master at 9600 Bd.
(7) Release reset button of Slave.
(8) Release reset button of Master.
(9) Press button K1.
(10) Check that the content of PINB Register of Slave has correctly appeared on Serial Monitor of Master.

(11) Using jumpers engage Logic level at DPin-A0 to A3 (PC0 - PC3) of Slave.
(12) Press button K2.
(13) Check that the content of PINC0-PINC3 Register of Slave has correctly appeared on Serial Monitor of Master.

(14) Using jumpers engage Logic level at DPin-2 to 7 (PD2 - PD7) of Slave.
(15) Press button K3.
(16) Check that the content of PIND2-PIND7 Register of Slave has correctly appeared on Serial Monitor of Master.

sm30.png

i2c-1xc.png

sm30.png