ESP-IDF: How to scan I2C devices
The following function allows you to scan I2C devices on a ESP-IDF I2C bus. The result will be printed on the configured console.
#include <driver/i2c.h>
void scan_i2c(i2c_port_t port) {
printf("Scanning I2C bus on port %d...\n", port);
int devices_found = 0;
esp_err_t ret;
for (uint8_t address = 1; address < 127; address++) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(port, cmd, 50 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_OK) {
printf("I2C device found at address 0x%02X\n", address);
devices_found++;
} else if (ret != ESP_FAIL) { /* Slave has not ACKd the transfer*/
printf("Error at address 0x%02X, error: %s\n", address, esp_err_to_name(ret));
}
// Small delay between scans
vTaskDelay(5 / portTICK_PERIOD_MS);
}
if (devices_found == 0) {
printf("No I2C devices found\n");
} else {
printf("Scan complete, %d device(s) found\n", devices_found);
}
}
Prerequisites
You need to initialize the I2C bus before calling this function. Here is an example of how to do that:
#include <driver/i2c.h>
constexpr int Pin_I2C_SCL = 14;
constexpr int Pin_I2C_SDA = 13;
extern "C" void app_main()
{
// Setup I2C port 0 on the GPIOs
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = Pin_I2C_SDA,
.scl_io_num = Pin_I2C_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 400000
},
};
i2c_param_config(I2C_NUM_0, &conf);
i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0);
while(true) {
scan_i2c(I2C_NUM_0);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
Example output
Scanning I2C bus on port 0...
I2C device found at address 0x70
Scan complete, 1 device(s) found
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow