I2C
I2C – definition
I2C, also written as I2C or I²C, is a synchronous serial communication bus used to connect integrated circuits over short distances on a printed circuit board or within an embedded system. The name stands for Inter-Integrated Circuit. NXP Semiconductors maintains the I2C-bus specification, including the electrical signaling rules, addressing methods, bus states, and speed modes.
In mobile robotics, I2C is commonly used for low-bandwidth sensors and peripheral devices connected to an onboard computer or microcontroller. Typical devices include IMUs, magnetometers, barometric pressure sensors, real-time clocks, battery-monitoring ICs, GPIO expanders, OLED displays, and environmental sensors. It is not normally used for high-throughput sensors such as LiDARs, RGB-D cameras, or GNSS receivers that stream large data volumes.
An I2C bus uses two shared signal lines:
- SCL – serial clock, generated by the active controller.
- SDA – serial data, used for addressing, commands, and payload bytes.
Both lines use open-drain or open-collector signaling and require pull-up resistors to the logic supply voltage. Devices can pull a line low, but they do not actively drive it high. This electrical model enables multiple devices to share one bus and allows arbitration when more than one controller is present.
How I2C works on a mobile robot
An I2C transaction starts when SDA changes from high to low while SCL is high. The controller then transmits an address, a read/write bit, and, depending on the transaction, one or more register or command bytes and data. A receiving device acknowledges each accepted byte by pulling SDA low during the acknowledgement clock pulse; in a read transaction, the controller normally ends the transfer by not acknowledging the final byte.
The standard defines both 7-bit and 10-bit addressing. In practical robotics integrations, 7-bit addresses are most common. A device address is not the same as a Linux bus number. For example, /dev/i2c-1 identifies a Linux I2C adapter, while an address such as 0x68 identifies a device connected to that adapter.
I2C supports several defined speed modes. The applicable electrical limits and timing parameters are specified in the NXP I2C-bus specification.
| Mode | Maximum clock rate | Typical robotics use |
|---|---|---|
| Standard-mode | 100 kbit/s | Simple peripheral and legacy sensor interfaces |
| Fast-mode | 400 kbit/s | Common IMU, environmental sensor, and GPIO integration |
| Fast-mode Plus | 1 Mbit/s | Higher-rate embedded peripherals where controller and sensor support it |
| High-speed mode | 3.4 Mbit/s | Specialized designs with compatible hardware and layout constraints |
Source: NXP, UM10204 I2C-bus specification and user manual, Rev. 7.0, 2021. The usable rate on a UGV can be lower than the nominal mode rate because of cable capacitance, pull-up resistor values, level shifters, device clock stretching, and operating-system scheduling.
I2C in ROS 2 systems
ROS 2 does not define I2C as a transport layer for ROS messages. I2C operates below ROS 2, usually through a Linux kernel I2C adapter driver and the /dev/i2c-* device interface. A ROS 2 node, hardware interface, or microcontroller firmware reads registers from an I2C device and converts the result into ROS 2 messages.
For an IMU connected through I2C, a driver may publish sensor_msgs/msg/Imu. This message contains orientation, angular velocity, linear acceleration, and covariance arrays. A magnetometer driver can publish sensor_msgs/msg/MagneticField, while a barometric or thermal sensor may publish sensor_msgs/msg/FluidPressure, sensor_msgs/msg/Temperature, or a custom message.
The bus itself provides bytes, addresses, acknowledgements, and timing. It does not provide timestamps, coordinate frames, calibration, covariance, unit conversion, or ROS 2 Quality of Service settings. Those elements must be implemented in the driver and configured in the robot software stack.
# List Linux I2C adapters
i2cdetect -l
# Scan addresses on adapter 1
sudo i2cdetect -y 1
# Read one byte from register 0x75 at device address 0x68
sudo i2cget -y 1 0x68 0x75
These commands use the Linux I2C userspace interface and the i2c-tools utility. Scanning or reading registers can affect devices that implement side effects on access. Such commands should therefore be used only with the sensor datasheet and the target device state in mind.
I2C integration on Leo Rover and Raph Rover
On Leo Rover, I2C is relevant when adding low-level sensors to the Raspberry Pi-based compute unit or to a compatible external microcontroller. Leo Rover can be used with ROS 2, but the supported ROS 2 distribution depends on the installed system image and the available Leo Rover software packages. An I2C sensor does not become available to ROS 2 automatically: the integrator must enable the relevant hardware interface, verify voltage compatibility, install or develop a driver, and publish correctly framed data.
For example, an I2C IMU can provide angular velocity and acceleration data for state estimation. To use it with a differential-drive Leo Rover, the driver should publish a stable sensor frame such as imu_link, while the robot description defines the transform between base_link and that frame. The resulting data can be fused with wheel odometry and other sensors by a ROS 2 state-estimation node.
Raph Rover can use the same integration pattern when its payload requires embedded sensors, power monitoring, or auxiliary I/O. I2C remains appropriate for local peripherals. It should not be selected as the primary interface for high-rate perception payloads used for mapping, visual odometry, or dense computer vision.
Electrical and software limitations
I2C is intended for short-distance board-level communication. Long unshielded cables on a mobile platform can introduce capacitance, electromagnetic interference, ground-reference problems, and clock-edge degradation. These issues are more likely near motor controllers, DC-DC converters, and high-current battery wiring.
Before connecting a sensor, verify the following items against the sensor and compute-unit documentation:
- Logic voltage level, including whether the device accepts 3.3 V signaling.
- Device address and whether another device already uses that address.
- Required pull-up resistors and the total bus capacitance.
- Supported clock rate and clock-stretching behavior.
- Driver output units, frame ID, timestamp source, and ROS 2 message type.
Address conflicts are a common limitation because many sensor boards use fixed or limited address-selection pins. If two required devices share the same address, use an I2C multiplexer, separate bus controller, or a sensor variant with configurable addressing.
Normative references and standards
The primary technical reference for I2C electrical operation is NXP UM10204. ROS 2 interface definitions should be checked against the versioned ROS documentation and message repositories used by the target distribution.
- NXP UM10204, I2C-bus specification and user manual, Rev. 7.0, 2021
- ROS 2 sensor_msgs documentation
- Linux kernel I2C and SMBus subsystem documentation
- Leo Rover technical documentation