Data exchange master slave i2C

Hi,

I have two Arduino Mega boards which one will act as Master and the other as Slave. I want to trigger the Slave to perform a given task by sending a specific integer value, then, the Slave should reply with another value (the integer values may go from 1 up to 3 digits).

I've solved all the communication issues between them and, they are connected through the PINS 20 and 21.

The master sends an integer to the slave correctly, however, I don't know if the slave receives a value (and in the case of receiving one, probably is wrong). The slave knows that a byte has arrived and sends another integer value to the master.

For an initial test, I would like that both master and slave send/receive the same value. Thus, 1) the master sends the value X to the slave 2) the slave reads it, 3) the slave sends the same value to the master and 4) the master reads and prints the received value.

I add the complete code.

Master

const int buttonSel = 50;//button to Select options
const int buttonStart = 53; //button to Start option
const int buttonStop = 52; //button to Stop option
const int Marcia = 32; //Initiates Marcia of the TX module
const int PR17 = 22; //PR17 relay of the TX module
const int PR16 = 24; //PR16 relay of the TX module
const int PR15 = 26; //PR15 relay of the TX module
const int PR27 = 28; //PR27 relay of the TX module
const int PR26 = 30; //PR26 relay of the TX module
const int PR25 = 31; //PR25 relay of the TX module
const int PR11 = 33; //PR11 relay of the TX module
const int PR10 = 34; //PR10 relay of the TX module
const int PR9 = 35; //PR9 relay of the TX module
const int PR5 = 36; //PR5 relay of the TX module
const int PR6 = 37; //PR6 relay of the TX module
const int PR7 = 38; //PR7 relay of the TX module
const int PR23 = 39; //PR23 relay of the TX module
const int PR22 = 40; //PR22 relay of the TX module
const int PR21 = 41; //PR21 relay of the TX module
int programCount = 0;//variable to move through the program
int delay_ = 1000;
int read;
int pass = 0; // integer to indicate if at least one pins doesn't pass 0-OK 1-FAIL
int Error = 0; // integer to indicate that there is an error during the checking 0-NO 1-YES
int x; int y;
const byte SLAVE_ADDRESS = 42;
const byte MY_ADDRESS = 25;

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip

void setup() {
  Wire.begin ();
  lcd.begin(20, 4);
  Serial.begin (9600);
  lcd.setCursor(0, 0);
  programCount = 0;//start at the beginning
  pinMode(buttonSel, INPUT); //set the button as an input
  pinMode(buttonStart, INPUT); //set the button as an input
  pinMode(buttonStop, INPUT); //set the button as an input
  lcd.print("Select");
  Serial.println("CLEARDATA");
  Serial.println("LABEL, Time, Device, Link, Check");
}

void loop()
{
  Wire.beginTransmission (SLAVE_ADDRESS);  
  switch (programCount)
  {
    case 0: // This case option remains the "Select" option idle
      if (digitalRead(buttonSel) == HIGH)
      {
        programCount = 1;
      }
      break;
    case 1:
      static const uint8_t arraypin[] = {PR5, PR6, PR7, PR9, PR10, PR11, PR15, PR16, PR17, PR21, PR22, PR23, PR25, PR26, PR27};     
      x = 15;
      lcd.clear();
      lcd.print("Edilbox");
      delay(delay_);
      if (digitalRead(buttonSel) == HIGH)
      {
        programCount = 2;
      }
      if (digitalRead(buttonStart) == HIGH)
      {
        lcd.clear();
        lcd.print("Start Edilbox");
        digitalWrite(Marcia, LOW);
        delay(2000);
        digitalWrite(Marcia, HIGH);
        for (int i = 0; i < x; i++)
        {
          for (int j = 0; j < x; j++)
          {
            if (i == j)
            {
              digitalWrite(arraypin[j], LOW);
              Wire.write (y = arraypin[j]);
              Serial.println("Transmiting from Master");
              Serial.println(y);
              Wire.requestFrom(42, 1);
              if (Wire.available() != 0)
              {
                delay(1000);
                Serial.println("Receiving from Slave");
                int y = Wire.read();
                Serial.println(y, DEC);
                delay(1000);

              }
            }            
            else
            {
              digitalWrite(arraypin[j], HIGH);
              delay(delay_);
            }
          }
          for (int j = 0; j < x; j++)
          {
            if ((i == j) && (digitalRead(arraypin[j]) == LOW))
            {
              pass = 0;              
              delay(delay_);
            }

            else if ((i != j) && (digitalRead(arraypin[j]) == HIGH))
            {
              pass = 0;
              delay(delay_);
            }
            else if ((i != j) && (digitalRead(arraypin[j]) == LOW))
            {
              pass = 1;
              Error = 1;
              delay(delay_);
            }
            else
            {
              // NOTHING
            }
          }

        }
      }
      if (digitalRead(buttonStop) == HIGH)
      {
        lcd.clear();
        lcd.print("Stop Edilbox");
        digitalWrite(Marcia, LOW);
        delay(delay_);
      }
      break;
    
    case 2:
      lcd.clear();
      lcd.print("R9");//print the number
      delay(delay_);
      if (digitalRead(buttonSel) == HIGH)
      {
        programCount = 3;
      }
      if (digitalRead(buttonStart) == HIGH)
      {
        lcd.clear();
        lcd.print("Start R9");//print the number
        delay(delay_);
      }
      if (digitalRead(buttonStop) == HIGH)
      {
        lcd.clear();
        lcd.print("Stop R9");//print the number
        delay(delay_);
      }
      break;
    
    case 3:
      lcd.clear();
      lcd.print("R7");//print the number
      delay(delay_);
      if (digitalRead(buttonSel) == HIGH)
      {
        programCount = 0;
      }
      if (digitalRead(buttonStart) == HIGH)
      {
        lcd.clear();
        lcd.print("Start R7");//print the number
        delay(delay_);
      }
      if (digitalRead(buttonStop) == HIGH)
      {
        lcd.clear();
        lcd.print("Stop R7");//print the number
        delay(delay_);
      }
      break;
  }
  Wire.endTransmission ();
}

