# VL53L7CX / VL53L5CX 多区域 ToF 距离传感器模块资料

## 1. 商品信息

- **SKU**: VL53L7
- **淘宝链接**: http://item.taobao.com/item.htm?id=1012730024177
- **产品名**: VL53L7CX / VL53L5CX 多区域 ToF 距离传感器模块
- **是否建议做网页**: 是

---

## 1.1 实拍图片

### 模块正面

![VL53L7CX模块-正面](https://img.alicdn.com/imgextra/i3/1804731589/O1CN01zFDhCj1NboUUgYM2y_!!1804731589.png)

### 模块背面

![VL53L7CX模块-背面](https://img.alicdn.com/imgextra/i4/1804731589/O1CN01cr0GAn1NboUUWx82P_!!1804731589.png)

---

## 1.2 测试实况视频

ESP32 + VL53L7CX 上电测试，8×8 连续测距实时输出演示。

> 📹 测试视频：https://img.alicdn.com/imgextra/i4/1804731589/O1CN01K74nXU1NboUUQxsUc_!!1804731589.mp4
>
> 视频内容：ESP32 开发板 + VL53L7CX 模块，通过 Arduino IDE 烧录 8×8 连续测距程序，串口监视器实时输出 64 区距离数据（mm）。传感器检测、固件下载、初始化成功，稳定输出矩阵距离值。

---

## 2. 买家测试前需要准备

### 硬件

| 物品 | 说明 |
|------|------|
| 单片机开发板 | Arduino UNO / Nano、ESP32、STM32（任选一种，**推荐 ESP32**） |
| 杜邦线 | 公对母 × 4~6 根 |
| USB 数据线 | 与开发板匹配的供电+下载线 |
| VL53L7 模块 | 本商品 |
| 目标物体 | 白墙、纸板、手掌等均可 |

### 软件

| 软件 | 说明 |
|------|------|
| Arduino IDE | [arduino.cc](https://www.arduino.cc/en/software) 下载，版本 ≥ 1.8 |
| **stm32duino/VL53L7CX 库** | 在 Arduino IDE 库管理器中搜索安装（详见第 5 章） |
| 串口监视器 | Arduino IDE 自带，波特率 115200 |

### 供电要求

- VL53L7CX 模块典型工作电压 **3.3V**（部分模块板载 LDO 可接 5V，请以实物丝印为准）
- 测距时峰值电流 ≈ **100~150 mA**，确保开发板 3.3V 输出能力足够
- **UNO/Nano 用户注意：5V GPIO 直接接 3.3V 传感器 I2C 可能损坏模块，必须电平转换**

> ⚠️ 不确定模块是否板载电压转换时，先用 3.3V 供电，用万用表确认 VCC 引脚电压。

---

## 3. 模块基础说明

### 3.1 工作原理

VL53L7CX 和 VL53L5CX 是 ST（意法半导体）FlightSense™ 系列的**多区域 ToF（Time-of-Flight，飞行时间）距离传感器**。

- 发射 940nm 不可见红外激光（Class 1 人眼安全）
- SPAD 阵列接收反射光，计算光子飞行时间 → 距离
- 一次测量返回 **64 个区域（8×8）** 或 **16 个区域（4×4）** 的距离值
- 每个区域独立测距，互不干扰

### 3.2 VL53L7CX 与 VL53L5CX 差异

| 参数 | VL53L7CX | VL53L5CX |
|------|----------|----------|
| **视场角（FoV）** | 60°×60° 方形，对角 90° | 45°×45° 方形，对角 65° |
| **最远测距** | ~350 cm | ~400 cm |
| **环境光下测距** | ~65 cm | ~170 cm |
| **最低功耗** | ~8.3 mW | ~4.5 mW |
| **分辨率** | 均为 4×4（16 区）或 8×8（64 区）可选 |
| **帧率** | 均最高 60 Hz（4×4 时） |
| **封装尺寸** | 均为 6.4 × 3.0 mm（引脚兼容） |
| **接口** | 均为 I²C（默认地址 0x52） |
| **软件驱动** | 完全兼容同一套 ULD API |

> 简言之：**VL53L7CX 视野更大（广角），VL53L5CX 测得更远、抗环境光更强**。选哪个看具体场景。如果你的模块外壳/场景要求广角覆盖，选 L7；如果要求远距离或在户外使用，选 L5。

### 3.3 关键概念

- **Zone（区域）**: 8×8=64 个独立测距区，每区返回一个距离值
- **Target status（状态码）**: 每区的数据有效性标记，**不可忽略**。不看状态码会导致读到无效值
- **连续模式 vs 自主模式**: 连续模式始终以最高功率测距；自主模式可设积分时间，功耗更低

### 3.4 状态码速查

| 状态码 | 含义 | 是否有效 |
|--------|------|----------|
| 0 | 无数据/未更新 | ❌ 无效 |
| 5 | 测距完成（最高置信度） | ✅ 有效 |
| 6 | 测距完成（中等置信度） | ✅ 有效 |
| 9 | 测距完成（有干扰目标，合脉冲） | ✅ 有效（精度略降） |
| 12 | 测距完成（低置信度） | ⚠️ 视应用酌情使用 |
| 其他 | 无效/错误 | ❌ 无效 |

> 代码中判断有效的通用写法：
> ```cpp
> if (target_status == 5 || target_status == 6 || target_status == 9) {
>     // 该区距离有效
> }
> ```

---

## 4. 接线说明

### 4.1 模块引脚定义

典型 VL53L7CX 模块（breakout board）引脚：

| 模块引脚 | 功能 | 说明 |
|----------|------|------|
| **VCC / VDD** | 电源正 | 3.3V（部分板载 LDO 可接 5V，以实物为准） |
| **GND** | 电源地 | 接开发板 GND |
| **SDA** | I²C 数据线 | 需上拉电阻（通常模块已板载） |
| **SCL** | I²C 时钟线 | 需上拉电阻（通常模块已板载） |
| **INT / GPIO1** | 中断输出（可选） | 传感器数据就绪时拉低，可不用接 |
| **LPn / XSHUT** | 低功耗/复位（可选） | 拉低=关机，悬空或拉高=工作；可不用接 |

> **模块最简接法（3.3V 系统）: 只需接 VCC、GND、SDA、SCL 四根线即可工作。**

### 4.2 ESP32 接线（推荐）

ESP32 原生 3.3V，无需电平转换，默认 I²C 接口稳定可靠。

```
VL53L7 模块        ESP32
==========         ==========
VCC (3.3V)   →     3V3
GND          →     GND
SDA          →     GPIO21
SCL          →     GPIO22
INT          →     (可不接)
LPn          →     (可不接，或接 GPIO19)
```

### 4.3 Arduino UNO / Nano 接线

> ⚠️ UNO/Nano 的 GPIO 为 5V 电平，直接接 VL53L7 **可能损坏传感器**！建议加 4 通道电平转换模块（如 TXS0104E），或使用板载 LDO+电平转换的 VL53L7 模块。

```
VL53L7 模块      电平转换      Arduino UNO/Nano
==========       ======       ===============
VCC (3.3V)   →                →  3.3V（UNO 3.3V 引脚）
GND          →                →  GND
SDA          →  LV ↔ HV   →  A4 (SDA)
SCL          →  LV ↔ HV   →  A5 (SCL)
```

> ⚠️ UNO 3.3V 引脚最大输出电流约 50mA，VL53L7 峰值需 ~150mA。建议为模块**单独供电**（外接 3.3V 稳压），仅将 GND 共地。

### 4.4 树莓派 / Pico（待确认）

树莓派和 Raspberry Pi Pico 的 I²C 均可直连（3.3V 电平），接线与 ESP32 类似：

- 树莓派：SDA→GPIO2 (Pin3)，SCL→GPIO3 (Pin5)，3.3V→Pin1
- Pico：SDA→GPIO0/4/8 等（可自定义），SCL→GPIO1/5/9 等

> 具体引脚和驱动安装步骤以树莓派/Pico 官方文档为准，此处不作展开。

---

## 5. Arduino IDE 安装步骤

### 5.1 安装 Arduino IDE

1. 打开 [arduino.cc/en/software](https://www.arduino.cc/en/software)
2. 下载对应系统版本（Windows / macOS / Linux）
3. 安装并启动 Arduino IDE

### 5.2 安装 ESP32 开发板支持（ESP32 用户）

> UNO / Nano 用户可跳过此步。

1. 打开 Arduino IDE → **文件** → **首选项**（Preferences）
2. 在"附加开发板管理器网址"中添加：
   ```
   https://espressif.github.io/arduino-esp32/package_esp32_index.json
   ```
3. 点击 **工具** → **开发板** → **开发板管理器**
4. 搜索 `esp32`，安装 **esp32 by Espressif Systems**（推荐最新版）

### 5.3 安装 VL53L7CX 库

1. 打开 Arduino IDE → **工具** → **管理库**
2. 搜索 `VL53L7CX`
3. 找到 **VL53L7CX by STMicroelectronics**（库名 `stm32duino/VL53L7CX`），点击安装
4. 安装完成后可在 **文件** → **示例** → **VL53L7CX** 中找到官方示例

### 5.4 选择开发板和端口

1. **工具** → **开发板** → 选择你的板子
   - ESP32: `ESP32 Dev Module`
   - UNO: `Arduino Uno`
   - Nano: `Arduino Nano`
2. **工具** → **端口** → 选择对应 COM 口
   - Windows: `COM3`、`COM8` 等
   - macOS: `/dev/cu.usbserial-*`
   - Linux: `/dev/ttyUSB0`

### 5.5 打开示例、上传、监视

1. **文件** → **示例** → **VL53L7CX** → 选择示例（如 `RangingBasic`）
2. 点击 **上传** 按钮（→ 箭头）
3. 上传成功后，**工具** → **串口监视器**（或 Ctrl+Shift+M）
4. **设置波特率为 115200**（与示例代码一致）

---

## 6. 测试程序说明

### 6.1 官方库来源

推荐使用 **stm32duino/VL53L7CX**（ST 官方维护的 Arduino 库）：

- GitHub: https://github.com/stm32duino/VL53L7CX
- 许可证: BSD 3-Clause（允许商用）
- 官方 API 文档: [UM3038](https://www.st.com/resource/en/user_manual/um3038-a-guide-to-using-the-vl53l7cx-timeofflight-multizone-ranging-sensor-with-90-fov-stmicroelectronics.pdf) — ST 官方用户手册，含完整 API 说明

VL53L5CX 用户也使用同一套库，因为二者驱动完全兼容。

### 6.2 最小测试程序（8×8 连续测距）

以下程序演示了最核心的测距流程：初始化 → 设 8×8 分辨率 → 设 10Hz → 连续模式 → 启动 → 循环读取 64 区距离。

```cpp
/**
 * VL53L7CX 8×8 连续测距 — 最小示例
 * 适用于 ESP32 / UNO / Nano（UNO 需提前处理好电平转换和供电）
 *
 * 接线（ESP32）：
 *   VL53L7 VCC → 3.3V    GND → GND
 *   VL53L7 SDA → GPIO21  SCL → GPIO22
 *
 * 接线（UNO）：
 *   VL53L7 VCC → 3.3V (外接供电)    GND → GND
 *   VL53L7 SDA → A4 (经电平转换)   SCL → A5 (经电平转换)
 */

#include <Arduino.h>
#include <Wire.h>
#include <vl53l7cx_api.h>

VL53L7CX_Configuration  g_dev;       // 传感器配置
VL53L7CX_ResultsData    g_results;   // 测距结果

void setup()
{
    Serial.begin(115200);
    while (!Serial);  // 等待串口就绪（UNO 需要）
    delay(500);

    Serial.println("VL53L7CX 8x8 Ranging Test");

    // ====== 1. 初始化 I²C ======
#if defined(ESP32)
    Wire.begin(21, 22, 400000);   // ESP32: SDA=GPIO21, SCL=GPIO22, 400kHz
#else
    Wire.begin();                  // UNO/Nano: 默认 SDA=A4, SCL=A5
#endif
    Wire.setClock(400000);

    // ====== 2. 设置 I²C 地址并检测传感器 ======
    g_dev.platform.address = VL53L7CX_DEFAULT_I2C_ADDRESS;  // 8-bit 地址 0x52

    uint8_t isAlive;
    uint8_t status = vl53l7cx_is_alive(&g_dev, &isAlive);
    if (!isAlive || status) {
        Serial.println("ERROR: VL53L7CX not detected! Check wiring.");
        while (1) { delay(1000); }
    }
    Serial.println("Sensor detected!");

    // ====== 3. 初始化传感器（含固件下载） ======
    status = vl53l7cx_init(&g_dev);
    if (status != VL53L7CX_STATUS_OK) {
        Serial.printf("ERROR: init failed (code %d)\n", status);
        while (1) { delay(1000); }
    }
    Serial.printf("Driver: %s, Module: %u\n",
                  VL53L7CX_API_REVISION, g_dev.module_type);
    // module_type: 0=VL53L5, 1=VL53L7, 2=VL53L8

    // ====== 4. 设置参数 ======
    vl53l7cx_set_resolution(&g_dev, VL53L7CX_RESOLUTION_8X8);
    vl53l7cx_set_ranging_frequency_hz(&g_dev, 10);
    vl53l7cx_set_ranging_mode(&g_dev, VL53L7CX_RANGING_MODE_CONTINUOUS);

    // ====== 5. 启动测距 ======
    status = vl53l7cx_start_ranging(&g_dev);
    if (status != VL53L7CX_STATUS_OK) {
        Serial.printf("ERROR: start ranging failed (code %d)\n", status);
        while (1) { delay(1000); }
    }

    Serial.println("Ranging started! Output: 8x8 matrix (mm)");
    Serial.println();
}

void loop()
{
    uint8_t isReady;
    vl53l7cx_check_data_ready(&g_dev, &isReady);

    if (isReady) {
        vl53l7cx_get_ranging_data(&g_dev, &g_results);

        Serial.printf("=== Frame #%lu ===\n", g_dev.streamcount);

        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 8; col++) {
                int zone = row * 8 + col;
                uint8_t st = g_results.target_status[
                    VL53L7CX_NB_TARGET_PER_ZONE * zone];
                int16_t dist = g_results.distance_mm[
                    VL53L7CX_NB_TARGET_PER_ZONE * zone];

                // 有效状态码: 5, 6, 9
                if (st == 5 || st == 6 || st == 9) {
                    Serial.printf("%4d ", dist);
                } else {
                    Serial.print("  -- ");
                }
            }
            Serial.println();
        }
        Serial.println();
    }

    delay(5);  // 避免过度轮询
}
```

### 6.3 修改 I²C 引脚（适配不同开发板）

在 `Wire.begin()` 中修改引脚号即可。常用配置：

```cpp
// ESP32 默认 I²C-0
Wire.begin(21, 22);          // SDA=GPIO21, SCL=GPIO22

// ESP32 自定义引脚（如 I²C-1）
Wire1.begin(18, 19);         // SDA=GPIO18, SCL=GPIO19

// UNO / Nano
Wire.begin();                // 只有 A4(SDA), A5(SCL)

// STM32 (如 Blue Pill)
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
```

> ⚠️ 如果用 ESP32 的非默认 I²C 引脚（如 GPIO18/19），同时需要修 `platform.cpp` 中的 I²C 引用，或直接在 `Wire1` 上操作。对 Arduino UNO 用户无此问题。

### 6.4 UNO/Nano 适配注意

Arduino UNO/Nano 的 SRAM 仅 2KB，而 VL53L7CX 在 8×8 模式下的 results 结构体约需 2KB 内存，非常紧张。建议：

1. **使用 4×4 分辨率**（`VL53L7CX_RESOLUTION_4X4`），只需 16 区数据
2. **禁用不需要的输出**以节省 RAM：在 `platform.h` 中取消注释对应宏，如：
   ```c
   #define VL53L7CX_DISABLE_AMBIENT_PER_SPAD
   #define VL53L7CX_DISABLE_NB_SPADS_ENABLED
   #define VL53L7CX_DISABLE_SIGNAL_PER_SPAD
   ```
3. 如仍内存不足，建议换用 ESP32（320KB SRAM，价格相近）

### 6.5 串口输出示例

串口监视器 @115200 baud 的输出大致如下：

```
VL53L7CX 8x8 Ranging Test
Sensor detected!
Driver: VL53L7CX_1.3.2, Module: 1
Ranging started! Output: 8x8 matrix (mm)

=== Frame #3 ===
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --
  --   --   --   --   --   --   --   --

=== Frame #7 ===
7979 7989 7809   --   --   --   --   --
7897 7814 7752 7827 7826 7782   --   --
7970 7984 7928 7944 7790 7812   --   --
8031 8062 7920 7830 7971 7861   --   --
8037 7974 8059 7829 7875 7799 6502 4514
7854 8133 8236 8175   -- 8016 6234 2408
8135 8034 8015 8107 7927 8052 3249 2425
8135 7948 7843 8022 6180 6215 3328 2915
```

- **数字**（如 7979）表示该区测距值，单位毫米
- **`--`** 表示该区无有效目标（超出量程、过近、或面对开放空间）
- 前几帧常为全 `--`，因为传感器刚启动，需要 3~5 帧初始化内部参数

---

## 7. 常见问题排查

### 7.1 编译错误

| 错误信息 | 原因 | 解决 |
|----------|------|------|
| `No such file: vl53l7cx_api.h` | 库未安装或未包含 | 在库管理器中搜索安装 `VL53L7CX` |
| `multiple definition of setup()` | 项目里有多个 `.ino` 或 `.cpp` 文件定义了 setup | 删掉多余文件 |
| `undefined reference to vl53l7cx_*` | C/C++ 链接问题 | 确保主文件为 `.cpp`（非 `.c`），或用 `extern "C"` 包裹库头文件 |
| `error: 'class TwoWire' ...` | 库在 `.c` 文件中 include 了 Arduino C++ 头文件 | 将文件后缀改为 `.cpp` |

### 7.2 传感器未检测到

```
[ERR] VL53L7 not detected at requested address
```

可能原因及排查：

1. **接线错误** — 用万用表蜂鸣档确认 SDA/SCL/VCC/GND 通断
2. **供电不足** — VL53L7 峰值电流 ~150mA，UNO 3.3V 仅 50mA；需外接 3.3V 稳压
3. **I²C 地址冲突** — 先运行 I²C 扫描器确认地址：
   ```cpp
   // I2C Scanner（精简版）
   #include <Wire.h>
   void setup() {
       Serial.begin(115200);
       Wire.begin();
       for (uint8_t addr = 1; addr < 127; addr++) {
           Wire.beginTransmission(addr);
           if (Wire.endTransmission() == 0)
               Serial.printf("Found: 0x%02X\n", addr);
       }
   }
   void loop() {}
   ```
   VL53L7CX 默认 7-bit 地址为 `0x29`（Arduino Wire 使用 7-bit 地址）
4. **电平问题（UNO 常见）** — 5V 信号可能损坏或不兼容 3.3V 传感器；必须加电平转换
5. **LPn/XSHUT 引脚** — 如果模块将 LPn 引出至排针但没有上拉电阻，需手动拉高（接 3.3V 或 GPIO 输出 HIGH）

### 7.3 初始化失败

```
[ERR] vl53l7cx_init failed: X
```

返回值 X 含义：

| 值 | 含义 | 常见原因 |
|----|------|----------|
| 1 | 通用错误 | I²C 通信异常，检查接线和供电 |
| 2 | 超时 | 固件下载过程中 I²C 阻塞，降低 I²C 速率到 100kHz 重试 |
| 4 | MCU 错误 | 传感器内部错误，重新上电 |

解决方法：
- 将 `Wire.setClock(400000)` 改为 `Wire.setClock(100000)`
- 检查杜邦线是否松动
- 确认模块不是 VL53L0X / VL53L1X（它们是不一样的产品，用的是完全不同的库）

### 7.4 串口输出全是 `--`

1. **前几帧正常** — 传感器启动后需要 3~5 帧稳定，之后才会有数据
2. **始终全 `--`** — 检查：
   - 传感器发射窗/接收窗是否被遮挡（标签膜、外壳、手指）
   - 目标物体是否在量程内（2cm ~ 350cm）
   - 有没有强光直射传感器窗口
   - 尝试用白纸在传感器上方 10~30cm 处晃动

### 7.5 数据波动大 / 不准

1. **检查状态码** — 只信任 status=5/6/9 的数据
2. **降低测距频率** — 10Hz 改 5Hz，给每帧更多积分时间
3. **增加积分时间** — 调用 `vl53l7cx_set_integration_time_ms(&g_dev, 50)`（默认约 5ms）
4. **盖板/玻璃影响** — 传感器窗口前的保护玻璃会引入串扰（crosstalk），需运行 Xtalk 校准例程
5. **环境光太强** — VL53L7CX 在强环境光下测距距离会显著缩短（约 65cm），VL53L5CX 抗光性能更好

### 7.6 UNO/Nano 内存不足

```
Global variables use XXXX bytes (XX%) of dynamic memory
```

- 8×8 模式 + 全输出会使 RAM 接近极限
- 解决：切换到 4×4 分辨率，禁用不用的输出（见 6.4 节）
- 或换 ESP32 开发板（价格相近，320KB SRAM，推荐）

### 7.7 ESP32 特定问题

- **烧录失败**: 按住 BOOT 按钮再点 Upload，或检查 COM 口是否正确
- **串口乱码**: 确认监视器波特率 = 115200，且代码中 `Serial.begin(115200)` 一致
- **I²C 报错 `i2cWriteReadNonStop returned Error -1`**: 通常是接线或供电问题，先运行 I²C 扫描器确认

---

## 8. 参考资料

| 资料 | 链接 |
|------|------|
| ST 官方 VL53L7CX 产品页 | https://www.st.com/en/imaging-and-photonics-solutions/vl53l7cx.html |
| ST 官方 Arduino 库 (GitHub) | https://github.com/stm32duino/VL53L7CX |
| ST 官方 ULD API 包 (STSW-IMG036) | https://www.st.com/en/embedded-software/stsw-img036.html |
| 用户手册 UM3038 (ULD API 详解) | https://www.st.com/resource/en/user_manual/um3038.pdf |
| VL53L7CX Datasheet | https://www.st.com/resource/en/datasheet/vl53l7cx.pdf |
| VL53L5CX Datasheet | https://www.st.com/resource/en/datasheet/vl53l5cx.pdf |
| DeepWiki API 文档（第三方整理） | https://deepwiki.com/stm32duino/VL53L7CX |
| ST 社区论坛（问题求助） | https://community.st.com/ |

---

> 📝 本文档基于 ST 官方资料和实际测试整理。VL53L7CX 和 VL53L5CX 驱动完全兼容，代码通用。
> 如有问题，在本商品页面留言，或参考 ST 官方社区论坛。
