TOF400C Time-of-Flight Sensor
The TOF400C is a long-range laser-based time-of-flight (ToF) sensor based on the VL53L1X chip from STMicroelectronics. It measures distances up to 4 meters with high accuracy and is ideal for robotics, navigation, and presence detection applications.

On this page
TOF400C pinout
The TOF400C pinout includes I2C communication pins (SDA, SCL), power supply (VIN, GND), interrupt pin (INT), and shutdown pin (SHUT) for long-range distance measurements up to 4 meters. Based on the VL53L1X chip.
| Pin | Type | Description | Notes |
|---|---|---|---|
| VIN | Power | Power supply input (3.0V to 5.0V) | Typically 3.3V (VL53L1X requires 2.6-3.5V) |
| GND | Ground | Ground connection | Common ground |
| SDA | I2C Data | I2C Serial Data line | Bidirectional data (requires pull-up) |
| SCL | I2C Clock | I2C Serial Clock line | Clock signal (requires pull-up) |
| INT | Interrupt | Interrupt output pin | Optional for event-driven measurements |
| SHUT | Control | Shutdown pin (active low) | Tie high to enable sensor, low to disable |
Based on VL53L1X Time-of-Flight sensor chip
Long-range distance measurement: 0 cm to 400 cm (4 meters)
Resolution: 1 mm accuracy
Field of View: 27°
Operating voltage: 3.0V to 5.0V (onboard regulator)
VL53L1X chip requires: 2.6V to 3.5V (regulated on board)
I2C address: 0x29 (default)
Laser wavelength: 940 nm (Class 1)
Current consumption: ~40 mA typical
Advanced filtering and timing budget control
Adjustable distance modes: short, medium, long
Wiring the TOF400C to ESP32
Connect the TOF400C to your ESP32 via I2C (SDA and SCL pins). This sensor is based on the VL53L1X chip and provides long-range distance measurements up to 4 meters with adjustable timing budgets. Pull-up resistors are typically included on modules.
| TOF400C pin | ESP32 pin | Purpose |
|---|---|---|
| VIN | 3.3V or 5V | Power supply (onboard regulator) |
| GND | GND | Ground connection |
| SDA | GPIO21 | I2C data line (with pull-up) |
| SCL | GPIO22 | I2C clock line (with pull-up) |
| INT | GPIO (optional) | Interrupt output for measurement ready · optional |
| SHUT | 3.3V or GPIO | Shutdown control (tie high to enable) · optional |
Based on VL53L1X chip - compatible with VL53L1X libraries
Extended range: up to 4 meters (10x longer than TOF050C)
I2C address: 0x29 (same as VL53L0X/VL6180X)
Onboard voltage regulator: accepts 3.3V or 5V input
Pull-up resistors typically included on module
SHUT pin: Tie high to enable, allows multiple sensors on same bus
INT pin signals when measurement is ready
Use Adafruit_VL53L1X or Pololu VL53L1X library
Adjustable distance modes: short (1.3m), medium (3m), long (4m)
Adjustable timing budget affects accuracy vs speed
940 nm laser wavelength (Class 1, eye-safe)
Better ambient light performance than VL53L0X
Can replace VL53L1X in existing projects
TOF400C code examples
TOF400C 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 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);
}This Arduino code demonstrates how to use the VL53L0X sensor with the Adafruit library. It initializes the sensor using the lox.begin() method. In the loop(), the rangingTest() method measures the distance to an object in millimeters, which is printed to the Serial Monitor every 500 ms. If no object is detected or the object is out of range, a corresponding message is displayed. The I2C protocol facilitates communication with the sensor. The TOF400C is a VL53L0X-based module - the VL53L0X driver applies unchanged.
TOF400C 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("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 TOF400C is a VL53L0X-based module - the VL53L0X driver applies unchanged.
TOF400C ESPHome example
Copyi2c:
sda: GPIO21
scl: GPIO22
sensor:
- platform: vl53l0x
name: "VL53L0X Distance"
update_interval: 500msThis ESPHome configuration uses the vl53l0x platform to interface with the sensor. The sensor’s name, ‘VL53L0X Distance,’ makes it easily identifiable in home automation platforms like Home Assistant. The update_interval of 500 ms ensures frequent updates for applications requiring real-time distance measurements. The TOF400C is a VL53L0X-based module - the VL53L0X driver applies unchanged.
TOF400C 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. The TOF400C is a VL53L0X-based module - the VL53L0X driver applies unchanged.
TOF400C 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 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 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. The TOF400C is a VL53L0X-based module - the VL53L0X driver applies unchanged.
About the TOF400C
The TOF400C is a breakout board wrapped around STMicroelectronics’s longer-range VL53L1X time-of-flight chip - confirmed by its own datasheet linking to ST’s VL53L1X document and matched by multiple independent sellers describing it the same way. Same 940 nm laser and 16x16 SPAD array as the bare VL53L1X, same fixed I2C address of 0x29, just a different PCB and onboard regulator.
Specced range is 4 to 400 cm with a documented dead zone of about 0-4 cm right at the sensor face, accuracy around plus-or-minus 6 cm in the 0.2-3 m band, and up to 40 mA while ranging at up to 50 Hz. As with the plain VL53L1X, the 4-meter headline number assumes favorable, low-ambient-light conditions using the chip’s long distance mode; in bright light or with a less reflective target, actual usable range drops well short of that, particularly if long mode’s extended integration time is picking up stray IR from sunlight or other sources.
For projects that need real multi-meter reach - robot navigation, water tank level sensing, presence detection across a room - this is the sensor in the family to reach for over its shorter siblings. If 4 meters is more than needed, the VL53L0X-based TOF200C covers about 2 meters for less money and with a simpler ambient-light story; the bare VL53L1X is the same chip without the TOF400C’s board-specific pinout.
TOF400C troubleshooting
Sensor Not Detected
›
Issue: Sensor not detected via I²C.
Solution: Check pull-up resistors, wiring, and ensure SHUT pin is high or tied to VIN. Try scanning I²C address.
Distance Readings Unstable
›
Issue: Inconsistent or flickering values.
Solution: Increase timing budget in code, shield from ambient light, or use reflective target surfaces.
Reads Max Distance Constantly
›
Issue: Always shows max range (e.g. 4000 mm).
Solution: Ensure target is within FOV and reflective enough. Use long-range mode and increase integration time.
Where to buy the TOF400C

Resources
Similar sensors





