
When you build a mobile robot, you usually reach for a lidar or a depth camera for sensings the robot’s environment. Both are great tools, but also consume a lot of energy and space which can be overkill for a small mobile platform. Time-of-Flight (ToF) sensors are a good compromise and have increasingly higher resolution and sensing ranges.
The AMS TMF8829 is a particularly interesting one. In its highest-resolution mode it splits its field of view into a 48x32 grid and reports a distance and a confidence value for each of its 1536 zones. That is essentially a tiny depth image, refreshed several times per second, in a sensor that fits on a fingertip. However, the sensors main interface is I2C. In order to use it on a ROS 2 system you need a small piece of firmware that bridges the two worlds.
This article walks through tof-tmf8829-micro-ros, an Arduino sketch that does exactly that. It runs micro-ROS on an Arduino UNO R4 Minima, reads the 16x16 distance data (not using the full resolution for this demo) from the TMF8829, converts it into a sensor_msgs/PointCloud2, and publishes it on a ROS 2 topic so that you can visualise the result in Rviz2.
You will need exactly two parts:
- 1 x Arduino UNO R4 Minima
- 1 x AMS TMF8829_EVM_EB_SHIELD evaluation shield
The shield plugs directly onto the Arduino’s headers, there is no wiring involved. The Renesas RA4M1 microcontroller on the UNO R4 Minima has enough flash and RAM to comfortably run the micro-ROS client together with the TMF8829 driver (although your ArduinoCore-renesas needs patching).
Note: The same approach works on any Arduino-compatible board for which a micro-ROS port exists. If you already have a Portenta H7 or a Teensy in your drawer, you can adapt the --fqbn accordingly.
The sketch can be built and flashed with arduino-cli. Make sure that the Arduino UNO R4 Minima is connected via USB and shows up as /dev/ttyACM0 (the device name may differ on your system).
| |
Internally the sketch uses micro_ros_arduino to set up a single publisher on topic /scan, and a vendored TMF8829 driver to talk to the sensor over I2C. After power-up the firmware initialises the sensor in 16x16 mode, computes the per-zone direction vectors from the sensor’s typical 41 degree field of view, and starts streaming measurements. For each measurement cycle the firmware iterates over all 256 zones, converts the polar (distance, azimuth, elevation) triplet into Cartesian (x, y, z) coordinates, and packs the result into the data field of the PointCloud2 message.
The Arduino sketch is a micro-ROS client. It needs a corresponding agent on the host side to translate between the serial transport and DDS, so that the published topic shows up as a regular ROS 2 topic. The easiest way to bring the agent up is via Docker:
| |
--net=host is required so that the agent can announce the topic on the same DDS domain that the rest of your ROS 2 system uses. --device=/dev/ttyACM0 exposes the Arduino’s serial port to the container.
Once the agent is up you should see the topic in a separate terminal:
| |
If the topic does not appear, the most common causes are a mismatched ROS_DOMAIN_ID between agent and consumer, or another process holding /dev/ttyACM0 open (for example the Arduino IDE’s serial monitor).
The repository ships an Rviz2 configuration file which is preconfigured with the correct topic name and a fixed frame matching the sensor frame published by the firmware:
| |
Wave your hand in front of the sensor and you should see the point cloud follow it in real time, as shown in the video at the top of this article.
The complete source code, including the vendored TMF8829 driver, the Rviz2 configuration, and a more detailed README, is available at lxrobotics/tof-tmf8829-micro-ros. For further reading I recommend the micro-ROS documentation for everything related to running ROS 2 on microcontrollers, and the TMF8829 datasheet for the full set of operating modes the sensor supports beyond the 16x16 grid used here.

