Sensors/ Distance/ TOF200C

TOF200C Time-of-Flight Sensor

The TOF200C is a compact, low-cost laser-ranging sensor based on the VL53L0X time-of-flight chip from STMicroelectronics. It provides accurate distance measurement using a 940nm VCSEL emitter.

TOF200C Time-of-Flight Sensor image
TOF200C · I2C
I2C
Interface
6pins
Connections
3.0-5.0V
Supply
~40mA
Power
1mm
Resolution
$2
Typical price
On this page

TOF200C pinout

6 pins · I2C

The TOF200C sensor features 6 pins for power, communication, and control. Here’s a detailed breakdown of each pin’s function and specifications.

View:
TOF200C Time-of-Flight Sensor pinout
PinTypeDescriptionNotes
VINPowerPower supply input (3.0V - 5.0V)Accepts both 3.3V and 5V logic
GNDPowerGround connectionConnect to ESP32 ground
SDACommunicationI²C Data lineBidirectional data signal for I²C communication
SCLCommunicationI²C Clock lineClock signal provided by ESP32 master
INTControlInterrupt outputOptional - triggers when new measurement is ready
SHUTControlShutdown control (active low)Pull high to enable, or use GPIO for control
  • I²C address: 0x29 (fixed, not configurable)

  • Pull-up resistors on SDA/SCL may already be on the module

  • INT pin is useful for interrupt-driven measurements instead of polling

Wiring the TOF200C to ESP32

6 connections · 2 optional

Connect the TOF200C sensor to your ESP32 microcontroller using the I²C interface. The sensor operates on 3.3V or 5V and provides accurate distance measurements up to 200cm.

TOF200C Time-of-Flight Sensor wiring with ESP32
TOF200C pinESP32 pinPurpose
VIN3.3V or 5VPower supply pin
GNDGNDGround connection
SDAGPIO21I²C Data line (default SDA)
SCLGPIO22I²C Clocgk line (default SCL)
INTAny GPIOInterrupt output (optional) · optional
SHUTVCC or GPIOShutdown control (tie to VCC to enable, or use GPIO for control) · optional
  • The sensor works with both 3.3V and 5V logic levels

  • Ensure proper I²C pull-up resistors (4.7kΩ recommended) if not already on board

  • GPIO21 and GPIO22 are the default I²C pins on ESP32, but you can use any GPIO with software I²C

  • The INT pin can be used for interrupt-driven operation to reduce polling overhead

TOF200C code examples

5 platforms
Platform:

TOF200C Arduino example

Copy
#include <Wire.h>
#include <Adafruit_VL53L0X.h>

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  Serial.begin(115200);
  Wire.begin();

  if (!lox.begin()) {
    Serial.println("Failed to initialize TOF200C sensor!");
    while (1);
  }
  Serial.println("TOF200C ready!");
}

void loop() {
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);

  if (measure.RangeStatus != 4) {
    Serial.print("Distance: ");
    Serial.print(measure.RangeMilliMeter);
    Serial.println(" mm");
  } else {
    Serial.println("Out of range");
  }
  delay(500);
}

This Arduino sketch uses the Adafruit VL53L0X library to read distance measurements from the TOF200C sensor. It initializes the I²C bus and repeatedly prints the measured distance in millimeters.

TOF200C ESP-IDF example

Copy
// Minimal raw-I2C single-shot ranging for the VL53L0X (address 0x29).
// The chip boots with usable default settings; this reads uncalibrated
// distance directly. For production accuracy, use ST's VL53L0X API.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c.h"

#define I2C_MASTER_SCL_IO  22
#define I2C_MASTER_SDA_IO  21
#define I2C_MASTER_NUM     I2C_NUM_0
#define I2C_MASTER_FREQ_HZ 100000
#define VL53L0X_ADDR       0x29

#define REG_SYSRANGE_START          0x00
#define REG_RESULT_INTERRUPT_STATUS 0x13
#define REG_RESULT_RANGE_MM         0x1E // RESULT_RANGE_STATUS + 10
#define REG_SYSTEM_INTERRUPT_CLEAR  0x0B

static esp_err_t wr8(uint8_t reg, uint8_t val) {
    uint8_t buf[2] = {reg, val};
    return i2c_master_write_to_device(I2C_MASTER_NUM, VL53L0X_ADDR, buf, 2, pdMS_TO_TICKS(1000));
}

static esp_err_t rd(uint8_t reg, uint8_t *data, size_t len) {
    return i2c_master_write_read_device(I2C_MASTER_NUM, VL53L0X_ADDR, &reg, 1, data, len, pdMS_TO_TICKS(1000));
}

