VL53L8CH、VL53L7CX、VL53L5CX 用的是同一套底层驱动(VL53LMZ ULD API),但侧重点完全不同——选型前务必看清楚这张表,尤其是视场角这一行。
| VL53L8CH | VL53L7CX | VL53L5CX | |
|---|---|---|---|
| 每区域目标数 | 最多 4 个 | 1 个 | 1 个 |
| 视场角 FoV | 45°×45°(对角 65°) | 60°×60°(对角 90°) | 45°×45°(对角 65°) |
| 最远测距 | 400 cm | ~350 cm | ~400 cm |
| AI 直方图输出(CNH) | 有 | 无 | 无 |
| I²C 速率 | 最高 1 MHz | 常用 400kHz | 常用 400kHz |
| 封装尺寸 | 6.4×3.0×1.75mm | 6.4×3.0mm | 6.4×3.0mm |
模块只需 4 根线即可工作:VCC、GND、SDA、SCL。ESP32 原生 3.3V,不需要电平转换。
| 模块引脚 | 接 ESP32 | 说明 |
|---|---|---|
| VCC | 3V3 | 3.3V 供电 |
| GND | GND | 共地 |
| SDA | GPIO21 | I²C 数据 |
| SCL | GPIO22 | I²C 时钟 |
| INT | — | 可不接,轮询方式即可 |
| LPn | — | 可不接,悬空即为工作状态 |
左边是桌面 3D 多目标仪表盘的真实截图(COM6 实时连接,非模拟数据);右边是 ESP32 + VL53L8CH + 2.8 寸黄屏的实拍接线照片。
网页里放压缩版,方便客户直接看;B站发布使用本地高清源文件 vl53l8ch_bilibili_v1.mp4。
最小可运行的 8×8 多目标测距程序——每个 zone 最多读 4 个目标,按近到远排列。驱动源码需要和 .ino 放在同一个 sketch 文件夹(VL53L8CH 目前没有 Arduino 库管理器可直接安装的库)。
#include <Arduino.h>
#include <Wire.h>
#include "vl53lmz_api.h" // platform.h 里 VL53LMZ_NB_TARGET_PER_ZONE 要设成 4U
static VL53LMZ_Configuration g_dev;
static VL53LMZ_ResultsData g_results;
void setup()
{
Serial.begin(115200);
delay(300);
Wire.begin(21, 22, 400000); // SDA=GPIO21, SCL=GPIO22, 400kHz
g_dev.platform.address = VL53LMZ_DEFAULT_I2C_ADDRESS; // 8-bit 地址 0x52
uint8_t isAlive;
uint8_t status = vl53lmz_is_alive(&g_dev, &isAlive);
if (!isAlive || status) {
Serial.println("ERROR: VL53L8CH not detected! Check wiring.");
while (1) { delay(1000); }
}
status = vl53lmz_init(&g_dev);
if (status != VL53LMZ_STATUS_OK) {
Serial.printf("ERROR: init failed (code %d)\n", status);
while (1) { delay(1000); }
}
// module_type 读回来应该是 2 (VL53LMZ_MODULE_TYPE_L8)
Serial.printf("Driver: %s, module_type=%u\n", VL53LMZ_API_REVISION, g_dev.module_type);
vl53lmz_set_resolution(&g_dev, VL53LMZ_RESOLUTION_8X8);
vl53lmz_set_ranging_frequency_hz(&g_dev, 10);
vl53lmz_set_ranging_mode(&g_dev, VL53LMZ_RANGING_MODE_CONTINUOUS);
vl53lmz_set_target_order(&g_dev, VL53LMZ_TARGET_ORDER_CLOSEST);
vl53lmz_start_ranging(&g_dev);
}
void loop()
{
uint8_t isReady;
vl53lmz_check_data_ready(&g_dev, &isReady);
if (!isReady) { delay(2); return; }
vl53lmz_get_ranging_data(&g_dev, &g_results);
Serial.printf("=== Frame #%u ===\n", g_dev.streamcount);
for (int zone = 0; zone < 64; zone++) {
uint8_t nb = g_results.nb_target_detected[zone];
if (nb == 0) continue;
Serial.printf("Zone %2d (%u targets): ", zone, nb);
for (uint8_t k = 0; k < nb; k++) {
uint16_t idx = VL53LMZ_NB_TARGET_PER_ZONE * zone + k;
Serial.printf("[%dmm @%u%%] ", g_results.distance_mm[idx], g_results.reflectance[idx]);
}
Serial.println();
}
Serial.println();
}
# 真实数据(COM 口以实际插入的为准)
python vl53l8_dashboard.py COM6 115200
# 没接硬件时看模拟多目标效果
python vl53l8_dashboard.py --demo
2026-07-11 用 ESP32 + VL53L8CH 实测烧录验证过,以下两个现象是芯片本身的真实特性,不是接线或模块故障。
几乎每个 zone 都会多测到一个很近(几十毫米)、反射率很低(0~2%)的目标——这是保护盖板玻璃自身的反射(cover-glass crosstalk),单目标传感器通常把它滤掉看不见,开了多目标之后才会暴露出来。
ST 官方为此专门写了盖板玻璃选型指南(AN5939),有更高展示要求时可以做串扰标定去掉这个近场幽灵点。
官方文档说"状态码 5/6/9 才算测距有效",但多目标模式下较弱的那个目标经常不是这三个值——可它确实被 nb_target_detected 算进去了。
正确做法:非 255(空槽)就当作真实回波显示出来,让反射率去体现"这个目标有多可信",而不是在这一步就武断丢弃数据。
客户来网页通常是找代码和资料,这里把最常用入口单独做成卡片。