The code provided demonstrates the usage of the I2C (Inter-Integrated Circuit) protocol on an ESP8266 NodeMCU module. I2C is a popular serial communication protocol used to connect multiple peripherals with a microcontroller or a microprocessor. In this context, the code initializes the I2C interface on the NodeMCU module and showcases how to read data from a specific register of an I2C device.
Contents
Pr-Request to Lean
- Embedded Protocol I2C : https://aruneworld.com/embedded/embedded-protocol/i2c/
ESP8266 I2C Core
ESP8266 hardware supports only one i2c. But in bit-banking(Bar Metal code) method you can use all your gpio pin as i2c pins. ESP8266 NodeMCU firmware platform supports only standard speed mode (Sm) 100khz . That means ESP8266 NodeMCU firmware supports 100Kbps for data transfer.
ESP8266 I2C Scanner
- Required NodeMCU Modules (Firmware) : GPIO Module, I2C Module
- Required hardware : ESP8266 with Programmer (or) NodeMCU Dev Kit
- Required software tools : ESPlorer IDE Tool
Code
This script helps identify I2C devices connected to the ESP8266 NodeMCU board by scanning through all possible device addresses and checking for responses. It’s useful for troubleshooting and verifying the connectivity of I2C devices in the system.
lua -- https://www.aruneworld.com/embedded/espressif/esp8266/esp8266_nodemcu/ -- Tested By: Arun(20170112) -- Example Name: AEW_I2C_DeviceScaner.lua ---------------------------------------- -- Setup local id = 0 -- always 0 local pinSDA = 2 -- 1~12, IO index local pinSCL = 1 -- 1~12, IO index local speed = i2c.SLOW -- only i2c.SLOW supported -- Initialize i2c.setup(id, pinSDA, pinSCL, speed) -- Initialize the I²C module. print("Scanning Started....") for count = 0, 127 do i2c.start(id) -- Send an I²C start condition. local Status = i2c.address(id, count, i2c.TRANSMITTER) -- Setup I²C address and read/write mode for the next transfer. i2c.stop(id) -- Send an I²C stop condition. if Status == true then print("Addrss - " .. count .. " Detected device address is 0x" .. string.format("%02x", count) .. " (" .. count .. ")") elseif Status == false then print("Addrss - " .. count .. " nil") end end print("Scanning End")
Explanation
This Lua script is designed to scan for I2C devices connected to an ESP8266 NodeMCU board. Here’s a breakdown of its functionality:
Setup:
- It initializes the variables
id
,pinSDA
,pinSCL
, andspeed
. id
is set to 0, which typically refers to the first I2C interface on ESP8266 NodeMCU.pinSDA
andpinSCL
are set to the GPIO pins used for SDA (data line) and SCL (clock line), respectively.speed
is set toi2c.SLOW
, indicating the desired speed for I2C communication.
Initialization:
- It initializes the I2C module using
i2c.setup()
with the specifiedid
,pinSDA
,pinSCL
, andspeed
.
Scanning for Devices:
- It iterates through possible device addresses from 0 to 127.
- For each address, it attempts to establish communication with the device by sending a start condition (
i2c.start()
), setting the address (i2c.address()
), and then stopping the communication (i2c.stop()
). - If communication is successful (
Status == true
), it prints the detected device address in hexadecimal and decimal format. - If communication fails (
Status == false
), it prints “nil” for that address.
Printing Results:
- It prints “Scanning Started….” before starting the scanning loop.
- It prints “Scanning End” after the scanning loop is complete.
This table breaks down the code into its key components, making it easier to understand the flow and purpose of each part of the script.
Line | Explanation |
---|---|
1-4 | Introduction and setup of necessary variables and constants. |
6 | Initialization of the I2C module with specified parameters. |
8-15 | Loop to iterate through possible device addresses (0 to 127). |
10 | Start condition for I2C communication. |
11 | Attempt to set the address and read/write mode for the next transfer. |
12 | Stop condition for I2C communication. |
13-15 | Check if the status of the communication is successful and print the detected device address. |
17 | Print “Scanning Started….” to indicate the beginning of the scanning process. |
18-21 | Loop to scan through all possible device addresses and attempt communication. |
22-25 | Print “Scanning End” to indicate the completion of the scanning process. |
ESP8266 I2C Example
Code
id = 0 sda = 1 scl = 2 -- Initialize I2C, set pin1 as SDA, set pin2 as SCL i2c.setup(id, sda, scl, i2c.SLOW) -- User-defined function: Read from reg_addr content of dev_addr function read_reg(dev_addr, reg_addr) i2c.start(id) i2c.address(id, dev_addr, i2c.TRANSMITTER) i2c.write(id, reg_addr) i2c.stop(id) i2c.start(id) i2c.address(id, dev_addr, i2c.RECEIVER) c = i2c.read(id, 1) i2c.stop(id) return c end -- Get content of register 0xAA of device 0x77 reg = read_reg(0x77, 0xAA) print(string.byte(reg))
Code Explanation
This code sets up an I2C interface, defines a function to read data from a specific register of an I2C device, and then uses this function to read the content of a specific register from a specific device address.
Line(s) | Explanation |
---|---|
1-3 | Define the I2C interface parameters: id for the I2C bus, sda for the data line, and scl for the clock line. |
5 | Initialize the I2C communication with the specified parameters (I2C bus, SDA pin, SCL pin, and speed). |
8-16 | Define a custom function read_reg to read data from a specified register address of a given device address. |
9-11 | Start the I2C communication and address the device in write mode to specify the register to read from. |
12 | Write the register address to the device. |
13 | Stop the I2C communication after writing the register address. |
14-16 | Restart the I2C communication, address the device in read mode, read one byte of data from the device, and then stop the I2C communication. |
17-19 | Call the read_reg function to read the content of register 0xAA from device address 0x77. |
20 | Print the byte value of the register content returned by the read_reg function. |
See Also
- ESP32 NodeMCU Module – I2C : https://aruneworld.com/embedded/esp32/esp32-nodemcu/esp32-nodemcu-module-i2c/