Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ jobs:
target: esp32
- path: 'components/tt21100/example'
target: esp32s3
- path: 'components/vl53l/example'
target: esp32s3
- path: 'components/wifi/example'
target: esp32
- path: 'components/wrover-kit/example'
Expand Down
4 changes: 4 additions & 0 deletions components/vl53l/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
REQUIRES "base_peripheral"
)
21 changes: 21 additions & 0 deletions components/vl53l/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# add the component directories that we want to use
set(EXTRA_COMPONENT_DIRS
"../../../components/"
)

set(
COMPONENTS
"main esptool_py timer logger vl53l i2c"
CACHE STRING
"List of components to include"
)

project(vl53l_example)

set(CMAKE_CXX_STANDARD 20)
40 changes: 40 additions & 0 deletions components/vl53l/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# VL53LXX Example

This example shows the use of the `Vl53l` component to communicate with a VL53L0X
time-of-flight distance sensor.

The example initializes the sensor, configures it, and then reads the distance
from the sensor every 50ms. The distance is then printed to the console.

![CleanShot 2025-03-19 at 08 40 32](https://github.com/user-attachments/assets/93dc9340-8be6-4b9b-b592-958caa26570b)

## Hardware Required

This example is designed to work with any ESP32 which has I2C pins exposed, but
is pre-configured to run on QtPy boards such as the QtPy ESP32 Pico and QtPy
ESP32-S3.

It requires that you have a time of flight distance sensor dev board, such as
the [VL53L0X dev board from Adafruit](https://www.adafruit.com/product/3317).

![image](https://github.com/user-attachments/assets/47f7f64a-ad55-4529-9851-5283fc57bcb8)

## How to use example

### Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example Output

![CleanShot 2025-03-19 at 08 38 47](https://github.com/user-attachments/assets/63d059ac-41e5-4692-9fc5-f35ebdb455a2)
2 changes: 2 additions & 0 deletions components/vl53l/example/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS ".")
41 changes: 41 additions & 0 deletions components/vl53l/example/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
menu "Example Configuration"

choice EXAMPLE_HARDWARE
prompt "Hardware"
default EXAMPLE_HARDWARE_QTPY
help
Select the hardware to run this example on.

config EXAMPLE_HARDWARE_QTPY
bool "QtPy ESP32 Pico or QtPy ESP32-S3"

config EXAMPLE_HARDWARE_CUSTOM
bool "Custom"
endchoice

config EXAMPLE_I2C_SCL_GPIO
int "SCL GPIO Num"
range 0 50
default 40 if EXAMPLE_HARDWARE_QTPY && IDF_TARGET_ESP32S3
default 19 if EXAMPLE_HARDWARE_QTPY && IDF_TARGET_ESP32
default 19 if EXAMPLE_HARDWARE_CUSTOM
help
GPIO number for I2C Master clock line.

config EXAMPLE_I2C_SDA_GPIO
int "SDA GPIO Num"
range 0 50
default 41 if EXAMPLE_HARDWARE_QTPY && IDF_TARGET_ESP32S3
default 22 if EXAMPLE_HARDWARE_QTPY && IDF_TARGET_ESP32
default 22 if EXAMPLE_HARDWARE_CUSTOM
help
GPIO number for I2C Master data line.

config EXAMPLE_I2C_CLOCK_SPEED_HZ
int "I2C Clock Speed"
range 100 1000000
default 400000
help
I2C clock speed in Hz.

endmenu
107 changes: 107 additions & 0 deletions components/vl53l/example/main/vl53l_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include <chrono>
#include <vector>

#include "i2c.hpp"
#include "logger.hpp"
#include "timer.hpp"
#include "vl53l.hpp"

using namespace std::chrono_literals;

extern "C" void app_main(void) {
static espp::Logger logger({.tag = "VL53L4CX example", .level = espp::Logger::Verbosity::INFO});
// This example shows using the i2c adc (vl53l)
{
logger.info("Starting example!");

//! [vl53l example]
// make the i2c we'll use to communicate
static constexpr auto i2c_port = I2C_NUM_0;
static constexpr auto i2c_clock_speed = CONFIG_EXAMPLE_I2C_CLOCK_SPEED_HZ;
static constexpr gpio_num_t i2c_sda = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO;
static constexpr gpio_num_t i2c_scl = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO;
logger.info("Creating I2C on port {} with SDA {} and SCL {}", i2c_port, i2c_sda, i2c_scl);
logger.info("I2C clock speed: {} Hz", i2c_clock_speed);
espp::I2c i2c({.port = i2c_port,
.sda_io_num = i2c_sda,
.scl_io_num = i2c_scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.clk_speed = i2c_clock_speed});

// make the actual test object
espp::Vl53l vl53l(
espp::Vl53l::Config{.device_address = espp::Vl53l::DEFAULT_ADDRESS,
.write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
.read = std::bind(&espp::I2c::read, &i2c, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
.log_level = espp::Logger::Verbosity::WARN});

std::error_code ec;
// set the timing budget to 10ms, which must be shorter than the
// inter-measurement period. We'll log every 20ms so this guarantees we get
// new data every time
if (!vl53l.set_timing_budget_ms(10, ec)) {
logger.error("Failed to set inter measurement period: {}", ec.message());
return;
}
// set the inter-measurement period to 10ms, so we should be sure to get new
// data each measurement
if (!vl53l.set_inter_measurement_period_ms(10, ec)) {
logger.error("Failed to set inter measurement period: {}", ec.message());
return;
}
// tell it to start ranging
if (!vl53l.start_ranging(ec)) {
logger.error("Failed to start ranging: {}", ec.message());
return;
}

// make the task which will read the vl53l
fmt::print("%time (s), distance (m)\n");
auto read_task_fn = [&vl53l]() {
auto now = esp_timer_get_time();
static auto start = now;
float elapsed = (float)(now - start) / 1e6;
std::error_code ec;
// wait for the data to be ready
while (!vl53l.is_data_ready(ec)) {
std::this_thread::sleep_for(1ms);
}
// clear the interrupt so we can get another reading
if (!vl53l.clear_interrupt(ec)) {
logger.error("Failed to clear interrupt: {}", ec.message());
return false;
}
auto meters = vl53l.get_distance_meters(ec);
if (ec) {
logger.error("Failed to get distance: {}", ec.message());
return false;
}
fmt::print("{:.3f}, {:.3f}\n", elapsed, meters);
// we don't want to stop, so return false
return false;
};

espp::Timer timer({.period = 20ms,
.callback = read_task_fn,
.task_config =
{
.name = "VL53L4CX",
.stack_size_bytes{4 * 1024},
},
.log_level = espp::Logger::Verbosity::INFO});
//! [vl53l example]

while (true) {
std::this_thread::sleep_for(100ms);
}
}

logger.info("Example complete!");

while (true) {
std::this_thread::sleep_for(1s);
}
}
19 changes: 19 additions & 0 deletions components/vl53l/example/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CONFIG_IDF_TARGET="esp32s3"

CONFIG_FREERTOS_HZ=1000

# set compiler optimization level to -O2 (compile for performance)
CONFIG_COMPILER_OPTIMIZATION_PERF=y

# ESP32-specific
#
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240

# Common ESP-related
#
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384

# Set esp-timer task stack size to 6KB
CONFIG_ESP_TIMER_TASK_STACK_SIZE=6144
Loading