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.

On this page
TOF200C pinout
The TOF200C sensor features 6 pins for power, communication, and control. Here’s a detailed breakdown of each pin’s function and specifications.
| Pin | Type | Description | Notes |
|---|---|---|---|
| VIN | Power | Power supply input (3.0V - 5.0V) | Accepts both 3.3V and 5V logic |
| GND | Power | Ground connection | Connect to ESP32 ground |
| SDA | Communication | I²C Data line | Bidirectional data signal for I²C communication |
| SCL | Communication | I²C Clock line | Clock signal provided by ESP32 master |
| INT | Control | Interrupt output | Optional - triggers when new measurement is ready |
| SHUT | Control | Shutdown 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
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 pin | ESP32 pin | Purpose |
|---|---|---|
| VIN | 3.3V or 5V | Power supply pin |
| GND | GND | Ground connection |
| SDA | GPIO21 | I²C Data line (default SDA) |
| SCL | GPIO22 | I²C Clocgk line (default SCL) |
| INT | Any GPIO | Interrupt output (optional) · optional |
| SHUT | VCC or GPIO | Shutdown 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
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, ®, 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
Copyi2c:
sda: 21
scl: 22
sensor:
- platform: vl53l0x
name: "TOF200C Distance"
update_interval: 1sThis 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#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
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
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


Resources
Similar sensors





