I2C Pins
Typically you can use any GPIO: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html
To confirm, see the S# series datasheet for the ESP device you are using > Peripheral Pin Configurations
Resources
https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/i2c.html
https://github.com/espressif/esp-idf/tree/master/examples/peripherals/i2c
I2C Address
Set as normal byte address including RW at bit 0.
So 0b01101000 is set as 0x68, not (0x68 >> 1)
I2C Master Example
#include "driver/i2c.h"
#include <string.h> //Required for memset()
#define EXAMPLE_I2C_PORT_NUMBER I2C_NUM_1 //I2C port number
#define EXAMPLE_I2C_SCL_GPIO 16 //GPIO pin
#define EXAMPLE_I2C_SDA_GPIO 17 //GPIO pin
#define EXAMPLE_I2C_FREQ_HZ 100000 //!< I2C master clock frequency
#define EXAMPLE_I2C_ADDR 0x98
#define EXAMPLE_I2C_WRITE_BIT I2C_MASTER_WRITE
#define EXAMPLE_I2C_READ_BIT I2C_MASTER_READ
#define EXAMPLE_I2C_ACK_CHECK_EN 0x1
#define EXAMPLE_I2C_ACK_CHECK_DIS 0x0
#define EXAMPLE_I2C_ACK_VAL 0x0
#define EXAMPLE_I2C_NACK_VAL 0x1
//----- CREATE THE I2C PORT -----
int i2c_master_port = EXAMPLE_I2C_PORT_NUMBER;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = EXAMPLE_I2C_SDA_GPIO;
conf.sda_pullup_en = GPIO_PULLUP_DISABLE;
conf.scl_io_num = EXAMPLE_I2C_SCL_GPIO;
conf.scl_pullup_en = GPIO_PULLUP_DISABLE;
conf.master.clk_speed = EXAMPLE_I2C_FREQ_HZ; //I2C frequency is the clock speed for a complete high low clock sequence
i2c_param_config(i2c_master_port, &conf);
i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0); //(i2c_num, mode, slv_rx_buf_len, slv_tx_buf_len, intr_alloc_flags)
//i2c_driver_install(i2c_port, i2c_config.mode, 0, 0, ESP_INTR_FLAG_LOWMED); //<<< Alternative version using non dedicated level 1 interrupt (if you have issues running out of level 1 interrupts)
esp_err_t i2c_ret = ESP_OK;
uint8_t data_h;
uint8_t data_l;
i2c_cmd_handle_t OurI2cCmdHandle = i2c_cmd_link_create();
//----- WRITE BYTES -----
i2c_master_start(OurI2cCmdHandle);
i2c_master_write_byte(OurI2cCmdHandle, EXAMPLE_I2C_ADDR | EXAMPLE_I2C_WRITE_BIT, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_write_byte(OurI2cCmdHandle, 0x02, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_write_byte(OurI2cCmdHandle, 0x7f, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_stop(OurI2cCmdHandle);
//Send queued commands
i2c_ret = i2c_master_cmd_begin(EXAMPLE_I2C_PORT_NUMBER, OurI2cCmdHandle, (100 / portTICK_PERIOD_MS)); //"(# / portTICK_PERIOD_MS)"=maximum wait time. This task will be blocked until all the commands have been sent (not thread-safe - if you want to use one I2C port in different tasks you need to take care of multi-thread issues)
i2c_cmd_link_delete(OurI2cCmdHandle);
//If you want to know if the device returned NACK:
//if (i2c_ret == ESP_FAIL)
//{
// //NACK returned
//}
if (i2c_ret == ESP_OK)
{
//READ BYTES
printf("I2C Write OK\n");
OurI2cCmdHandle = i2c_cmd_link_create();
i2c_master_start(OurI2cCmdHandle);
i2c_master_write_byte(OurI2cCmdHandle, EXAMPLE_I2C_ADDR | EXAMPLE_I2C_READ_BIT, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_read_byte(OurI2cCmdHandle, &data_h, EXAMPLE_I2C_ACK_VAL);
i2c_master_read_byte(OurI2cCmdHandle, &data_l, EXAMPLE_I2C_NACK_VAL);
i2c_master_stop(OurI2cCmdHandle);
//Send queued commands
i2c_ret = i2c_master_cmd_begin(EXAMPLE_I2C_PORT_NUMBER, OurI2cCmdHandle, 100 / portTICK_PERIOD_MS); //"(# / portTICK_PERIOD_MS)"=maximum wait time. This task will be blocked until all the commands have been sent (not thread-safe - if you want to use one I2C port in different tasks you need to take care of multi-thread issues)
i2c_cmd_link_delete(OurI2cCmdHandle);
}
else
{
printf("I2C FAILED\n");
}
write, restart, read
i2c_cmd_handle_t OurI2cCmdHandle = i2c_cmd_link_create();
//----- WRITE & READ BYTES -----
i2c_master_start(OurI2cCmdHandle);
i2c_master_write_byte(OurI2cCmdHandle, EXAMPLE_I2C_ADDR | EXAMPLE_I2C_WRITE_BIT, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_write_byte(OurI2cCmdHandle, 0x02, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_start(OurI2cCmdHandle);
i2c_master_write_byte(OurI2cCmdHandle, EXAMPLE_I2C_ADDR | EXAMPLE_I2C_READ_BIT, EXAMPLE_I2C_ACK_CHECK_EN);
i2c_master_read_byte(OurI2cCmdHandle, &data_h, EXAMPLE_I2C_ACK_VAL);
i2c_master_read_byte(OurI2cCmdHandle, &data_l, EXAMPLE_I2C_NACK_VAL);
i2c_master_stop(OurI2cCmdHandle);
//Send queued commands
i2c_ret = i2c_master_cmd_begin(EXAMPLE_I2C_PORT_NUMBER, OurI2cCmdHandle, 100 / portTICK_PERIOD_MS); //"(# / portTICK_PERIOD_MS)"=maximum wait time. This task will be blocked until all the commands have been sent (not thread-safe - if you want to use one I2C port in different tasks you need to take care of multi-thread issues)
i2c_cmd_link_delete(OurI2cCmdHandle);

6 years ago
Hi! I am New for esp32. can you brief of how to develop the i2c for reading any sensor data.
5 years ago
Hello vignesh. The example given for the ESP32 reading I2C shows the technique for reading/writing on I2C. Each sensor will have documentation describing its own data details as far as what can or needs to be written or read and when. Once you have a specific sensor in mind, read the documentation and it will give that information.