The Gravity 8×8 Matrix ToF 3D Distance Sensor is a compact depth sensing module designed for embedded and maker projects. It uses Time-of-Flight (ToF) technology to measure distance by analyzing reflected light signals.
Unlike single-point distance sensors, this module provides an 8×8 matrix of measurements. It delivers 64 independent distance values at once, forming a basic 3D depth map of the scene.
The sensor integrates an onboard RP2040 microcontroller for data processing. It supports common interfaces such as I2C, UART, and USB. The detection range reaches up to about 3.5 meters with a field of view of around 60 degrees.
In this tutorial you will learn how to connect the sensor to an ESP32 or Arduino to retrieve and display the 8×8 distance matrix measured by the sensor.
Required Parts
You can get the Gravity 8×8 Matrix ToF Sensor at Amazon or DFRobot. You also will need an Arduino or an ESP32. I am using an Arduino R4 WiFi and an ESP32 Lite in this tutorial.
I picked the Arduino R4 WiFi for this project, since it has a built-in LED matrix, which we will use to display the measurements of the 8×8 Matrix ToF Sensor.
Alternatively, you can use an ESP32 or another Arduino and use an OLED as display. I will show you how to do that as well.
Finally, a breadboard and some Dupont cables for wiring will be useful.

Gravity 8×8 Matrix ToF Sensor

ESP32 lite

Arduino R4 WiFi

USB C Cable

OLED Display

Dupont Wire Set

Breadboard
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Hardware of the Gravity 8×8 Matrix ToF Sensor
The Gravity 8×8 Matrix ToF 3D Distance Sensor is built around a multi-zone Time-of-Flight ranging device. It uses the VL53L7CX sensor, which integrates an array of optical measurement zones. Each zone acts as an independent distance channel. The full array forms an 8×8 grid with 64 measurement points. The picture below shows the front and back of the sensor board:

On the top of the front of the board you can see the actual sensor (marked yellow). On the back is the Gravity connector for connecting the board and a DIP switch to set the communications mode (UART/I2C) and the I2C address.
Note that the sensor element is covered by a yellow plastic foil that you need to peel of before usage. The following photo shows the sensor element with and without foil:

An onboard RP2040 microcontroller handles signal processing and data aggregation. This reduces the computational load on the host microcontroller. The sensor outputs already processed distance values instead of raw timing data.
The system operates in continuous ranging mode. This means distance measurements are updated at a fixed rate without external triggering. The typical refresh rate ranges from 15 Hz up to 60 Hz depending on configuration.
Measurement Characteristics
The sensor measures distance using infrared light pulses and timing analysis. It supports a measurement range from approximately 20 mm up to 3.5 meters.
Accuracy depends on distance and target reflectivity. At short range between 20 mm and 200 mm, the error is typically around ±11 to ±12 mm. At longer distances, the error is expressed as a percentage and ranges from about ±5% to ±6%.
The field of view is defined by a wide angular coverage. It is about 60 degrees horizontally and vertically, with a diagonal angle close to 90 degrees. This allows the sensor to capture a broad scene in a single frame.
Each of the 64 zones reports an independent distance value. These values together form a low-resolution depth map. This enables basic 3D perception without complex image processing.
Electrical Characteristics
The sensor operates with a supply voltage between 3.3 V and 5 V. This makes it directly compatible with most Arduino and ESP32 boards.
The current consumption is below 80 mA during operation. This allows use in low-power embedded systems.
The module complies with Class 1 laser safety standards. This ensures safe operation under normal conditions without special precautions.
Communication Interfaces
The sensor supports multiple communication interfaces. It can operate over I2C, UART, or USB.
USB communication is mainly used for direct data streaming and firmware updates.
The I2C interface provides four selectable addresses: 0x30, 0x31, 0x32, and 0x33. The UART interface uses a fixed baud rate of 115200 bps. See the next section on how to switch between communication interfaces and how to set the I2C address.
Setting I2C Address and Communication Mode
You can switch the sensor’s communication mode between UART and I2C using a DIP switch. For I2C communication you can furthermore switch between four different I2C addresses. On the back of the board you find 3 DIP switches (marked yellow) labelled A1, A0 and I2C as shown below:

Note that on a new sensor board the DIP switch is covered by a yellow plastic foil that you need to remove, if you want to change the setting.
I used the default settings shown above. They indicate that the communication mode is set to I2C and the I2C address is 0x33.
The I2C address is determined by the A0 and A1 switches and the table at the back of the board tells you which setting of A0 and A1 corresponds to which I2C address:

