NodeMCU I2C with Arduino IDE

Introduction

I2C (Inter Integrated Circuit) is serial bus interface connection protocol. It is also called as TWI (two wire interface) since it uses only two wires for communication. Those two wires are SDA (serial data) and SCL (serial clock).

I2C is acknowledgement based communication protocol i.e. transmitter checks for acknowledgement from receiver after transmitting data to know whether data is received by receiver successfully.

I2Cworks in two modes namely,

  • Master mode
  • Slave mode

SDA (serial data) wire is used for data exchange in between master and slave device. SCL (serial clock) is used for synchronous clock in between master and slave device.

Master device initiates communication with slave device. Master device requires slave device address to initiate conversation with slave device. Slave device responds to master device when it is addressed by master device.

NodeMCU has I2C functionality support on its GPIO pins. Due to internal functionality on ESP-12E, we cannot use all its GPIOs for I2C functionality. So, do tests before using any GPIO for I2C applications.

 

Example

Let’s write Arduino sketch for NodeMCU as I2C master device and Arduino sketch for Arduino Uno as I2C slave device. Master device sends hello string to slave device and slave device will send hello string in response to the master device.

Here, we are using

Master Device: NodeMCU

Slave Device: Arduino Uno

Slave Device Address: 8

Interfacing diagram is shown in below figure

NodeMCU Arduino I2C interface

NodeMCU Arduino I2C interface

 

Arduino Sketch for NodeMCU (Master I2C Device)

#include <Wire.h>

void setup() {
 Serial.begin(9600); /* begin serial for debug */
 Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
 Wire.beginTransmission(8); /* begin with device address 8 */
 Wire.write("Hello Arduino");  /* sends hello string */
 Wire.endTransmission();    /* stop transmitting */

 Wire.requestFrom(8, 13); /* request & read data of size 13 from slave */
 while(Wire.available()){
    char c = Wire.read();
  Serial.print(c);
 }
 Serial.println();
 delay(1000);
}

Arduino Sketch for Arduino Uno (Slave I2C Device)

#include <Wire.h>

void setup() {
 Wire.begin(8);                /* join i2c bus with address 8 */
 Wire.onReceive(receiveEvent); /* register receive event */
 Wire.onRequest(requestEvent); /* register request event */
 Serial.begin(9600);           /* start serial for debug */
}

void loop() {
 delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(inthowMany) {
 while (0 <Wire.available()) {
    char c = Wire.read();      /* receive byte as a character */
    Serial.print(c);           /* print the character */
  }
 Serial.println();             /* to newline */
}

// function that executes whenever data is requested from master
void requestEvent() {
 Wire.write("Hello NodeMCU");  /*send string on request */
}

Output Window

Output window of serial monitor at Slave device (Arduino Uno)

Arduino Slave output window

Output window of serial monitor at Master device (NodeMCU)

Arduino output window of NodeMCU I2C master

 


Supporting Files

Source Code
Attached File

Comments

pic

daniloespinoza96

12 Nov 2017

Hello, i am doing my thesis right now, and i use something similar to this, but instead of being the NodeMCU the master i would prefer the Arduino to be the master, what shouls i change to make it possibe?
Thanks Beforehand,
Sirius~

lokeshc

13 Nov 2017

@Danilo Espinoza: I did not try any I2C slave sample for NodeMCU. On their official git page
https://github.com/esp8266/Arduino/issues/1330
the issue is mentioned about support for I2C slave mode in esp8266.
But it can possible to try with software I2C implementation.

I have not tried yet for software I2C but I will try for the same and share when it get done.

If you get it done please do share with me. It will help me too.

pic

terc1971

24 Nov 2017

Hello,
Please help me with one issue: Arduino Uno/Mega uses 5V while Nodemcu board uses 3.3V. Why you did not use a bi-directional level converter? Is there any chance to damage the Nodemcu without level converter?
I am asking you because I tried to use the level converter and the boards did not find each other on I2C...but it works perfect without level converter.
Thanks,
Eugen

lokeshc

30 Nov 2017

@EUGEN TERCHILA: NodeMCU board (ESP8266 based module) has IO pins which are 5V tolerant mentioned in the official datasheet of ESP8266. So there is no need for a level converter to use I2C pins of NodeMCU board which is also 5V tolerant.