Protocol options for data exchange between Arduino and ESP8266
Most I2C tutorials made each Arduino a slave and master, but this approach is better, because each Arduino is either a master or a slave (not both) and no switching is needed. That makes things easier.

I2C is better than serial, because you can add more Arduinos in the same bus.

I have implemented I2C between two Arduinos and it's not more complicated that reading/writing to the serial port (which you have already done). And I bet you can generalize your serial port code to work with both serial and I2C comms.

This is my example (just a proof of concept). The slave Arduino controls a some pins, a temp. sensor and a watchdog under orders from the master Arduino. If slave doesn't receive a beat in time, it reset the master Arduino. 

Master code

#include &lt;Wire.h&gt;

#define CMD_SENSOR    1
#define CMD_PIN_ON    2
#define CMD_PIN_OFF   3
#define CMD_LUMEN     4
#define CMD_BEAT      5

const byte SLAVE_ADDRESS = 42;
const byte LED = 13;

char buffer[32];

void setup ()
{
  Serial.begin(9600);
  Serial.println("Master");

  Wire.begin ();

  pinMode (LED, OUTPUT);
  digitalWrite(LED, HIGH);
  delay(1000);
  digitalWrite(LED, LOW);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Serial.println("Send LED on");
  Wire.write (CMD_PIN_ON);
  Wire.write (2);
  Wire.write (10);
  Wire.endTransmission();
  int x = Wire.requestFrom(SLAVE_ADDRESS, 1);
  Serial.print("status=");
  Serial.println(x);
}  // end of setup

void loop ()
{
  Serial.println(".");
  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_SENSOR);
  Wire.endTransmission();
  int x = Wire.requestFrom(SLAVE_ADDRESS, 1);
  Serial.print("Disponibles = ");
  Serial.println(x);
  int temp = (int) Wire.read();
  Serial.println(temp);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_LUMEN);
  Wire.endTransmission();
  Wire.requestFrom(SLAVE_ADDRESS, 2);
  int light = Wire.read() &lt;&lt; 8 | Wire.read();  
  Serial.print("Light=");
  Serial.println(light);

  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write (CMD_BEAT);
  Wire.endTransmission();
  Wire.requestFrom(SLAVE_ADDRESS, 1);

  delay (5000);
}  // end of loop


Slave code

/*
   Esclavo I2C

   Recibe los siguientes comandos
   &lt;- 1° byte -&gt; &lt;- 2° byte -&gt; &lt;- 3° byte -&gt;
   CMD_SENSOR
   CMD_PIN_ON    n° de pin     duracion en segundos
   CMD_PIN_OFF   n° de pin
   CMD_LUMEN
   CMD_BEAT

   Cada comando recibe una respuesta, ya sea el valor pedido
   o un status.
*/
#include &lt;max6675.h&gt;
#include &lt;Wire.h&gt;

typedef struct {
  int pin;
  unsigned long off;
} PIN_PGMA;

/*
   Lista de pines que se pueden activar via CMD_PIN_ON.
*/
#define PIN_LUMEN   A0
#define PIN_LED      2
#define PIN_RESET    3
PIN_PGMA pgma[] = {
  {PIN_LED, 0},
  {PIN_RESET, 0}
};
const int pgmaSize = sizeof(pgma) / sizeof(PIN_PGMA);

#define CMD_SENSOR    1
#define CMD_PIN_ON    2
#define CMD_PIN_OFF   3
#define CMD_LUMEN     4
#define CMD_BEAT      5

#define ST_OK         0
#define ST_BAD_PIN    1
#define ST_TIME_0     2
#define ST_BAD_LEN    3

#define MY_ADDRESS  42

//  Maximo tiempo de espera entre comandos CMD_BEAT. Pasado
//  ese tiempo, se activa el PIN_RESET.
//  En milisegundos.
#define BEAT_INTERVAL 10000
unsigned long lastBeat;
//  Largo del reset en milisegundos.
#define RESET_LENGTH  250
byte cmd = 0;
byte status = 0;