void app_main(void) {
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
    };
    ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_NUM, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0));

    uint8_t model_id = 0;
    if (rd(0xC0, &model_id, 1) != ESP_OK || model_id != 0xEE) {
        printf("VL53L0X not found (model id 0x%02X) - check wiring\n", model_id);
        return;
    }
    printf("TOF200C (VL53L0X) found.\n");

    while (1) {
        wr8(REG_SYSRANGE_START, 0x01); // Start a single-shot measurement

        // Wait for the result (interrupt status bits 0-2 set when ready)
        uint8_t status = 0;
        for (int i = 0; i < 50; i++) {
            rd(REG_RESULT_INTERRUPT_STATUS, &status, 1);
            if (status & 0x07) break;
            vTaskDelay(pdMS_TO_TICKS(5));
        }

        if (status & 0x07) {
            uint8_t range[2];
            rd(REG_RESULT_RANGE_MM, range, 2);
            uint16_t distance = (range[0] << 8) | range[1];
            if (distance < 8190) {
                printf("Distance: %u mm\n", distance);
            } else {
                printf("Out of range\n");
            }
            wr8(REG_SYSTEM_INTERRUPT_CLEAR, 0x01);
        } else {
            printf("Measurement timeout\n");
        }
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

This is a minimal raw-I2C example: the VL53L0X boots with usable default settings, so writing 0x01 to the SYSRANGE_START register triggers a single-shot measurement, the interrupt-status register signals completion, and the 16-bit range in millimeters is read from the result registers (values around 8190 mean out of range). This gives functional but uncalibrated readings - for production accuracy (calibration, long-range/high-accuracy profiles), port ST's official VL53L0X API as an ESP-IDF component. The TOF200C is a VL53L0X-based module, so the VL53L0X driver applies unchanged.

TOF200C ESPHome example

Copy
i2c:
  sda: 21
  scl: 22

sensor:
  - platform: vl53l0x
    name: "TOF200C Distance"
    update_interval: 1s

This ESPHome config sets up the TOF200C via the VL53L0X platform. It communicates over I²C and reports distance values every second.

TOF200C PlatformIO example

Copy
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    adafruit/Adafruit_VL53L0X @ ^1.2.4
src/main.cppCopy
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_VL53L0X.h>

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
    Serial.begin(115200);
    Wire.begin();

    if (!lox.begin()) {
        Serial.println("Failed to initialize VL53L0X! Check connections.");
        while (1);
    }
    Serial.println("VL53L0X Initialized.");
}

void loop() {
    VL53L0X_RangingMeasurementData_t measure;
    lox.rangingTest(&measure, false);

    if (measure.RangeStatus != 4) { // Status 4 means no object detected
        Serial.print("Distance: ");
        Serial.print(measure.RangeMilliMeter);
        Serial.println(" mm");
    } else {
        Serial.println("Out of range.");
    }

    delay(500);
}

The PlatformIO code uses the Adafruit VL53L0X library to interface with the sensor. After initializing I2C communication with Wire.begin(), the sensor is configured using lox.begin(). The rangingTest() function retrieves distance measurements in millimeters, which are printed to the Serial Monitor every 500 ms. A status check ensures meaningful data is displayed, and the code gracefully handles ‘out of range’ cases.

TOF200C MicroPython example

Copy
# Requires driver: VL53L0X.py from https://github.com/uceeatz/VL53L0X
# Copy it to the board: mpremote cp VL53L0X.py :
from machine import I2C, Pin
import time
import VL53L0X

# Initialize I2C (SDA=GPIO21, SCL=GPIO22)
i2c = I2C(0, scl=Pin(22), sda=Pin(21))

# Initialize TOF200C (VL53L0X) sensor
tof = VL53L0X.VL53L0X(i2c)
tof.start()

while True:
    distance = tof.read()  # Distance in mm
    print("Distance: {} mm".format(distance))
    time.sleep(0.5)

The TOF200C is a VL53L0X breakout, so the example uses the uceeatz/VL53L0X MicroPython driver (copy VL53L0X.py to the board). After start() begins ranging, read() returns the distance in millimeters; the sensor sits at address 0x29 on the default I2C pins.

TOF200C specifications

From the datasheet
Operating Range
3cm to 200cm
Dead Zone
3cm
Resolution
1mm
Voltage Range
3.0V to 5.0V
Current Consumption
~40mA
Interface
I²C
Wavelength
940nm
Field of View
25°

About the TOF200C

The TOF200C is a compact breakout board built around STMicroelectronics’s VL53L0X time-of-flight chip - confirmed by its own datasheet mirroring ST’s VL53L0X document, and consistent with how multiple independent sellers list it. That means the same 940 nm laser, the same fixed I2C address of 0x29, and the same driver code as any other VL53L0X breakout; only the PCB and pin labels differ.

Specced range is 3 to 200 cm with roughly plus-or-minus 3% accuracy and a response time under 30 ms, drawing up to about 40 mA while ranging and dropping to around 5 uA on standby. As with any VL53L0X board, the 200 cm figure is a best-case number against a bright, reflective target - dark or distant surfaces, and bright ambient light, will cut that down meaningfully, so budget for less in practice.

This is one of the more practical distance sensors on the site for real placement projects: its small size and I2C-only wiring make it easy to tuck into an enclosure. We used one to build a non-invasive standing desk height tracker with an ESP32-C3 SuperMini and ESPHome, reporting desk height straight into Home Assistant without touching the desk’s own controller. If a project needs the same chip on a different board layout, the VL53L0X and GY-530 pages cover the same silicon; for genuinely longer reach, the VL53L1X-based TOF400C reaches about 4 meters instead of 2.

TOF200C troubleshooting

3 common issues

No Distance Readings

›

Issue: The sensor always reports 'Out of range'.

Solution: Check power supply and wiring. Ensure SHUT pin is pulled high. Try initializing with a different I²C address if using multiple sensors.

I²C Not Detected

›

Issue: Device does not show up on I²C scanner.

Solution: Double-check SDA/SCL connections and use pull-up resistors (~4.7kΩ) if necessary. Ensure address conflicts are avoided if multiple devices share the bus.

Unstable Measurements

›

Issue: Readings fluctuate rapidly.

Solution: Use averaging in code, reduce ambient IR noise (sunlight), and avoid glossy targets.

Where to buy the TOF200C

TOF200C Time-of-Flight Sensor
TOF200C Time-of-Flight Sensor
$2per unit, typical
TOF200C Time-of-Flight Sensor enclosure
Snap-fit enclosure for the TOF200C
Protect your ESP32-C3 SuperMini and TOF200C sensor with our custom-designed snap-fit enclosure. Available in multiple colors and...
Amazon and AliExpress links are affiliate links - buying through them supports the site at no extra cost to you.

Resources