6. ROS Interface with an I2C Bus

6.1. Checking the I2C bus

Once the device is physically connected to an I2C bus, and before attempting to interface using ROS, you should use the command line tool to check the device is properly connected. See the I2C page for details of the command line tools, and see the single board computers (SBC) page for details of the I2C buses for the relevant SBC.

For example, if the device is connected to the I2C bus of pins (3,5) of the J21 expansion header of the Jetson Xavier NX, then this corresponds to I2C bus 8. Hence the addresses of the connected devices can be quickly checked with the command:

sudo i2cdetect -y -r 8

6.2. ROS templates

To interface with I2C devices via a ROS node, there are two templates provided:

  • The file named i2c_for_motors_and_servos.cpp: this template manages an I2C bus with the Pololu SMC G2 motor controller boards and PCA9685 servo driver board connected.

  • The file named i2c_for_sensors.cpp: this template manages an I2C bus with a time-of-flight distance sensor connected.

Both files are located in the repository at the relative file path:

catkin_ws/src/asclinic_pkg/src/nodes/

Both files are extensively commented and the comments serve as the documentation for how to edit the file to implement your use case. The I2C templates are C++ files because the library used for interfacing with the I2C buses is C++ based, and hence the drivers developed for the I2C devices are also written in C++.

The two template nodes can be respectively launched by files i2c_for_motors_and_servos.launch and i2c_for_sensors.launch. You should review the launch files to check how they are structured. Then you can launch the template I2C nodes with:

roslaunch asclinic_pkg i2c_for_motors_and_servos.launch
roslaunch asclinic_pkg i2c_for_sensors.launch

Note

When you copy either template C++ file, you will need to add it to the CMakeLists.txt file in the repository at the relative file path:

catkin_ws/src/asclinic_pkg/CMakeLists.txt

Simply duplicate and accordingly edit the lines where the name of the respective template I2C C++ file appears. Most important is that the add_executable(...) needs to list the executable files for any I2C driver that in included by the node. For example, the template_i2c_external node has the following add_executable(...) in the CMakeLists.txt file:

add_executable(i2c_for_sensors
  src/nodes/i2c_for_sensors.cpp
  src/drivers/src/i2c_driver/i2c_driver.cpp
  src/drivers/src/vl53l1x/vl53l1x.cpp
  src/drivers/src/vl53l1x/core/VL53L1X_api.c
  src/drivers/src/vl53l1x/platform/vl53l1_platform.c
  )

Note

You can view the source code of the available drivers at the relative path:

catkin_ws/src/asclinic_pkg/src/drivers/src/

Documentation of the drivers in available in the SOFTWARE DRIVERS FOR SENSORS AND ACTUATORS section of the wiki.

6.3. Important notes on I2C usages in ROS nodes

Important

If multiple I2C devices are connected to the same I2C bus, then you MUST use one ROS node to interface with all those devices.

It does NOT work if you create a separate ROS node for each I2C device on the same I2C bus. In such a case, the first ROS node to launch opens the I2C bus and blocks any other nodes from accessing that same I2C bus.

Important

If your code attempts to communicate with an I2C device that is not physically connected to that bus, then the behaviour is not guaranteed and can be unexpected.

The I2C drivers are written with the intention to degrade gracefully in the case of a missing device:

  • The absence of the device is detected when attempting to initialise the device and a warning is display.

  • Any further request to communicate with the device is not executed.

  • A subsequent attempt to initialise the device will again check if for the presence or absence of the device.

Despite this intention for graceful degradation, it can still happen that the a node stalls due to a missing I2C device. This stalling can mean that the function called is continually trying to communicate with the missing, and the result can be that all I2C and GPIO buses and channels exhibit unexpected behaviour because the low level interface controllers are overloaded with the requests of the stalled node.

6.4. Step-by-step guides for the I2C device drivers



Creative Commons License
Paul N. Beuchat, 2023