int thermoDO = 11;
int thermoCS = 12;
int thermoCLK = 13;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

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

  pinMode(PIN_LUMEN, INPUT);
  analogRead(PIN_LUMEN);

  for (int i = 0; i &lt; pgmaSize; i++) {
    pinMode(pgma[i].pin, OUTPUT);
    digitalWrite(pgma[i].pin, LOW);
  }
  lastBeat = millis();

  Wire.begin (MY_ADDRESS);
  Wire.onReceive (receiveCommand);
  Wire.onRequest (sendAnswer);
} 

void loop()
{
  unsigned long now = millis();

  //  Baja la linea de RESET si no ha recibido un beat ultimamente.
  unsigned long diff = now - lastBeat;
  if (diff &gt; BEAT_INTERVAL) {
    resetPin();
  }

  //  Recorre la lista de pines y apaga aquellos cuyo tiempo termino.
  for (int i = 0; i &lt; pgmaSize; i++) {
    if (pgma[i].off &gt; 0 &amp;&amp; pgma[i].off &lt;= now) {
      Serial.print("off pin="); Serial.println(pgma[i].pin);
      pgma[i].off = 0;
      digitalWrite(pgma[i].pin, LOW);
    }
  }
}

// called by interrupt service routine when outgoing data is requested
void sendAnswer() {
  byte temp;
  int  lightReading;

  switch (cmd) {
    case CMD_SENSOR:
      temp = thermocouple.readCelsius();
      Wire.write(temp);
      break;
    case CMD_LUMEN:
      lightReading  = analogRead(PIN_LUMEN);
      Wire.write(lightReading &gt;&gt; 8);
      Wire.write(lightReading % 0xFF);
      break;
    case CMD_PIN_ON:
    case CMD_PIN_OFF:
    case CMD_BEAT:
      Wire.write(status);
      status = ST_OK;
      break;
  }
  cmd = 0;
}

// called by interrupt service routine when incoming data arrives
void receiveCommand (int howMany) {
  cmd = Wire.read ();
  status = ST_OK;
  switch (cmd) {
    case CMD_PIN_ON:
      cmdPinOn();;
      break;
    case CMD_PIN_OFF:
      cmdPinOff();
      break;
    case CMD_BEAT:
      lastBeat = millis();
      break;
  }
}  // end of receiveEvent

void cmdPinOff() {
  if (Wire.available() != 1) {
    status = ST_BAD_LEN;
  } else {
    int pin = Wire.read();
    int i = searchPin(pin);
    if (i &lt; 0) {
      status = ST_BAD_PIN;
    }
    else {
      pgma[i].off = 0;
      digitalWrite(pin, LOW);
    }
  }
}

int searchPin(int pin) {
  int i = pgmaSize - 1;
  while (i &gt;= 0 &amp;&amp; pgma[i].pin != pin) {
    i--;
  }
  return i;
}

/*
 * Programa el encendido y duracion del RESET.
 */
void resetPin() {  
  if (digitalRead(PIN_RESET) == LOW) {
    unsigned long now = millis();

    int i = searchPin(PIN_RESET);

    pgma[i].off = now + RESET_LENGTH;
    lastBeat = now;
    digitalWrite(PIN_RESET, HIGH);
  }
}

void cmdPinOn() {
  if (Wire.available() != 2) {
    status = ST_BAD_LEN;
  } else {
    int pin = Wire.read();
    int len = Wire.read();

    int i = searchPin(pin);
    Serial.print("pin="); Serial.print(pin); Serial.print(",index="); Serial.println(i);
    if (i &lt; 0) {
      status = ST_BAD_PIN;
      Serial.println("bad pin");
    } else {
      if (len == 0) {
        status = ST_TIME_0;
        Serial.println("ban len");
      }
      else {
        pgma[i].off = millis() + len * 1000;
        digitalWrite(pin, HIGH);
        Serial.println("ok");
      }
    }
  }
}