Introduction
The ProtoCentral TMF8829 dToF Depth Imager Breakout turns the ams OSRAM TMF8829 — a single-chip, multi-zone direct time-of-flight (dToF) sensor — into a plug-and-play board you can wire to any microcontroller over I²C.
Unlike a single-point distance sensor that returns one number, the TMF8829 returns a full depth image: distance and confidence for every zone in its field of view, up to a 48 × 32 grid (1,536 zones) at up to 15 fps, with an 80° field of view and ranging out to 11 m. Two integrated, Class-1 eye-safe VCSEL emitters do the illuminating, so there are no external optics to add.
That makes it a compact way to do gesture sensing, presence and people detection, robotics obstacle mapping, and low-resolution 3D scanning — all from a board smaller than a postage stamp.

Key Features
- ams OSRAM TMF8829 direct time-of-flight (dToF) imager
- 48 × 32 depth array — 1,536 zones per frame, up to 15 fps
- Selectable focal-plane modes: 8 × 8, 16 × 16, 32 × 32, 48 × 32
- 80° field of view, ranging up to 11 m, ~0.25 mm resolution
- Two integrated VCSEL emitters (Class 1 eye-safe)
- I²C and SPI interfaces; SparkFun Qwiic connector for solder-free I²C
- On-board AP2112K 1.8 V LDO; JP1 jumper selects 3.3 V or 1.8 V sensor I/O
- 3.3 V – 5 V host supply with on-board level translation
- Open-source hardware (CERN-OHL-P v2) and Arduino library (MIT)
What’s in the Box
- 1 × ProtoCentral TMF8829 dToF Depth Imager Breakout Board
- 1 × 4-pin 0.1″ male header strip (I²C side)
- 1 × 6-pin 0.1″ male header strip (SPI side)
The two Qwiic connectors let you start without soldering at all.
Specifications
| Parameter | Value |
|---|---|
| Sensor | ams OSRAM TMF8829 multi-zone dToF imager |
| Depth array | 48 × 32 zones (1,536), up to 15 fps |
| Modes | 8 × 8 / 16 × 16 / 32 × 32 / 48 × 32 |
| Field of view | 80° |
| Range | up to 11 m |
| Resolution | ~0.25 mm |
| Illumination | 2 × VCSEL, Class 1 eye-safe |
| Interface | I²C (up to 1 MHz), SPI and I³C; I²C address 0x41. The ProtoCentral Arduino library currently supports I²C only. |
| Connectors | 2 × Qwiic / STEMMA QT + 0.1″ I²C (4-pin) and SPI (6-pin) headers |
| Supply | 3.3 V – 5 V host; on-board AP2112K-1.8 LDO, JP1-selectable 3.3 V / 1.8 V VIO |
| Board size | ~26 × 26 mm, 4 mounting holes |
Hardware Overview
The board breaks the TMF8829 out to two interfaces and keeps the sensor happy on its native 1.8 V rail while letting you talk to it from a 3.3 V or 5 V host.
| Feature | Notes |
|---|---|
| 2 × Qwiic | Solder-free I²C (SDA / SCL / 3V3 / GND) — daisy-chain with other Qwiic boards |
| I²C header (4-pin) | SDA · SCL · 3.3V · GND |
| SPI / GPIO header (6-pin) | MOSI/GPIO0 · CSN/GPIO1 · SCLK/GPIO2 · MISO/GPIO3 · INTB/GPIO6 · GND |
| JP1 (VIO) | Selects sensor I/O level: 3.3 V (default) or 1.8 V |
| AP2112K-1.8 LDO | Generates the 1.8 V the silicon needs from your 3.3–5 V supply |
| Mounting | 4 × mounting holes |
At a glance: the sensor answers at I²C address 0x41 over either Qwiic connector or the 4-pin header. The 6-pin header adds the full SPI bus (MOSI / MISO / SCLK / CSN) plus the INTB result-ready interrupt. JP1 selects the sensor I/O level — 3.3 V (default) or 1.8 V — and the on-board AP2112K LDO derives the 1.8 V rail the silicon needs from your 3.3–5 V supply.
The optical window must have a clear line of sight — don’t cover it with tape, hot glue, or an enclosure window that isn’t IR-transparent.
Wiring
The TMF8829 communicates over I²C at address 0x41.
Other interfaces. The TMF8829 silicon also supports SPI and I³C — the 6-pin header breaks out the SPI pins (MOSI / MISO / SCLK / CSN). The ProtoCentral Arduino library currently drives the sensor over I²C only, so follow the I²C wiring below.
Option 1 — Qwiic (recommended, solder-free)
The easiest way to connect the board to an Arduino is over Qwiic — no soldering and no jumper wires. Add a Qwiic shield to your Arduino, then run a Qwiic cable from the shield to either of the board’s two Qwiic connectors. Power and I²C all share the one cable.
- SparkFun Qwiic Shield for Arduino — stacks onto an Uno / R3-footprint board and brings out solder-free Qwiic ports.
- SparkFun Qwiic Cable Kit — assorted Qwiic cable lengths to reach the sensor.
With the shield seated and a cable plugged in, you’re wired — skip straight to installing the Arduino library.
Option 2 — 0.1″ header to a breadboard
Solder the included 4-pin header to the I²C side and wire it to your microcontroller:
| TMF8829 pin | Arduino UNO / Nano | ESP32 | Function |
|---|---|---|---|
| 3.3V | 3.3 V | 3V3 | Supply |
| GND | GND | GND | Ground |
| SDA | A4 | GPIO21 | I²C data |
| SCL | A5 | GPIO22 | I²C clock |
| INTB (opt.) | any GPIO | any GPIO | Result-ready interrupt |
Bus speed scales with the grid. 8 × 8 works at I²C Standard mode (100 kHz). 16 × 16 needs Fast mode (400 kHz); 32 × 32 and 48 × 32 need Fast-mode Plus — call
Wire.setClock(1000000)on a core that supports it (most ARM/ESP cores do; AVR caps at 400 kHz, so use 8 × 8 / 16 × 16 there).
Installing the Arduino Library
Option 1 — Library Manager (recommended)
- Open the Arduino IDE
- Sketch → Include Library → Manage Libraries…
- Search for “ProtoCentral TMF8829” and click Install
Option 2 — Manual install from GitHub
Clone or download Protocentral/protocentral_tmf8829_arduino into your Arduino libraries/ folder and restart the IDE. The official ams OSRAM RAM firmware ships inside the library — there are no extra files to flash.
The cold-boot sequence (read this first)
The TMF8829 ships with only a bootloader in ROM — the measurement application lives in RAM and must be downloaded by the host every cold boot. The library does this for you, but the order of calls matters:
begin()— drivesENhigh, waits for CPU-ready, verifies the chip ID, and latches I²C as the host interface. The chip is now in its ROM bootloader.loadFirmware()— streams the bundled ams OSRAM RAM application into the chip and starts it. Idempotent — a no-op if it’s already running.setMeasurementMode()→startMeasurement()→readFrame()— app-level commands, now legal.
Pulling
ENlow (or a hard power-cycle) wipes RAM, soloadFirmware()must run again afterwards. Re-flashing your host sketch on a board that does not power-cycle the sensor (Nano 33 BLE, SAMD, ESP32…) leaves the previous session running — the library handles that case for you.
Your first reading — verify the board
This sketch loads the firmware, runs the 8 × 8 mode, and prints the distance at the centre of the grid. It’s the “hello world” — run it first to confirm wiring.
#include <Wire.h>
#include <Protocentral_TMF8829.h>
TMF8829 tof;
void setup() {
Serial.begin(115200);
Wire.begin();
if (!tof.begin()) { // power up + chip-ID check + bootloader latch
Serial.println("TMF8829 not found — check wiring/address");
while (1);
}
tof.loadFirmware(); // stream the RAM app into the chip
tof.setMeasurementMode(TMF8829_MODE_8X8);
tof.startMeasurement();
}
void loop() {
if (tof.dataReady()) {
tmf8829_frame_t frame;
if (tof.readFrame(&frame) == TMF8829_OK) {
uint8_t cx = frame.cols / 2, cy = frame.rows / 2;
if (frame.isValidAt(cx, cy)) {
Serial.print("centre: ");
Serial.print(frame.distanceMmAt(cx, cy));
Serial.println(" mm");
}
}
}
}
Open the Serial Monitor at 115200 baud and wave your hand in front of the sensor — the centre distance should track it.
Depth modes
Pick the grid that fits your application and your host’s I²C speed and memory:
| Mode | Zones | Min. I²C speed | Notes |
|---|---|---|---|
TMF8829_MODE_8X8 |
64 | 100 kHz | Fast, low memory; also _LONG_RANGE / _HIGH_ACCURACY variants |
TMF8829_MODE_16X16 |
256 | 400 kHz | Good detail / speed balance |
TMF8829_MODE_32X32 |
1024 | 1 MHz | High resolution |
TMF8829_MODE_48X32 |
1536 | 1 MHz | Full resolution |
Memory: the frame buffer sizes to
TMF8829_MAX_ZONES(default 1536, ~7 KB SRAM). That’s fine on Nano 33 BLE, SAMD, ESP32 and RP2040, but a 2 KB AVR (Uno/Nano) can’t fit it — compile with-DTMF8829_MAX_ZONES=64(8 × 8) or=256(16 × 16) on AVR.
Reading a depth grid
Every frame exposes (x, y) accessors with the row-major convention baked in — x is the column (0 = left), y is the row (0 = top):
tmf8829_frame_t frame;
tof.readFrame(&frame);
for (uint8_t y = 0; y < frame.rows; y++) {
for (uint8_t x = 0; x < frame.cols; x++) {
if (frame.isValidAt(x, y))
Serial.print(frame.distanceMmAt(x, y)); // mm
else
Serial.print("----");
Serial.print('t');
}
Serial.println();
}
The GridASCII example (sketch 04) builds on this to print a live ASCII heat-map.
Application examples
The library ships with seven examples — start simple and work up:
| # | Sketch | What it shows |
|---|---|---|
| 01 | DistanceSingle | Nearest + centre distance each frame |
| 02 | ProximityLED | Light the built-in LED when something comes within 20 cm — no serial monitor needed |
| 03 | SerialPlotter | Plot centre/nearest distance in the IDE Serial Plotter |
| 04 | GridASCII | 8 × 8 ASCII heat-map + numeric grid |
| 05 | HighResGrid | 16 × 16 (switchable to 32 × 32 / 48 × 32) console heat-map |
| 06 | GestureProximity | Detect hand swipes (left/right/up/down) from the moving depth centroid |
| 07 | OpenViewStream | Stream the grid to ProtoCentral OpenView for a live heat-map (OpenView 3 — releasing soon) |
Visualizing with OpenView
Note — OpenView 3 is releasing soon. The desktop OpenView app with the live depth-heatmap view shown above is in final testing and ships shortly. In the meantime you can watch the same data as a live heatmap right in the Arduino Serial Monitor with the GridASCII (04) and HighResGrid (05) examples — no extra software needed.
The OpenViewStream example streams the live depth grid to ProtoCentral OpenView, where you can watch the depth heat-map update in real time — the easiest way to see what the sensor sees while you prototype.
Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
TMF8829 not found at begin() |
Check Qwiic/header wiring and 3.3 V supply; confirm address 0x41; if you have an EN pin wired, make sure it’s driven (or tie it high and skip setEnablePin). |
begin() OK but readFrame() never returns data |
You skipped loadFirmware() — the RAM app isn’t running. See the cold-boot sequence. |
| Works at 8 × 8 but garbles at 32 × 32 / 48 × 32 | I²C too slow — call Wire.setClock(1000000) on an ARM/ESP core. AVR can’t go past 400 kHz; use 8 × 8 / 16 × 16. |
| Compiles fail / crashes on Uno or Nano | AVR SRAM overflow — compile with -DTMF8829_MAX_ZONES=64 or =256. |
| Noisy or short readings | Keep the optical window clean and unobstructed; avoid IR-opaque enclosure windows; watch for highly reflective or absorbing targets at range. |
Resources
- Product page — https://protocentral.com/product/tmf8829-depth-imager/
- Arduino library — https://github.com/Protocentral/protocentral_tmf8829_arduino
- Hardware design files (KiCad) — https://github.com/Protocentral/protocentral_tmf8829_hardware
- Schematic (PDF) — linked from the product’s Downloads tab
- IC datasheet (ams OSRAM) — https://look.ams-osram.com/m/4215c1ea1a30e283/original/TMF8829-Time-of-flight-sensor.pdf
Licenses
- Hardware (board design files) — CERN-OHL-P v2
- Software (Arduino library) — MIT
- Bundled sensor firmware — © ams OSRAM, MIT-licensed (unmodified)
This device is intended for evaluation, education and research — it is not a certified safety or medical instrument.