In my case (the default), A0=1 and A1=1 corresponds to the I2C address is 0x33. You will find that this address is used in the code. But should it conflict with the I2C address of your OLED, the you can change it here.
Pinout
The picture below shows the Pinout of the Gravity 8×8 Matrix ToF Sensor. You will find the white 4 pin Gravity connector (PH2.0-4P) on the back of the board as shown below:

It has pins for power supply (VCC, GND) and for I2C (SDA, SCL) or UART (TX, RX), whereby the communications mode depends on the DIP switch setting described before.
Technical Specifications
The following table summarizes the key technical parameters of the Gravity 8×8 Matrix ToF 3D Distance Sensor.
| Parameter | Value |
|---|---|
| Sensor model | VL53L7CX |
| Processing MCU | RP2040 |
| Measurement grid | 8 × 8 matrix (64 zones) |
| Ranging mode | Continuous ranging |
| Refresh rate | 15 Hz to 60 Hz |
| Measurement range | 20 mm to 3.5 m |
| Accuracy (short range) | ±11 to ±12 mm (20–200 mm) |
| Accuracy (long range) | ±5% to ±6% (>200 mm) |
| Field of view | 60° × 60° (90° diagonal) |
| Supply voltage | 3.3 V to 5 V |
| Current consumption | < 80 mA |
| Interfaces | I2C, UART, USB |
| I2C addresses | 0x30, 0x31, 0x32, 0x33 |
| UART baud rate | 115200 bps |
| Connector type | PH2.0-4P (Gravity) |
| Laser safety class | Class 1 |
Connecting the Gravity 8×8 Matrix ToF Sensor to Arduino R4
Connecting the Gravity 8×8 Matrix ToF Sensor to an Arduino R4 is simple. Start by connecting VIN to 5V or 3.3V of the Arduino. Next connect GND to GND. Finally, connect the I2C interface by wiring SCL and SDA of the sensor to the corresponding pins on the R4. The picture below shows the complete wiring:

For convenience here a table with the connections you need to make:
| Sensor | Arduino R4 |
|---|---|
| VIN | 5V or 3.3V |
| GND | GND |
| SCL | SCL |
| SDA | SDA |
Connecting the Gravity 8×8 Matrix ToF Sensor to ESP32
Connecting the sensor to an ESP32 is equally simple. The default I2C interface of the ESP32 lite is located on pins 19 (SDA) and 23 (SCL). We therefore connect SCL of the sensor to pin 23 and SDA to pin 19.
Next we connect VCC of the sensor to the 3V pin, which provides 3.3V. And finally, we connect GND of the sensor to the G (Ground) pin of the ESP32. The picture below shows the complete wiring:

For convenience here a table with the connections you need to make:
| Sensor | ESP32 Lite |
|---|---|
| VIN | 3.3V |
| GND | G |
| C/R | 23 (SCL) |
| D/T | 19 (SDA) |
The ESP32 has no built-in LED matrix and we therefore going to connect an OLED to visualize the distances measured by the Gravity 8×8 Matrix ToF Sensor. Adding the OLED to the circuit is simple, since we can connect the OLED in parallel to the Sensor. Just connect the SDA, SCL and powerlines in parallel:

Installing the DFRobot_MatrixLidar library
Before we can write any code, we need to install the DFRobot_MatrixLidar library. To install this library go to the DFRobot_MatrixLidar repo, click on the green “<> Code” button and then “Download ZIP” to download the library as a ZIP file as shown below:

Then create a new Arduino Sketch, go to Sketch -> Include Library -> Add .ZIP Library … to install the downloaded ZIP library (DFRobot_MatrixLidar-master.zip):

