// I2C master
#include <Wire.h>

// Slave address
uint8_t SLAVE_ADDRESS = 0x33; 

// Buffers for sending and receiving
uint8_t masterTxData[3] = {0x30, 0x41, 0x51};
uint8_t masterRxData[4] = {0};

// Function for sending data via I2C bus
uint8_t masterSendData(uint8_t* data, uint8_t dataLen)
{
  // Initiating work with the bus
  Wire.beginTransmission(SLAVE_ADDRESS);
  // Send data
  Wire.write(data, dataLen);
  // Finish working with the bus and return the result
  return Wire.endTransmission();
}

// Function to receive a specified number of bytes from the I2C bus
uint8_t masterGetData(uint8_t *buf, uint8_t dataSize)
{
  // Request data
  Wire.requestFrom(SLAVE_ADDRESS, dataSize);
  // If there are bytes available for reading, read them in a loop
  uint8_t n = 0;
  while (Wire.available()) 
  {
    // reading from the bus - from the slave device
    buf[n] = Wire.read();
    // Increasing the number of received bytes
    n++;
  }
  // Return the number of received bytes 
  return n;
}


// -------------------------------------------- //

void setup() 
{  
  Serial.begin(57600);
  while (!Serial);
  Serial.println("I2C master start");  

  // Initialize the device on the I2C bus as a master
  Wire.begin(); 
}

void loop() 
{
  // Send data to slave
  Serial.println("------------------------");
  Serial.println("Master | Sending 3 bytes");
  uint8_t result = masterSendData(masterTxData, sizeof(masterTxData));
  // Show result
  if (result == 0)
    Serial.println("Master | Bytes sended");
  else
  {
    Serial.print("Master | Send ERROR! Code: ");
    Serial.println(result);
  }
  // Change the first byte for variety
  masterTxData[0] += 1; 
  // Delay before requesting data
  delay(2000);
  

  // Request data from the slave
  Serial.println("------------------------");
  Serial.println("Master | Receiving 4 bytes");
  uint8_t bytesQty = masterGetData(masterRxData, sizeof(masterRxData));
  // Show result
  if (bytesQty == 0)
    Serial.println("Master | Receive ERROR!");
  else
  {
    for (uint8_t i = 0; i < bytesQty; i++)
    {
      Serial.print("Master | Received byte: 0x");
      Serial.println(masterRxData[i], HEX);
    }
  }
  // Delay before sending data
  delay(2000);
}
 
