Getting Started

Getting Started with the ProtoCentral TMF8829 dToF Depth Imager

Last updated Jun 11, 2026

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.

ProtoCentral TMF8829 48×32 dToF Depth Imager Breakout

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

ProtoCentral TMF8829 board layout and pinout

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.

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

ProtoCentral TMF8829 to Arduino Uno I²C hookup

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)

  1. Open the Arduino IDE
  2. Sketch → Include Library → Manage Libraries…
  3. 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:

  1. begin() — drives EN high, waits for CPU-ready, verifies the chip ID, and latches I²C as the host interface. The chip is now in its ROM bootloader.
  2. loadFirmware() — streams the bundled ams OSRAM RAM application into the chip and starts it. Idempotent — a no-op if it’s already running.
  3. setMeasurementMode()startMeasurement()readFrame() — app-level commands, now legal.

Pulling EN low (or a hard power-cycle) wipes RAM, so loadFirmware() 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)
Live depth heat-map from the TMF8829 — 48 × 32 zones streaming at 15 fps. Shown in ProtoCentral 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

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.