NodeMCU I2C with ESPlorer IDE

Introduction

I2C (Inter-Integrated Circuit) is a 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 an acknowledgment-based communication protocol i.e. transmitter waits for an acknowledgment from the receiver after transmitting data to know whether data is received by the receiver successfully.

I2Cworks in two modes namely,

  • Master mode
  • Slave mode

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

The master device initiates communication with the slave device. The master device requires a slave device address to initiate a conversation with the slave device. The slave device responds to the master device when it is addressed by the 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.

NodeMCU I2C functions

Let’s see the functions that are available to use with the I2C interface in NodeMCU.

i2c.setup()

This function is used to Initialize the I2C module.

Syntax: i2c.setup(id, SDApin, SCLpin, speed)

Parameters:

id: always 0

SDApin: 1 to 12, IO index

SCLpin: 1 to 12, IO index

speed: i2c.SLOW supported. It is around 100KHz

Returns: it returns the SCL clock speed which is selected in parameters.

 

i2c.address()

This function is used to set up an I2C address and read/write operation mode.

Syntax: i2c.address(id, device_addr, direction)

Parameters:

id: always 0

device_addr: 7-bit slave device address. The I2C device address is the upper 7 bits followed by a single direction (read/write) bit.

direction: i2c.TRANSMITTER for writing mode, i2c. RECEIVER for reading mode

Returns: true if ack (acknowledgment) received, false if no ack received.

 

i2c.start()

This function is used to send an I2C start condition.

Syntax:i2c.start(id)

Parameters:

id: always 0

Returns: null

 

i2c.write()

This function is used to write data on the I2C bus. Data items can be multiple numbers, strings, or Lua tables.

Syntax: i2c.write(id, data1[, data2[, ..., datan]])

Parameters:

id: always 0

data: data can be numbers, string, or Lua table.

Returns: It returns the number of bytes written.

 

i2c.read()

This function is used to read data.

Syntax: i2c.read(id, len)

Parameters:

id: always 0

len: length i.e. number of data bytes

Returns: a string of received data

 

i2c.stop()

This function is used to send an I²C stop condition.

Syntax: i2c.stop(id)

Parameters:

id: always 0

Returns: null

 

Example

Let’s write Lua script for establishing communication between NodeMCU and Arduino Uno using I2C protocol.

Here, NodeMCU acts as an I2C master whereas Arduino Uno will act as a slave device.

The master device will send a hello string to the slave device and the slave device will send a hello string in response to the master device.

Here, we are using

Master Device: NodeMCU

Slave Device: Arduino Uno

Slave Device Address: 8

The interfacing diagram is shown in the below figure

NodeMCU and Arduino I2C Interface

NodeMCU and Arduino I2C Interface

 

Lua Script for NodeMCU (Master I2C Device)

id  = 0 -- always 0
sda = 1 -- set pin 1 as sda
scl = 2 -- set pin 2 as scl

i2c.setup(id, sda, scl, i2c.SLOW)   -- initialize i2c

i2c.start(id)       -- send start condition
if (i2c.address(id, 8, i2c.TRANSMITTER))-- set slave address and transmit direction
then
    i2c.write(id, 'Hello Arduino')  -- write string to slave arduino
    i2c.stop(id)    -- send stop condition
    i2c.start(id)   -- send start condition
    i2c.address(id, 8, i2c.RECEIVER)-- set slave address and receive direction
    response = i2c.read(id, 13)     -- read defined length response from slave
    i2c.stop(id)    -- send stop condition
print('Arduino responds with:',response) -- print response received from slave
else
print('Arduino Not responding..!')
end

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 the serial monitor at Slave device (Arduino Uno)

Arduino Output Window

Output window of the serial monitor at Master device (NodeMCU)

NodeMCU Output Window

 

 


Components Used

NodeMCU
NodeMCUNodeMCU
1
ESP12F
ESP12E
1

Downloads

ESP8266 Datasheet Download
NodeMCU Arduino Project file for I2C Download
Ad