Code Example: Measure and Print 8×8 Distance Matrix
The following code demonstrates how to use the Gravity 8×8 Matrix ToF (Time-of-Flight) 3D distance sensor with an ESP32 or an Arduino. It measures distances in an 8×8 matrix format and prints the distance values for each point in the matrix to the serial monitor.
// www.makerguides.com
// Libraries:
// - DFRobot_MatrixLidar V 1.0.0
// https://github.com/DFRobot/DFRobot_MatrixLidar
// - ESP32 Core V 3.3.8
#include "DFRobot_MatrixLidar.h"
DFRobot_MatrixLidar_I2C tof(0x33);
uint16_t buf[64];
void setup(void){
Serial.begin(115200);
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
}
void loop(void){
tof.getAllData(buf);
for(uint8_t i = 0; i < 8; i++){
for(uint8_t j = 0; j < 8; j++){
uint16_t dist = buf[i * 8 + j];
Serial.print(dist);
Serial.print(",");
}
Serial.println("");
}
Serial.println("------------------------------");
delay(100);
}
Imports
The code begins by including the DFRobot_MatrixLidar library, which provides the necessary functions to interface with the Gravity 8×8 Matrix ToF sensor over I2C.
#include "DFRobot_MatrixLidar.h"
Objects and Variables
Next, an object tof of the class DFRobot_MatrixLidar_I2C is created with the I2C address 0x33. This object will be used to communicate with the sensor.
Additionally, a buffer array buf of 64 unsigned 16-bit integers is declared. This buffer will hold the distance measurements for each of the 64 points in the 8×8 matrix.
DFRobot_MatrixLidar_I2C tof(0x33); uint16_t buf[64];
Setup Function
In the setup() function, the serial communication is initialized at 115200 baud to allow printing data to the serial monitor.
The sensor is then initialized by calling tof.begin(). If the initialization fails (returns a non-zero value), the code prints an error message and retries every 100 milliseconds until successful.
After successful initialization, the ranging mode of the sensor is set to eMatrix_8X8, which configures the sensor to measure distances in an 8×8 matrix format. Similar to initialization, if setting the mode fails, an error message is printed and the code retries until it succeeds.
void setup(void){
Serial.begin(115200);
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
}
Loop Function
The loop() function continuously reads distance data from the sensor and prints it to the serial monitor.
First, tof.getAllData(buf) fills the buf array with the latest distance measurements for all 64 points in the 8×8 matrix.
Two nested for loops iterate over the rows (i) and columns (j) of the matrix. For each point, the corresponding distance value is extracted from the buffer using the formula buf[i * 8 + j].
Each distance value is printed followed by a comma to separate the values in a row. After printing all columns in a row, a newline is printed to start a new row.
After printing the entire 8×8 matrix, a separator line of dashes is printed to visually distinguish each frame of data. Finally, the code waits 100 milliseconds before repeating the process.
void loop(void){
tof.getAllData(buf);
for(uint8_t i = 0; i < 8; i++){
for(uint8_t j = 0; j < 8; j++){
uint16_t dist = buf[i * 8 + j];
Serial.print(dist);
Serial.print(",");
}
Serial.println("");
}
Serial.println("------------------------------");
delay(100);
}
Output Example
The following screenshot show what you should see printed on the Serial Monitor:

You can see the 8×8 matrix of measured distance values. If no object is in front of the sensor or it is too far away the maximum distance of 4000 mm (=400 cm) is printed. If you place something close enough to the sensor, you will see smaller distances.
Code Example: Display 8×8 Distance Matrix on LED Matrix
The next code example demonstrates how to use the Gravity 8×8 Matrix ToF (Time-of-Flight) 3D distance sensor to measure distances in an 8×8 matrix format and display the results on an Arduino R4 LED matrix.
The sensor provides distance data for each of the 64 points in the matrix, and the code visualizes this data by lighting up LEDs corresponding to detected distances within a specified range. Below an output example:

