Kendziorra - ESP8266 I²C with Arduino Multi Masters
Last Arduino/ESP8266 project (click to open)

User Rating: 4 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Inactive
 

Article Index


ESP8266 as Master
Arduino #1, Arduino #2, Arduino #n all as Multi Masters (for ESP8266 all only as Slave)

(click thumbnail)
Demo setup I²C bus: ESP8266 Master with two Arduinos Multi Masters

 Amica NodeMCU V2 DEVKIT with ESP8266-12E and the ESP8266-01
(Less pins as Arduino but with the I2C bus you can mount a whole series of Arduino's ;-)



ESP8266 and Arduino(s) - I²C versus Serial:
ESP8266 Communications with one Arduino? You can use HardwareSerial or SoftwareSerial, but upload and debug is a bit tricky.
ESP8266 Communications with one, or more than one, Arduino? You can use I²C or other standard I/O. With I²C you can connect multiple devices with only two pins/wires, and... with I²C you can use it in Multi Masters mode ;-) However, Arduino-ESP8266 I²C Slave mode is NOT yet implemented :-(
The I²C buffer is in comparison with Serial smal, but if necessary you can increase it.
File ESP8266: <drive>:\Users\<user>\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\<version>\libraries\Wire\Wire.h
#define BUFFER_LENGTH 32
File Arduino: <drive>:\<pathToArduino>\Arduino\hardware\arduino\avr\libraries\Wire\Wire.h
#define BUFFER_LENGTH 32
So with I²C: Every device can easily communicate with each other device using only two bidirectional lines.

I²C bus 3.3V ↔ 5V:
5V Arduino? Use a 3.3V↔5V 'Bi-Directional Level Converter' to save your ESP8266.
(NOT: TXI→TXO - RXO←RXI     BUT:  HV1↔HV2 - LV1↔LV2)

Pull-up resistors:
Use on each I²C signal line one pull-up resistor!
If using a 'Bi-Directional Level Converter' then on both sides one set resistors.

Multi Masters:
Master to Slave is simple: The Master ask and the Slave obeyed. But the slave can not independently send a message and have to wait for a call from Master.
Master to Master is also simple (provided that Multi Masters is implemented): The called Master is then Slave. The Multi Masters can communicate with each other on the same level.

Slave to ESP8266:
Unfortunately, Multi Masters is not yet implemented but in the ESP8266 loop() function you can test all Slaves if there is data ready.

Demo sketches on the next three pages.


ESP8266:

#include <Wire.h>

const byte arduino_1 = 1;  // Arduino as Slave #1
const byte arduino_2 = 2;  // Arduino as Slave #2

void setup() {
  Serial.begin(115200);  
  Wire.begin();  // init as master
  delay(1000);
}

void loop() {
  // WRITE Arduino Slave #1
  Wire.beginTransmission(arduino_1);
  Wire.write("Hi Arduino #1, i am ESP");
  Wire.endTransmission();   
  //-----------------------
  // WRITE Arduino Slave #2
  Wire.beginTransmission(arduino_2);
  Wire.write("Hi Arduino #2, i am ESP");
  Wire.endTransmission();   
  //-----------------------
  // READ Arduino Slave #1
  String inBuf1 = "";
  Wire.requestFrom(arduino_1, 32, 1); // max 32 bytes
  while (Wire.available()) { 
    int c = Wire.read(); 
    if (c >= 32 && c <= 126) inBuf1 += (char)c;  
  }
  if (inBuf1 != "" ) Serial.println(inBuf1);  
  //-----------------------
  // READ Arduino Slave #2
  String inBuf2 = "";
  Wire.requestFrom(arduino_2, 32, 1); // max 32 bytes
  while (Wire.available()) { 
    int c = Wire.read(); 
    if (c >= 32 && c <= 126) inBuf2 += (char)c;  
  }
  if (inBuf2 != "" ) Serial.println(inBuf2);
  //-----------------------
  delay(1000);
}

Arduino Master/Slave #1:

#include <Wire.h>

// ESP has no slave function :(
const byte arduino_Me = 1; // Arduino Multi-Master/Slave #1, that's me!
const byte arduino_2 = 2; // Arduino Multi-Master/Slave #2, that is the other boss

char* msg = " "; // Master ESP message

void setup() {
  Serial.begin(115200);
  Wire.onRequest(requestEvent); // for all Masters
  Wire.onReceive(receiveEvent); // for all Masters
  Wire.begin(arduino_Me); // init as slave #1
  delay(1000);
}

void loop() {
  // i2c buffer max.32 chars !!
  msg = "Hi ESP, i am Arduino #1"; // set Master ESP message
  Wire.beginTransmission(arduino_2); // send message to Arduino Slave #2 
  Wire.write("Hi Slave #2, i am Arduino #1");
  Wire.endTransmission();
  delay(1000);
}

void requestEvent() { // sent message to Master ESP
  if (msg != "") Wire.write(msg); // max. 32 chars
  msg = ""; // avoid repetition
}

void receiveEvent(int howMany) { // receive messages from all Masters
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
  Serial.println();
}

Arduino Master/Slave #2:

#include <Wire.h>

// ESP has no slave function :(
const byte arduino_1 = 1; // Arduino Multi-Master/Slave #2, that is the other boss
const byte arduino_Me = 2; // Arduino Multi-Master/Slave #1, that's me!

char* msg = " "; // ESP message

void setup() {
  Serial.begin(115200);
  Wire.onRequest(requestEvent); // for all Masters
  Wire.onReceive(receiveEvent); // for all Masters
  Wire.begin(arduino_Me); // init as slave #2
  delay(1000);
}

void loop() {
  // i2c buffer max.32 chars !!
  msg = "Hi ESP, i am Arduino #2"; // set ESP message
  Wire.beginTransmission(arduino_1); // send message to Arduino Slave #1
  Wire.write("Hi Slave #1, i am Arduino #2");
  Wire.endTransmission();
  delay(1000);
}

void requestEvent() { // sent message to Master ESP
  if (msg != "") Wire.write(msg); // max. 32 chars
  msg = ""; // avoid repetition
}

void receiveEvent(int howMany) { // receive messages from all Masters
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
  Serial.println();
}