I2C
The I2C class provides a simple interface to the I2C bus. It is a wrapper around the esp-idf I2C driver.
A helper I2cMenu is also provided which can be used to interactively test I2C buses - scanning the bus, probing devices, reading and writing to devices.
API Reference
Header File
Classes
-
class I2c : public espp::BaseComponent
I2C driver.
This class is a wrapper around the ESP-IDF I2C driver.
Example
espp::I2c i2c({ .port = I2C_NUM_0, .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO, .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, }); // probe the bus for all addresses and store the ones that were found / // responded. NOTE: this will take a while to run, as it will probe all 128 // possible addresses and the hard-coded timeout on the I2C (inside ESP-IDF) // is 1 second (I2C_CMD_ALIVE_INTERVAL_TICK within // esp-idf/components/driver/i2c/i2c.c). std::vector<uint8_t> found_addresses; for (uint8_t address = 0; address < 128; address++) { if (i2c.probe_device(address)) { found_addresses.push_back(address); } } // print out the addresses that were found logger.info("Found devices at addresses: {::#02x}", found_addresses); static constexpr uint8_t device_address = CONFIG_EXAMPLE_I2C_DEVICE_ADDR; static constexpr uint8_t register_address = CONFIG_EXAMPLE_I2C_DEVICE_REG_ADDR; bool device_found = i2c.probe_device(device_address); if (device_found) { logger.info("Found device with address {:#02x}", device_address); std::vector<uint8_t> read_data(CONFIG_EXAMPLE_I2C_DEVICE_REG_SIZE, 0); bool success = i2c.read_at_register(device_address, register_address, read_data.data(), read_data.size()); if (success) { logger.info("read data: {::#02x}", read_data); } else { logger.error("read failed"); } } else { logger.error("Could not find device with address {:#02x}", device_address); }
Public Functions
-
inline explicit I2c(const Config &config)
Construct I2C driver
- Parameters
config – Configuration for I2C
-
inline ~I2c()
Destructor.
-
inline void init(std::error_code &ec)
Initialize I2C driver.
-
inline void deinit(std::error_code &ec)
Deinitialize I2C driver.
-
inline bool write(const uint8_t dev_addr, const uint8_t *data, const size_t data_len)
Write data to I2C device
- Parameters
dev_addr – I2C device address
data – Data to write
data_len – Length of data to write
- Returns
True if successful
-
inline bool write_vector(const uint8_t dev_addr, const std::vector<uint8_t> &data)
Write data to I2C device
- Parameters
dev_addr – I2C device address
data – Data to write
- Returns
True if successful
-
inline bool write_read(const uint8_t dev_addr, const uint8_t *write_data, const size_t write_size, uint8_t *read_data, size_t read_size)
Write to and read data from I2C device
- Parameters
dev_addr – I2C device address
write_data – Data to write
write_size – Length of data to write
read_data – Data to read
read_size – Length of data to read
- Returns
True if successful
-
inline bool write_read_vector(const uint8_t dev_addr, const std::vector<uint8_t> &write_data, std::vector<uint8_t> &read_data)
Write data to and read data from I2C device
- Parameters
dev_addr – I2C device address
write_data – Data to write
read_data – Data to read
- Returns
True if successful
-
inline bool read_at_register(const uint8_t dev_addr, const uint8_t reg_addr, uint8_t *data, size_t data_len)
Read data from I2C device at register
- Parameters
dev_addr – I2C device address
reg_addr – Register address
data – Data to read
data_len – Length of data to read
- Returns
True if successful
-
inline bool read_at_register_vector(const uint8_t dev_addr, const uint8_t reg_addr, std::vector<uint8_t> &data)
Read data from I2C device at register
- Parameters
dev_addr – I2C device address
reg_addr – Register address
data – Data to read
- Returns
True if successful
-
inline bool read(const uint8_t dev_addr, uint8_t *data, size_t data_len)
Read data from I2C device
- Parameters
dev_addr – I2C device address
data – Data to read
data_len – Length of data to read
- Returns
True if successful
-
inline bool read_vector(const uint8_t dev_addr, std::vector<uint8_t> &data)
Read data from I2C device
- Parameters
dev_addr – I2C device address
data – Data to read
- Returns
True if successful
-
inline bool probe_device(const uint8_t dev_addr)
Probe I2C device
This function sends a start condition, writes the device address, and then sends a stop condition. If the device acknowledges the address, then it is present on the bus.
- Parameters
dev_addr – I2C device address
- Returns
True if successful
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
-
struct Config
Configuration for I2C.
Public Members
-
int isr_core_id = -1
The core to install the I2C interrupt on. If -1, then the I2C interrupt is installed on the core that this constructor is called on. If 0 or 1, then the I2C interrupt is installed on the specified core.
-
i2c_port_t port = I2C_NUM_0
I2C port.
-
gpio_num_t sda_io_num = GPIO_NUM_NC
SDA pin.
-
gpio_num_t scl_io_num = GPIO_NUM_NC
SCL pin.
-
gpio_pullup_t sda_pullup_en = GPIO_PULLUP_DISABLE
SDA pullup.
-
gpio_pullup_t scl_pullup_en = GPIO_PULLUP_DISABLE
SCL pullup.
-
uint32_t timeout_ms = 10
I2C timeout in milliseconds.
-
uint32_t clk_speed = 400 * 1000
I2C clock speed in hertz.
-
bool auto_init = true
Automatically initialize I2C on construction.
-
int isr_core_id = -1
-
inline explicit I2c(const Config &config)
Header File
Classes
-
class I2cMenu
A CLI menu for interacting with an I2c bus.
This class provides a CLI menu for interacting with an I2c bus. It provides options for setting the log verbosity, scanning the bus for devices, probing for a device at a specific address, reading from a device, and writing to a device.
Example
espp::I2c i2c({ .port = I2C_NUM_0, .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO, .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .clk_speed = CONFIG_EXAMPLE_I2C_CLOCK_SPEED_HZ, .log_level = espp::Logger::Verbosity::INFO, }); // now make a menu for it espp::I2cMenu i2c_menu(i2c); cli::Cli cli(i2c_menu.get()); cli::SetColor(); cli.ExitAction([](auto &out) { out << "Goodbye and thanks for all the fish.\n"; }); espp::Cli input(cli); input.SetInputHistorySize(10); input.Start(); // As this is in the primary thread, we hold here until cli // is complete. This is a blocking call and will not return until // the user enters the `exit` command.