Slave

const int STOP  = 8; //STOP of the RX module
const int CLAX = 9; //CLAX of the RX module
const int START = 10; //START of the RX module
const int LAMP = 11; //LAMP of the RX module
int delay_ = 10000;
int x; int flag = 0; int y;
const byte MY_ADDRESS = 42;
const byte MASTER_ADDRESS = 25;
int LED = 13;
#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip

void setup() {
  Wire.begin (MY_ADDRESS);
  lcd.begin(20, 4);
  Serial.begin (9600);
  lcd.setCursor(0, 0);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
  pinMode(STOP, INPUT); digitalWrite(STOP, HIGH);
  pinMode(CLAX, INPUT); digitalWrite(CLAX, HIGH);
  pinMode(START, INPUT); digitalWrite(START, HIGH);
  pinMode(LAMP, INPUT); digitalWrite(LAMP, HIGH);
}

void loop() {
  delay(delay_);  
  if (Wire.available() != 0)
  {    
    Serial.println("Receiving from M");
    int y = Wire.read();
    Serial.println(y, DEC);
  }
}

void receiveEvent(int howMany) {
  flag = 1;
  int y = Wire.read();
  if (y == 0)
  {
    digitalWrite(LED, HIGH);
  }  
}

void requestEvent() {
  if (flag == 1)
  {    
    Wire.write(y=50);    
    flag = 0;
  }
}

I've tried to modify the received bytes, insert begin transmission at the slave and using different type of values.

Any clue how to exchange a single integer value?

@OP

Please execute these simple codes to check that the Arduinos are exchanging data over the I2C Bus. Once the I2C Bus is found working, add other hardware modules one-by-one and the associated software. This methodology is known as SSS Strategy (Small Start Strategy).

A: Master MEGA-1 Codes

#include <Wire.h>

void setup()
{
  Wire.begin(25);  
  Serial.begin(9600);
  Wire.onReceive(receiveEvent); 

  Wire.beginTransmission(42);
  Wire.write(0x45);   //code 0x45 goes to Slave
  Wire.endTransmission();
}

void loop()
{
  
}

void receiveEvent(int howmany)
{
  byte x = Wire.read();
  Serial.println(x, HEX);  //0x45 getting back from Slave
}

B: Slave NANO/MEGA-2 Codes //I don't have 2 MEGAs

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

void setup()
{
  Wire.begin(42);
  Serial.begin(9600);
  Wire.onReceive(receiveEvent);
}

void loop()
{
  if (flag1 == HIGH)
  {
    Wire.beginTransmission(25);
    Wire.write(x);   //code 0x45 goes to Master
    Wire.endTransmission();
    flag1 = LOW;
  }
}

void receiveEvent(int howmany)
{
  x = Wire.read();
  Serial.println(x, HEX);
  //------------------------
  flag1 = HIGH;

}

@GolamMostafa, thanks. It works. Both the master and the slave receives the hexadecimal value. However, I would like to send a decimal number. How should I modify your codes? If I send 45 (no 0x45) to the slave, it receives 69 instead of 45. I've also changed the println as (x, DEC).

The way (that you have followed) should work. Try by sending 29 (not x29) and then by sending 45 (not x45). They work, any way. In one hand, we are executing Wire.write(29); on the other hand, we are executing Serial.print(x, DEC);; the sense is nullified, and we see 29 on the Serial Monitor. Is this 29 of hex base or decimal base? It depends on the user.

Sender Code:

#include <Wire.h>

void setup()
{
  Wire.begin(25);  
  Serial.begin(9600);
  Wire.onReceive(receiveEvent); 

  Wire.beginTransmission(42);
  Wire.write(29);   //code decimal 29 goes to slave
  Wire.endTransmission();
}

void loop()
{
  
}

void receiveEvent(int howmany)
{
  byte x = Wire.read();
  Serial.println(x, DEC);  //0x45 getting back from Slave
}

Receiver Code:

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

void setup()
{
  Wire.begin(42);
  Serial.begin(9600);
  Wire.onReceive(receiveEvent);
}

void loop()
{
  if (flag1 == HIGH)
  {
    Wire.beginTransmission(25);
    Wire.write(x);   //code decimal 29 goes to Master
    Wire.endTransmission();
    flag1 = LOW;
  }
}

void receiveEvent(int howmany)
{
  x = Wire.read();
  Serial.println(x, DEC);
  //------------------------
  flag1 = HIGH;

}