I2C Scanner Using ESP32 IDF


Introduction

I2C (Inter-Integrated Circuit) is a common serial communication protocol used to connect microcontrollers and various peripherals. In I2C communication, there is a master device and one or more slave devices. Each slave device has a unique 7-bit or 10-bit address, and the master device selects the slave device to communicate with by sending this address.

Working Principle

The I2C scanner works by trying to communicate with all possible I2C addresses to identify slave devices present on the BUS. Specifically, the master attempts to send a "start condition" and a "stop condition" to every possible address and checks whether the slave device answers. If the slave answers, it means there is a device at that address.

Install VSCode & ESP-IDF VSCode Extension

Make sure you have installed and configured the ESP-IDF development environment. You can also refer to the article the ESP32 Tutorial – ESP-IDF With VSCode.

Create A New ESP32 Project

We can use VSCode's IDF plug-in to create a new ESP32 project. Please refer to ESP32 Tutorial – How To Create An ESP32 Project With VSCode.

Implemented Using ESP32 IDF

The following is a scanner program written using ESP32 IDF I2C, as shown below...

Program Description

1. i2c_master_init:
This code configures the SDA and SCL pins of the I2C master, the I2C clock frequency (100kHz), and installs the I2C driver.

The i2c_param_config function is used to set I2C parameters.

The i2c_driver_install function is used to install the I2C driver.

2. i2c_scanner:
This code loops through all possible I2C addresses (1 to 127). For each address, the master attempts I2C communication once. If the communication is successful (i.e. a reply from the slave is received), it means there is a device at that address.

Use i2c_cmd_link_create to create the I2C command chain and send the command via i2c_master_cmd_begin.

If communication is successful (ESP_OK), the discovered device address is printed.

3. Main program (app_main):
Initialize the I2C and run the scanner function.

Compile, Flash & Monitor

Find the "ESP32-IDF: Build, Flash and Monitor" ICON in VSCode to execute and burn.

Results

If there is no problem connecting the I2C device, we can check the printing results on the terminal, and the results will be as follows...
Scanning I2C bus...
Found device at address 0x3C
Found device at address 0x68
I2C scan complete.

I2C Scanner Program Description

When you run this I2C scanner program on ESP32, there are two main results, depending on whether there is an I2C device connected to the BUS.

1. If there is an I2C device connected to the BUS
When at least one device is connected to the I2C BUS, the scanner attempts to communicate with each address. Whenever it successfully communicates with an address and receives a reply from the device, it outputs the device's I2C address. The output might look like this:
Scanning I2C bus...
Found device at address 0x3C
Found device at address 0x68
I2C scan complete.
Scanning I2C bus...: Indicates that I2C scanning has started.
Found device at address 0x3C and Found device at address 0x68: These lines indicate that an I2C device was detected at address 0x3C and 0x68 respectively. Each address corresponds to an I2C slave connected to the BUS.
I2C scan complete.: Indicates that the scan has been completed.
2. If no I2C device is connected to the BUS
When no device is connected to the I2C BUS, the scanner still attempts to communicate with every possible address. However, the scanner does not detect any device addresses because no device answers. The output will look like this:
Scanning I2C bus...
I2C scan complete.
Scanning I2C bus...: Indicates that I2C scanning has started.
I2C scan complete.: Indicates that the scan has been completed.

Question

There is no other output between these two lines, which means that the device was not detected at all addresses within the scan range. This situation may occur under the following circumstances:
1. No device connected: There is no device on the I2C BUS physically connected to the ESP32.

2. Device wiring problem: The SDA or SCL line of the I2C device is not connected correctly, or the wiring is loose.

3. Power supply problem of the device: The I2C device is not powered or has insufficient power, resulting in the inability to answer I2C communication.

4. Address conflict or configuration error: The device address is set incorrectly or there is an address conflict, causing the scanner to be unable to communicate with the device.

5. Device does not support high frequency: Different I2C devices have different upper clock speeds. Some devices may only support standard mode (100 kHz) or fast mode (400 kHz). If the master's I2C clock frequency is set beyond the range supported by the slave, for example to 1 MHz or higher, the slave may not respond to communications properly, causing the scanner to fail to detect the device.

6. Pull-up Resistors are not suitable: In I2C communication, the SDA and SCL lines usually require pull-up resistors to ensure that the signal line can correctly return from low level to high level. When the frequency increases, if the value of the pull-up resistor is too large, the line may not be pulled up correctly during the clock cycle, causing signal problems and affecting communication stability.

Conclusion

The I2C scanner may not be able to scan the device at too high a frequency. This is mainly due to issues such as the upper frequency limit supported by the device, signal integrity, and the setting of the pull-up resistor. By reducing the I2C clock frequency and checking the hardware settings, you can improve the scan success rate and ensure that all connected I2C devices are detected.