Have a quick look at the complete code first and then we will discuss its details:
// www.makerguides.com
// Libraries:
// - DFRobot_MatrixLidar V 1.0.0
// https://github.com/DFRobot/DFRobot_MatrixLidar
#include "Arduino_LED_Matrix.h"
#include "DFRobot_MatrixLidar.h"
ArduinoLEDMatrix leds;
DFRobot_MatrixLidar_I2C tof(0x33);
void displayMatrix(uint16_t maxDist=200) {
static uint16_t buf[64];
static uint8_t frame[8][12] = {0};
tof.getAllData(buf);
for(uint8_t i = 0; i < 8; i++){
for(uint8_t j = 0; j < 8; j++){
uint16_t dist = buf[i * 8 + j];
frame[i][j] = dist > maxDist ? 0 : 1;
}
}
leds.renderBitmap(frame, 8, 12);
}
void setup(void){
Serial.begin(115200);
leds.begin();
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
Serial.println("running...");
}
void loop(void){
displayMatrix(100); // 100 mm =10cm
delay(50);
}
Imports
The code begins by including two essential libraries. The Arduino_LED_Matrix library manages the LED matrix display, while the DFRobot_MatrixLidar library handles communication with the Gravity 8×8 Matrix ToF sensor.
#include "Arduino_LED_Matrix.h" #include "DFRobot_MatrixLidar.h"
Objects
Next, two objects are created. The leds object controls the LED matrix display, and the tof object represents the ToF sensor connected via I2C at address 0x33.
ArduinoLEDMatrix leds; DFRobot_MatrixLidar_I2C tof(0x33);
DisplayMatrix Function
The displayMatrix() function is responsible for reading distance data from the sensor and updating the LED matrix accordingly. It accepts an optional parameter maxDist, which sets the maximum distance threshold in millimeters for lighting up LEDs. The default is 200 mm.
Inside the function, a static buffer buf of 64 unsigned 16-bit integers stores the raw distance data for each point in the 8×8 matrix. Another static 2D array frame represents the LED states to be displayed.
The function calls tof.getAllData(buf) to fill the buffer with current distance measurements. It then iterates over each point in the 8×8 matrix, checking if the measured distance is less than or equal to maxDist. If so, the corresponding LED is turned on by setting the value to 1; otherwise, it is turned off (0).
Finally, the leds.renderBitmap() method is called to update the LED matrix display with the prepared frame.
void displayMatrix(uint16_t maxDist=200) {
static uint16_t buf[64];
static uint8_t frame[8][12] = {0};
tof.getAllData(buf);
for(uint8_t i = 0; i < 8; i++){
for(uint8_t j = 0; j < 8; j++){
uint16_t dist = buf[i * 8 + j];
frame[i][j] = dist > maxDist ? 0 : 1;
}
}
leds.renderBitmap(frame, 8, 12);
}
Setup Function
The setup() function initializes serial communication at 115200 baud for debugging purposes and starts the LED matrix by calling leds.begin().
It then attempts to initialize the ToF sensor by calling tof.begin() in a loop until successful. If initialization fails, it prints an error message and retries after a short delay.
Once the sensor is initialized, the code sets its ranging mode to eMatrix_8X8, which configures the sensor to provide distance data in an 8×8 matrix format. This is also done in a loop with error checking.
After successful setup, a confirmation message “running…” is printed to the serial monitor.
void setup(void){
Serial.begin(115200);
leds.begin();
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
Serial.println("running...");
}
Loop Function
The loop() function continuously calls displayMatrix(100), which updates the LED matrix to show points where the distance is 100 millimeters (10 centimeters) or less. This creates a real-time visualization of objects detected within that range.
A short delay of 50 milliseconds is added between updates to control the refresh rate and avoid overwhelming the sensor or display.
void loop(void){
displayMatrix(100); // 100 mm =10cm
delay(50);
}
Output Demo
The short video below demonstrates how the sensor works and how movements and objects appear on the LED matrix:
Code Example: Display 8×8 Distance Matrix on OLED
For this last project we connect the sensor to and ESP32, add a small OLED to the circuit, and display the distance matrix on the OLED. The OLED has the advantage that we will be able to represent relative distances by the size of the matrix squares.
To control the OLED you need to install the Adafruit_SSD1306 library. You can install it via the Library Manager as usual:

The sensor provides distance measurements in a grid format, and the OLED visualizes these distances as filled squares of varying sizes, giving a clear spatial representation of the measured environment. See the output example below:

Have a quick look at the complete code first and then we will discuss its details:
// www.makerguides.com
// Libraries:
// - DFRobot_MatrixLidar V 1.0.0
// https://github.com/DFRobot/DFRobot_MatrixLidar
// - Adafruit_SSD1306 V 2.5.16
// https://github.com/adafruit/adafruit_ssd1306
// - ESP32 Core V 3.3.8
#include "Adafruit_SSD1306.h"
#include "DFRobot_MatrixLidar.h"
const int sw = 128;
const int sh = 64;
Adafruit_SSD1306 display(sw, sh, &Wire, -1);
DFRobot_MatrixLidar_I2C tof(0x33);
void displayMatrix(uint16_t maxDist = 400) {
const int cs = 8; // cell size
static uint16_t buf[64];
display.clearDisplay();
tof.getAllData(buf);
for (uint8_t i = 0; i < 8; i++) {
for (uint8_t j = 0; j < 8; j++) {
uint16_t dist = buf[i * 8 + j];
if (dist < maxDist) {
int fillSize = map(dist, 0, maxDist, cs, 0);
int x = (cs - fillSize) / 2;
int y = (cs - fillSize) / 2;
display.fillRect((j * cs) + x + sh / 2,
sh - (i * cs) + y,
fillSize, fillSize, WHITE);
}
}
}
display.display();
}
void setup(void) {
Serial.begin(115200);
while (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("Can't init display!"));
delay(100);
}
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
display.clearDisplay();
display.display();
Serial.println("running...");
}
void loop(void) {
displayMatrix(500); // 500mm
delay(50);
}
Imports
The code begins by including the necessary libraries. Adafruit_SSD1306 is used to control the OLED display, while DFRobot_MatrixLidar handles communication with the 8×8 Matrix ToF sensor.
#include "Adafruit_SSD1306.h" #include "DFRobot_MatrixLidar.h"
Constants and Objects
Two constants sw and sh define the width and height of the OLED display in pixels, set to 128 by 64 respectively. An Adafruit_SSD1306 object named display is created with these dimensions and linked to the I2C bus. The ToF sensor object tof is instantiated with its I2C address 0x33.
const int sw = 128; const int sh = 64; Adafruit_SSD1306 display(sw, sh, &Wire, -1); DFRobot_MatrixLidar_I2C tof(0x33);
displayMatrix Function
The displayMatrix() function is responsible for reading the distance data from the sensor and visualizing it on the OLED. It accepts an optional parameter maxDist which defaults to 400 millimeters and represents the maximum distance to consider for display.
Inside the function, a constant cs defines the size of each cell in the 8×8 grid as 8 pixels. A static buffer array buf of 64 elements stores the distance measurements for each cell.
The display is first cleared, then the sensor data is fetched into buf using tof.getAllData(). The function iterates through each cell in the 8×8 matrix, retrieving the distance value. If the distance is less than maxDist, it calculates a fill size for a square to represent the distance visually. The closer the object, the larger the square.
The position of each square is calculated to center it within its cell, and display.fillRect() draws the square on the OLED. Finally, display.display() updates the OLED with the new graphics.
void displayMatrix(uint16_t maxDist = 400) {
const int cs = 8; // cell size
static uint16_t buf[64];
display.clearDisplay();
tof.getAllData(buf);
for (uint8_t i = 0; i < 8; i++) {
for (uint8_t j = 0; j < 8; j++) {
uint16_t dist = buf[i * 8 + j];
if (dist < maxDist) {
int fillSize = map(dist, 0, maxDist, cs, 0);
int x = (cs - fillSize) / 2;
int y = (cs - fillSize) / 2;
display.fillRect((j * cs) + x + sh / 2,
sh - (i * cs) + y,
fillSize, fillSize, WHITE);
}
}
}
display.display();
}
Setup Function
The setup() function initializes serial communication at 115200 baud for debugging purposes. It then attempts to initialize the OLED display with the I2C address 0x3C. If initialization fails, it prints an error message and retries.
Next, the ToF sensor is initialized. If the sensor fails to start, the code prints an error and retries. After successful initialization, the sensor is set to the 8×8 ranging mode using tof.setRangingMode(eMatrix_8X8). Any failure here also triggers an error message and retry loop.
Finally, the display is cleared and updated, and a “running…” message is printed to the serial monitor to indicate that the setup is complete.
void setup(void) {
Serial.begin(115200);
while (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("Can't init display!"));
delay(100);
}
while (tof.begin() != 0) {
Serial.println("Can't init sensor!");
delay(100);
}
while (tof.setRangingMode(eMatrix_8X8) != 0) {
Serial.println("Can't set mode!");
delay(100);
}
display.clearDisplay();
display.display();
Serial.println("running...");
}
Loop Function
The loop() function continuously calls displayMatrix() with a maximum distance of 500 millimeters, updating the OLED display with the latest distance measurements from the sensor. A short delay of 50 milliseconds is added to control the update rate.
void loop(void) {
displayMatrix(500); // 500mm
delay(50);
}
Output Demo
The short video below demonstrates how the sensor works and how movements and objects appear on theOLED:
Conclusions
In this tutorial you learned how to connect the Gravity 8×8 Matrix ToF Sensor to an Arduino or an ESP32 for spatial distance measuring.
Compared to single-point laser distance sensors such as the TFmini-Plus, the GP2Y0E03, or the VL53L1X, for instance, the Gravity 8×8 Matrix ToF 3D Distance Sensor offers a major advantage in spatial awareness.
Instead of measuring only one distance value, it provides 64 distance points at once, which enables basic depth mapping and direction detection.
This reduces the need for mechanical scanning or multiple sensors. However, single-point sensors are typically simpler, smaller, and more precise for one specific measurement direction.
In general, the matrix approach is better for scene understanding, while single-beam sensors are better for precise distance measurement.
Typical applications of the Gravity 8×8 Matrix ToF Sensor are in robotics for obstacle detection and basic navigation. In smart home systems, it could be applied to gesture recognition, occupancy detection, motion tracking, and proximity-based control.
If you have any questions feel free to leave them in the comment section.
Happy Tinkering ; )
Stefan is a professional software developer and researcher. He has worked in robotics, bioinformatics, image/audio processing and education at Siemens, IBM and Google. He specializes in AI and machine learning and has a keen interest in DIY projects involving Arduino and 3D printing.

